Click here to Skip to main content
Click here to Skip to main content

An Encoder class derived from a stream

By , 1 Sep 2004
 

Introduction

Very often you want to add special features to a stream class (istream, ostream or iostream). A way to do this, is to create a specialized streambuf class and to overload stream base class methods.

A Xstream class constructor has a streambuf parameter that is attached to the stream. For example, to write to a file, you can do:

filebuf fb; 
fb.open ("test.txt",ios::out); 
ostream os(&fb); //... 

But if your objective isn't to write to a file, but to a generic memory buffer, you can construct your ostream derived class like that:

class MyStreamBuf : public streambuf { 
// ... you can overload streambuf methods here
}; 
class MyOutputStream : public ostream { 
public: 
MyOutputStream() : ostream(&stBuf) {} 
// ... you can overload ostream methods here
private: 
MyStreamBuf stBuf; 
};

The same for istream and iostream classes. Overloading of Xstream methods permit you to create a specialized stream class.

If you want to serialize primitive types or other objects to MyOutputStream, you must create a method that returns a MyOutputStream reference object, so you can write something like that:

MyOutputStream mos; 
mos << "hello";

We now see an example where this technique is applied to an Encoder class where the encode operation can be performed in this way:

Encoder obj;
obj << "Hello"; //encode the "Hello" string e put it into an Encoder stream
and the decode operation can be performed so
string str;
obj >> str; //decoding in str

Using the code

Here, we will see an example that allows to manipulate a string through the operators << and >> of a derived class from ostream. Furthermore, we create a specialized streamuf class that encodes and decodes a string buffer.

In this example code, like we have explained before, a string can be encoded and decoded in this way:

Encoder y; 
y << "Hello" //encode a string into a stream 
y >> str;  //decode stream into a string

The Encode method simply consists of an ASCII conversion of chars within the string and Decode reverses this manipulation.

#include <string>
#include <fstream>
#include <iostream> 

using namespace std;

class BufferEncoder: public streambuf {
private:
string buffer; //encoded string
int numCar; //chars number of encoded string
public:

BufferEncoder() : streambuf(), numCar(0) {}
~BufferEncoder() {}

//encode a string and put it into BufferEncoder buffer
void Encode(const string& s){
    char tmp[10];
    for (unsigned int i=0; i< s.length(); ++i){
        itoa(s[i],tmp,10);
        buffer+= (string)tmp + (string)" "; //encode in an ASCII value
        numCar +=strlen(tmp)+1;
    }
}

//decode BufferEncoder buffer and return it into s
void Decode(string& s){
    string decodeStr;
    for (int i=0; i< numCar;++i){
        string tokenStr;
        while ((buffer.at(i) != ' ')&& (buffer.at(i)!='\n') && (i< numCar)){
            tokenStr += buffer.at(i);
            i++;
        }
        int v = atoi(tokenStr.c_str());
        decodeStr += (char) v; //decoded char
    }
    s = decodeStr;
}

//add and end of line into buffer 
void EndOfLine() {
   buffer += '\n';
   numCar ++;
}

//return buffer pointer
char* GetBuffer() {return ((char*) buffer.c_str());}
};

class Encoder : public ostream {
private:
    BufferEncoder myStrBuf; 
public: 
    //constructors
    Encoder(filebuf* fb) : ostream(fb),ios(0) {}
    Encoder() : ostream(&myStrBuf),ios(0) {}

    //endl manipulator serialization
    _Myt& operator<<(_Myt&(__cdecl *_Pfn )(_Myt&) ){
        // call basic_ostream manipulator
        //... no others manipulators than endl
        myStrBuf.EndOfLine();
        return ((*_Pfn)(*this));
    }

    //from Encoder to ostream serialization
    friend ostream& operator<<(ostream & s, Encoder& c) {
        s << c.myStrBuf.GetBuffer();
        return s;
    }

    //from const char* to Encoder serialization
    Encoder& operator<<(const char * s) {
        myStrBuf.Encode(s);
        return *this;
    }

    //from Encoder to string serialization
    Encoder& operator>>(string& s) {
        myStrBuf.Decode(s);
        return *this;
    } 
}; 

int main ()
{
    Encoder y;

    //encoding
    y <<"Hello World!";
    cout <<"ENCODED: "<< y << endl;

    //decoding
    string s ;
    y >> s;
    cout << "DECODED: " << s << endl;
    return 0;
}

Points of Interest

This code can help you to learn how to serialize an object (primitive or used defined), to or from an object stream, like predefined objects cin and cout. In fact, like a istream object, cin, and ostream object cout, in C++, you can define derived and user- defined objects from these classes and create methods to or from these objects.

History

  • v 1.1 fixed some code style tricks
  • v 1.0

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

Andrea Cacciarru
Engineer
Italy Italy
Member
See Andrea's profile on Linkedin

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
Hint: For improved responsiveness ensure Javascript is enabled and choose 'Normal' from the Layout dropdown and hit 'Update'.
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
QuestionTraditional Chinese characters aren’t being read from network streammemberMember 864850821 Mar '12 - 19:58 
GeneralHello!sussCode Inspector2 Sep '04 - 8:59 
GeneralRe: Hello!memberAndrea Cacciarru2 Sep '04 - 22:27 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web04 | 2.6.130523.1 | Last Updated 2 Sep 2004
Article Copyright 2004 by Andrea Cacciarru
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid