Here's something I came up with that mirrors what John Harrison is
referring to with respect to ostringstream. The getBuffer function has
since been re-written to use a vector but this might provide some
clues. Of course the experts will comment if I'm way off so ...
#ifndef DATA_STREAM_H
#define DATA_STREAM_H
# include <iostream>
# include <string>
# include <map>
# include <typeinfo>
# include <sstream>
///////////////////////////////////////////////////
// data_stream
///////////////////////////////////////////////////
struct data_stream
{
std::string classId;
std::string buffer;
size_t curPos;
data_stream(std::string clsId)
: classId(clsId), curPos(0)
{}
data_stream(char* buf, size_t size)
: curPos(0)
{
std::string temp(buf, size);
size_t pos = temp.find(':');
if (pos == std::string::npos || pos == 0 || pos == size-1)
return;
classId = temp.substr(0, pos);
buffer = temp.substr(pos+1);
}
bool isValid() { return curPos <= buffer.length(); }
operator bool() { return isValid(); }
size_t getBufferSize() { return isValid()? classId.size() + 1 +
buffer.size() : 0; }
size_t getBuffer(char*& buf, size_t siz)
{
size_t sizNeeded = getBufferSize();
size_t sizClass = classId.size();
if (buf == NULL || siz < sizNeeded)
{
delete buf;
buf = new char[sizNeeded];
}
memcpy(buf, classId.c_str(), sizClass);
buf[sizClass] = ':';
memcpy(&buf[sizClass+1], buffer.c_str(), buffer.size());
return sizNeeded;
}
};
template <class T>
inline data_stream& operator<<(data_stream& ds, const T& t)
{
std:
stringstream out;
out<<t;
ds<<out.str();
return ds;
}
template <class T>
inline data_stream& operator>>(data_stream& ds, T& t)
{
if (ds.isValid()) {
std::string s;
ds>>s;
std::istringstream in(s);
in>>t;
}
return ds;
}
inline data_stream& operator<<(data_stream& ds, const std::string& s)
{
if (ds)
{
ds.buffer += s;
ds.buffer += '\0';
ds.curPos = ds.buffer.size();
}
return ds;
}
inline data_stream& operator>>(data_stream& ds, std::string& s)
{
if (ds)
{
s = &ds.buffer[ds.curPos];
ds.curPos += s.size();
if (ds.curPos < ds.buffer.length() &&
ds.buffer[ds.curPos] == '\0')
ds.curPos++; // add terminating zero
}
return ds;
}
#endif
Depending on wethere I'm transmitting or receiving data..... Lets
assume I'll transmit data.
std::string buffer("served_data:"); // test data
buffer+="2";
buffer+='\0';
buffer+="5.0";
buffer+='\0';
buffer+="Terlim bom bom";
buffer+='\0';
data_stream st (&buffer[0], buffer.length());
if (st)
{
//
}