By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
458,069 Members | 1,249 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 458,069 IT Pros & Developers. It's quick & easy.

type t determination - operator << and >>

P: n/a

Consider

#include <iostream>
#include <string>
#include <map>

using namespace std;

struct dstream // data_stream class
{
string classId;
string buffer;
size_t curPos;

dstream(string clsId)
: classId(clsId), curPos(0){}

dstream(char* buf, int size)
: curPos(0)
{
string temp(buf, size);
//int pos = temp.find(':');
size_t pos = temp.find(':');

if (pos == 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 dstream& operator<<(dstream& ds, const T& t) { //// (1)
if (ds.isValid())
{
size_t curPos = ds.curPos;
ds.curPos += sizeof(T);
ds.buffer.resize(ds.curPos);
memcpy(&ds.buffer[curPos], &t, sizeof(t));
}
return ds;
}

// non const version of above the same .

template <class T>
inline dstream& operator>>(dstream& ds, T& t) { //// (2)
if (ds.isValid())
{
size_t curPos = ds.curPos;
ds.curPos += sizeof(t);
if (ds.isValid())
memcpy(&t, &ds.buffer[curPos], sizeof(t));
}
return ds;
}

// non const version of above the same .
// since bool is 4 bytes on GCC and 1 on .NET,
// maybe we shouldn't use them
// then again we' could also turn them into characters and back
//
inline dstream& operator>>(dstream& ds, bool& b) {
if (ds.isValid()) // perhaps i should just do 'if (ds)'
{
unsigned char uc;
ds >> uc;
//b == (uc) ? true : false;
b == (uc != '\0') ? true : false;
}
return ds;
}

// and so on
inline dstream& operator>>(dstream& ds, const bool& b) {
}
inline dstream& operator>>(dstream& ds, bool& b) {
}
inline dstream& operator>>(dstream& ds, const bool& b) {
}
inline dstream& operator>>(dstream& ds, string& s) {
}

// now comes the factory ...
class factory;
typedef factory* (*CreateInstanceFunc)( void );

class factory
{
// factory map is mapping class names to create functions
static map<string, CreateInstanceFunc> factoryMap;
public:
virtual string getClassId() = 0;
virtual bool loadFromStream(dstream& ds) = 0;
virtual bool storeToStream(dstream& ds) = 0;

static factory* createInstance(const dstream& ds)
{ }

static bool registerClass(const string& className, CreateInstanceFunc
createFunc)
{
}
dstream* store() {}
};

// now we're ready
class outgoing_msg : public factory
{
// test all the types
int i;
double d;
string s;
char c;
bool b;
public:
outgoing_msg() : i(1), d(2.), s("abc"), b(false), c('X')
{
// call register class on the incoming_msg side.
}

string getClassId() { return "outgoing_msg"; }

bool loadFromStream(dstream& ds)
{
ds >> i >> d >> s >> b >> c;
return ds.isValid();
}
bool storeToStream(dstream& ds)
{
ds << i << d << s << b << c;
return ds.isValid();
}
};

int main()
{
// create an instance of outgoing_msg.
// fill objects (i, d, s, etc with 'stuff' );;
// callt he store member function.
// Now we have a bucket of bits for transmittal across the pipe
}

For simplicity I trimmed most of the code and I do hope I didn't
provide too much. That said at issue is the lines marked ' (1) and
(2). The operators >> and << are called for types int, long, double
and character.

I need a way to determine if the type (hence t) is int, long or double?
How would I achieve that. The reason I'm asking centers around calling
the byteSwap routine (below) on those types.
#include <algorithm> //required for std::swap

#define ByteSwap5(x) ByteSwap((unsigned char *) &x,sizeof(x))

void ByteSwap(unsigned char * b, int n)
{
register int i = 0;
register int j = n-1;
while (i<j)
{
std::swap(b[i], b[j]);
i++, j--;
}
}

so now - pseudo code
if (typeid = int)
byteSwap( (unsigned char*)t , sizeof(int));
////////////
One other thing:
if (ds.isValid()) //(1)

if (ds) //(2)

In theory options 1 and 2 are the same. So far so good? That said, I'm
reminded of the day when I first saw.

if ( cin >> x)

It puzzled me cause I wondered why operator>> was returning a pointer.
I soon learned that operator<< returns a reference to iostream and that
one could test a class object on true or false by simply providing an
operator bool() member fucntion.

I still have trouble sometimes when i look at these operators,
nonetheless, what's the use of (1). I could easily get rid of option
1?
Thanks in advance for the help.

Jul 23 '05 #1
Share this question for a faster answer!
Share on Google+

This discussion thread is closed

Replies have been disabled for this discussion.