Main Page | Class Hierarchy | Class List | File List | Class Members

/Users/baford/proj/netsteria/sst/lib/xdr.h

Go to the documentation of this file.
00001 
00003 #ifndef SST_XDR_H
00004 #define SST_XDR_H
00005 
00006 #include <QIODevice>
00007 
00008 #include "os.h"
00009 
00010 class QByteArray;
00011 
00012 
00013 namespace SST {
00014 
00019 class XdrStream : public QObject
00020 {
00021 public:
00022         enum Status {
00023                 Ok = 0,
00024                 ReadPastEnd,
00025                 ReadCorruptData,
00026                 IOError,
00027         };
00028 
00029 private:
00030         QIODevice *dev;
00031         Status st;
00032 
00033         static char zeros[4];
00034 
00035 public:
00038         XdrStream();
00039 
00043         XdrStream(QIODevice *d);
00044 
00047         XdrStream(QByteArray *a, QIODevice::OpenMode mode);
00048 
00050         XdrStream(const QByteArray &a);
00051 
00052 
00054 
00056         inline QIODevice *device() { return dev; }
00057 
00059         void setDevice(QIODevice *d);
00060 
00061 
00063 
00065         inline Status status() const { return st; }
00066 
00068         inline void setStatus(Status st) { this->st = st; }
00069 
00071         inline void resetStatus() { setStatus(Ok); }
00072 
00073 
00075 
00077         inline bool atEnd() { return dev->atEnd(); }
00078 
00081         inline void readRawData(void *buf, int len) {
00082                 if (dev->read((char*)buf, len) < len)
00083                         setStatus(ReadPastEnd);
00084         }
00085 
00089         inline void skipRawData(int len) {
00090                 if (!dev->seek(dev->pos() + len))
00091                         setStatus(IOError);
00092         }
00093 
00096         inline void writeRawData(const void *buf, int len) {
00097                 if (dev->write((const char*)buf, len) < len)
00098                         setStatus(IOError);
00099         }
00100 
00101 
00103 
00107         void readPadData(void *buf, int len);
00108 
00110         void skipPadData(int len);
00111 
00115         void writePadData(const void *buf, int len);
00116 
00117 
00119 
00127         void readBytes(char *&s, qint32 &len);
00128 
00132         void writeBytes(const char *s, qint32 len);
00133 
00135         inline XdrStream &operator<<(bool b) {
00136                 qint32 v = htonl(b);
00137                 writeRawData(&v, 4);
00138                 return *this;
00139         }
00140 
00142         inline XdrStream &operator<<(qint8 i) {
00143                 qint32 v = htonl(i);
00144                 writeRawData(&v, 4);
00145                 return *this;
00146         }
00147 
00149         inline XdrStream &operator<<(qint16 i) {
00150                 qint32 v = htonl(i);
00151                 writeRawData(&v, 4);
00152                 return *this;
00153         }
00154 
00156         inline XdrStream &operator<<(qint32 i) {
00157                 qint32 v = htonl(i);
00158                 writeRawData(&v, 4);
00159                 return *this;
00160         }
00161 
00163         inline XdrStream &operator<<(qint64 i) {
00164                 qint32 v[2] = { htonl(i >> 32), htonl(i) };
00165                 Q_ASSERT(sizeof(v) == 8);
00166                 writeRawData(&v, 8);
00167                 return *this;
00168         }
00169 
00171         inline XdrStream &operator<<(quint8 i) {
00172                 return *this << (qint8)i;
00173         }
00174 
00176         inline XdrStream &operator<<(quint16 i) {
00177                 return *this << (qint16)i;
00178         }
00179 
00181         inline XdrStream &operator<<(quint32 i) {
00182                 return *this << (qint32)i;
00183         }
00184 
00186         inline XdrStream &operator<<(quint64 i) {
00187                 return *this << (qint64)i;
00188         }
00189 
00191         inline XdrStream &operator<<(float f) {
00192                 Q_ASSERT(sizeof(f) == 4);
00193                 return *this << *(qint32*)&f;
00194         }
00195 
00197         inline XdrStream &operator<<(double f) {
00198                 Q_ASSERT(sizeof(f) == 8);
00199                 return *this << *(qint64*)&f;
00200         }
00201 
00202 
00204 
00206         inline XdrStream &operator>>(bool &b) {
00207                 qint32 v;
00208                 readRawData(&v, 4);
00209                 b = (v != 0);
00210                 return *this;
00211         }
00212 
00214         inline XdrStream &operator>>(qint8 &i) {
00215                 qint32 v;
00216                 readRawData(&v, 4);
00217                 i = ntohl(v);
00218                 return *this;
00219         }
00220 
00222         inline XdrStream &operator>>(qint16 &i) {
00223                 qint32 v;
00224                 readRawData(&v, 4);
00225                 i = ntohl(v);
00226                 return *this;
00227         }
00228 
00230         inline XdrStream &operator>>(qint32 &i) {
00231                 qint32 v;
00232                 readRawData(&v, 4);
00233                 i = ntohl(v);
00234                 return *this;
00235         }
00236 
00238         inline XdrStream &operator>>(qint64 &i) {
00239                 quint32 v[2];
00240                 Q_ASSERT(sizeof(v) == 8);
00241                 readRawData(&v, 8);
00242                 i = ((quint64)(quint32)ntohl(v[0]) << 32) |
00243                         (quint32)ntohl(v[1]);
00244                 return *this;
00245         }
00246 
00248         inline XdrStream &operator>>(quint8 &i) {
00249                 return *this >> *(qint8*)&i;
00250         }
00251 
00253         inline XdrStream &operator>>(quint16 &i) {
00254                 return *this >> *(qint16*)&i;
00255         }
00256 
00258         inline XdrStream &operator>>(quint32 &i) {
00259                 return *this >> *(qint32*)&i;
00260         }
00261 
00263         inline XdrStream &operator>>(quint64 &i) {
00264                 return *this >> *(qint64*)&i;
00265         }
00266 
00268         inline XdrStream &operator>>(float &f) {
00269                 Q_ASSERT(sizeof(f) == 4);
00270                 return *this >> *(qint32*)&f;
00271         }
00272 
00274         inline XdrStream &operator>>(double &f) {
00275                 Q_ASSERT(sizeof(f) == 8);
00276                 return *this >> *(qint64*)&f;
00277         }
00278 
00280         XdrStream &operator>>(QByteArray &a);
00281 
00283         XdrStream &operator<<(const QByteArray &a);
00284 
00286         XdrStream &operator<<(const QString &s);
00287 
00289         XdrStream &operator>>(QString &s);
00290 
00291 
00294         QString errorString();
00295 };
00296 
00297 
00298 // Helper functions for encoding/decoding vectors and arrays
00299 template<class T>
00300 void xdrEncodeVector(XdrStream &xs, const QList<T> &l, int len)
00301 {
00302         Q_ASSERT(l.size() == len);
00303         for (int i = 0; i < len; i++) {
00304                 if (xs.status() != xs.Ok)
00305                         return;
00306                 xs << l.at(i);
00307         }
00308 }
00309 
00310 template<class T>
00311 void xdrDecodeVector(XdrStream &xs, QList<T> &l, int len)
00312 {
00313         l.clear();
00314         for (int i = 0; i < len; i++) {
00315                 if (xs.status() != xs.Ok)
00316                         return;
00317                 T v;
00318                 xs >> v;
00319                 l.append(v);
00320         }
00321 }
00322 
00323 template<class T>
00324 void xdrEncodeArray(XdrStream &xs, const QList<T> &l, quint32 maxlen)
00325 {
00326         quint32 len = l.size();
00327         Q_ASSERT(len <= maxlen);
00328         xs << len;
00329         for (quint32 i = 0; i < len; i++) {
00330                 if (xs.status() != xs.Ok)
00331                         return;
00332                 xs << l.at(i);
00333         }
00334 }
00335 
00336 template<class T>
00337 void xdrDecodeArray(XdrStream &xs, QList<T> &l, quint32 maxlen)
00338 {
00339         quint32 len;
00340         xs >> len;
00341         if (len > maxlen)
00342                 return xs.setStatus(xs.ReadCorruptData);
00343         l.clear();
00344         for (quint32 i = 0; i < len; i++) {
00345                 if (xs.status() != xs.Ok)
00346                         return;
00347                 T v;
00348                 xs >> v;
00349                 l.append(v);
00350         }
00351 }
00352 
00353 
00354 // Helper functions for encoding/decoding byte vectors and arrays
00355 inline void xdrEncodeVector(XdrStream &xs, const QByteArray &v, int len)
00356 {
00357         Q_ASSERT(v.size() == len);
00358         xs.writeRawData(v.constData(), len);
00359 }
00360 
00361 inline void xdrDecodeVector(XdrStream &xs, QByteArray &v, int len)
00362 {
00363         v.resize(len);
00364         xs.readRawData(v.data(), len);
00365 }
00366 
00367 inline void xdrEncodeArray(XdrStream &xs, const QByteArray &v, quint32 maxlen)
00368 {
00369         Q_ASSERT((quint32)v.size() <= maxlen);
00370         xs << v;
00371 }
00372 
00373 inline void xdrDecodeArray(XdrStream &xs, QByteArray &v, quint32 maxlen)
00374 {
00375         xs >> v;
00376         if ((quint32)v.size() > maxlen)
00377                 return xs.setStatus(xs.ReadCorruptData);
00378 }
00379 
00380 
00381 
00390 template<class T> class XdrPointer
00391 {
00392 private:
00393         T *i;
00394 
00395 public:
00396         inline XdrPointer() : i(0) { }
00397         inline XdrPointer(const T &o) : i(new T(o)) { }
00398         inline XdrPointer(const XdrPointer<T> &o)
00399                 : i(o.i ? new T(*o.i) : 0) { }
00400 
00401         inline ~XdrPointer() { if (i) delete i; }
00402 
00403         inline bool isNull() const { return i == 0; }
00404         inline void clear() { if (i) { delete i; i = 0; } }
00405         inline T& alloc() { if (!i) i = new T; return *i; }
00406 
00407         inline XdrPointer<T> &operator=(const XdrPointer<T> &o)
00408                 { clear(); if (o.i) i = new T(*o.i); }
00409         inline XdrPointer<T> &operator=(T *o)
00410                 { clear(); if (o) i = new T(o); }
00411 
00412         inline T* operator->() const { return i; }
00413         inline T& operator*() const { return *i; }
00414         inline operator T*() const { return i; }
00415 };
00416 
00417 template<class T>
00418 inline XdrStream &operator<<(XdrStream &xs, const XdrPointer<T> &p)
00419         { if (p) { xs << true << *p; } else { xs << false; }; return xs; }
00420 template<class T>
00421 inline XdrStream &operator>>(XdrStream &xs, XdrPointer<T> &p)
00422         { bool f; xs >> f; if (f) { xs >> p.alloc(); } else p.clear();
00423           return xs; }
00424 
00425 
00435 template<class T> class XdrOption
00436 {
00437 private:
00438         T *i;                           // Decoded option value
00439         QByteArray enc;                 // Encoded option value
00440 
00441 public:
00442         inline XdrOption() : i(NULL) { }
00443         inline XdrOption(const T &o) : i(new T(o)) { }
00444         inline XdrOption(const XdrOption<T> &o)
00445                 : i(o.i ? new T(*o.i) : NULL), enc(o.enc) { }
00446 
00447         inline ~XdrOption() { if (i) { delete i; i = NULL; } }
00448 
00450         inline bool isNull() const { return i == NULL; }
00451 
00453         inline bool isEmpty() const { return i == NULL && enc.isEmpty(); }
00454 
00455         // Set or clear the item's decoded representation
00456         inline T& alloc() { enc.clear(); if (!i) i = new T; return *i; }
00457         inline void clear() { enc.clear(); if (i) { delete i; i = NULL; } }
00458 
00459         // Set or clear the item's encoded representation
00460         inline QByteArray getEncoded() const { return enc; }
00461         inline void setEncoded(const QByteArray &e)
00462                 { clear(); enc = e; }
00463 
00464         inline XdrOption<T> &operator=(const XdrOption<T> &o)
00465                 { clear(); if (o.i) i = new T(*o.i); enc = o.enc;
00466                   return *this; }
00467         inline XdrOption<T> &operator=(T *o)
00468                 { clear(); if (o) i = new T(o); return *this; }
00469 
00470         inline T* operator->() const { return i; }
00471         inline T& operator*() const { return *i; }
00472         inline operator T*() const { return i; }
00473 };
00474 
00475 template<class T>
00476 XdrStream &operator<<(XdrStream &xs, const XdrOption<T> &o)
00477 {
00478         if (!o.isNull()) {
00479                 QByteArray buf;
00480                 XdrStream bxs(&buf, QIODevice::WriteOnly);
00481                 bxs << *o;
00482                 xs << buf;
00483         } else
00484                 xs << o.getEncoded();
00485         return xs;
00486 }
00487 
00488 template<class T>
00489 XdrStream &operator>>(XdrStream &xs, XdrOption<T> &o)
00490 {
00491         QByteArray buf;
00492         xs >> buf;
00493         if (buf.isEmpty()) {
00494                 o.clear();
00495                 return xs;
00496         }
00497         XdrStream bxs(&buf, QIODevice::ReadOnly);
00498         bxs >> o.alloc();
00499         if (bxs.status() != bxs.Ok)
00500                 o.setEncoded(buf);
00501         return xs;
00502 }
00503 
00504 } // namespace SST
00505 
00506 #endif  // SST_XDR_H

Generated on Wed Mar 28 11:48:05 2007 for SST by doxygen 1.3.4