CNER.h
Go to the documentation of this file.
00001 #ifndef CASTOR_ENCODING_CNER_H
00002 #define CASTOR_ENCODING_CNER_H 1
00003 
00004 #include <sstream>
00005 #include <iostream>
00006 
00007 #include "Encoding.h"
00008 #include "EncodingException.h"
00009 
00010 namespace castor { namespace encoding {
00011 
00012         class CNER : public Encoder, public Decoder {
00013 
00014                 private:
00015 
00016                         std::stringstream buffer;
00017 
00018                         bool doSwitchEndian;
00019 
00020                         bool marked;
00021                         size_t marker;
00022 
00023                         size_t length;
00024 
00025                         inline void writeInternal(const char *data, size_t length, bool ignoreEndian = false) {
00026 
00027                                 if (this->mode != encode) return;
00028 
00029                                 if ((this->doSwitchEndian) && (!ignoreEndian)) {
00030 
00031                                         if (length > 0) {
00032                                                 char temp[length];
00033                                                 for (int i = length - 1; i >= 0; i--) {
00034                                                         temp[i] = data[(length - 1) - i];
00035                                                 }
00036                                                 this->buffer.write(temp, length);
00037 //                                                      this->buffer.put(data[i]);
00038 //                                              }
00039                                         }
00040 
00041                                 } else {
00042                                         this->buffer.write(data, length);
00043 
00044 //                                      for (size_t i = 0; i < length; i++) {
00045 //                                              this->buffer.put(data[i]);
00046 //                                      }
00047                                 }
00048                         }
00049 
00050                         inline void readInternal(char *data, size_t length, bool ignoreEndian = false) {
00051 
00052                                 if (this->mode != decode) return;
00053 
00054                                 if ((this->doSwitchEndian) && (!ignoreEndian)) {
00055 
00056                                         if (length > 0) {
00057                                                 char temp[length];
00058                                                 this->buffer.read(temp, length);
00059 
00060                                                 for (int i = length - 1; i >= 0; i--) {
00061                                                         data[i] = temp[(length - 1) - i];
00062 //                                                      this->buffer.get();
00063                                                 }
00064                                         }
00065 
00066                                 } else {
00067                                         this->buffer.read(data, length);
00068 
00069 //                                      for (size_t i = 0; i < length; i++) {
00070 //                                              data[i] = this->buffer.get();
00071 //                                      }
00072                                 }
00073                         }
00074 
00075                         enum { encode, decode } mode;
00076 
00077                 public:
00078         
00079                         CNER() :
00080                                 buffer(std::ios_base::out), doSwitchEndian(false),
00081                                 marked(false), marker(0), length(0), mode(encode)
00082                         {
00083                         }
00084 
00085                         CNER(const BytesPtr x, size_t offset) :
00086                                 buffer(std::string(x->begin() + offset, x->end()), std::ios_base::in),
00087                                 doSwitchEndian(false), marked(false), marker(0), length(x->size()), mode(decode)
00088                         {
00089                         }
00090 
00091                         CNER(const char *x, size_t length) :
00092                                 buffer(std::string(x, length), std::ios_base::in),
00093                                 doSwitchEndian(false), marked(false), marker(0), length(length), mode(decode)
00094                         {
00095                         }
00096 
00097                         CNER(const char *x, size_t offset, size_t length) :
00098                                 buffer(std::string(std::string(x, length), offset),
00099                                         std::ios_base::in),
00100                                 doSwitchEndian(false), marked(false), marker(0), length(length), mode(decode)
00101                         {
00102                         }
00103 
00104                         ~CNER() { }
00105 
00106                         inline EncoderPtr createEncoder() {
00107                                 return EncoderPtr(new CNER());
00108                         }
00109 
00110                         inline DecoderPtr createDecoder(const BytesPtr x, size_t offset = 0) {
00111                                 return DecoderPtr(new CNER(x, offset));
00112                         }
00113 
00114                         inline DecoderPtr createDecoder(const char *x, size_t length) {
00115                                 return DecoderPtr(new CNER(x, length));
00116                         }
00117 
00118                         DecoderPtr createDecoder(const char *x, size_t offset, size_t length) {
00119                                 return DecoderPtr(new CNER(x, offset, length));
00120                         }
00121 
00122                         inline void switchEndianness(bool yes) {
00123                                 this->doSwitchEndian = yes;
00124                         }
00125 
00126                         inline size_t getLength() {
00127 
00128                                 size_t length = 0;
00129 
00130                                 if (this->mode == encode) {
00131 
00132                                         size_t pos = this->buffer.tellp();
00133 
00134                                         this->buffer.seekp(0, std::ios::end);
00135                                         length = this->buffer.tellp();
00136                                         this->buffer.seekp(pos, std::ios::beg);
00137 
00138                                 } else {
00139 
00140                                         size_t pos = this->buffer.tellg();
00141 
00142                                         this->buffer.seekg(0, std::ios::end);
00143                                         length = this->buffer.tellg();
00144                                         this->buffer.seekg(pos, std::ios::beg);
00145                                 }
00146 
00147                                 return length;
00148                         }
00149 
00150                         inline size_t getPosition() {
00151                                 return (this->mode == encode ?
00152                                                 this->buffer.tellp() :
00153                                                 this->buffer.tellg());
00154                         }
00155 
00156                         inline const char *getBuffer() {
00157                                 return this->buffer.str().c_str();
00158                         }
00159 
00160                         inline BytesPtr getBytes() {
00161                                 std::string x = this->buffer.str();
00162                                 return BytesPtr(new Bytes(x.begin(), x.end()));
00163                         }
00164 
00165                         inline void mark() {
00166                                 this->marked = true;
00167                                 this->marker = getPosition();
00168                         }
00169 
00170                         inline void commit() {
00171                                 this->marked = false;
00172                                 this->marker = 0;
00173                         }
00174                         
00175                         inline void rollback() {
00176                         
00177                                 if (this->mode == encode) {
00178                                         this->buffer.seekp(this->marker, std::ios_base::beg);
00179                                 } else {
00180                                         this->buffer.seekg(this->marker, std::ios_base::beg);
00181                                 }
00182                                 this->marked = false;
00183                                 this->marker = 0;
00184                         }
00185 
00186                         inline void reset() {
00187                                 if (this->mode == encode) {
00188                                         this->buffer.str("");
00189                                 } else {
00190                                         this->buffer.seekg(0, std::ios_base::beg);
00191                                 }
00192 
00193                                 this->buffer.clear();
00194                                 this->marked = false;
00195                                 this->marker = 0;
00196                         }
00197 
00198                         inline void seek(long offset) {
00199                                 if (this->mode == encode) {
00200                                         this->buffer.seekp(offset, std::ios_base::cur);
00201                                 } else {
00202                                         this->buffer.seekg(offset, std::ios_base::cur);
00203                                 }
00204                         }
00205 
00206                         inline void encLength(size_t x) {
00207 
00208                                 if (this->mode != encode) throw EncodingException("wanted to encode while being in decode mode");
00209 
00210                                 if (x == 0) {
00211                                         this->buffer.put(0);
00212                                         return;
00213                                 }
00214 
00215                                 while (x > 0) {
00216 
00217                                         // Get the lowest 7 bits
00218                                         char c = (char)(x & 0x7f);
00219 
00220                                         // Remove these bits
00221                                         x >>= 7;
00222 
00223                                         // Write them down to the stream.
00224                                         // If the highest order bit is '1', there are more bytes coming.
00225                                         // We're processing the last byte if the highest order bit is '0'
00226                                         this->buffer.put((x == 0 ? c : (c | 0x80)));
00227                                 }
00228                         }
00229 
00230                         inline void encBool(bool x) {
00231                                 if (this->mode != encode) return;
00232                                 this->buffer.put((char)x);
00233                         }
00234 
00235                         inline void encInt8(char x) {
00236                                 if (this->mode != encode) return;
00237                                 this->buffer.put(x);
00238                         }
00239 
00240                         inline void encUInt8(unsigned char x) {
00241                                 if (this->mode != encode) return;
00242                                 this->buffer.put((char)x);
00243                         }
00244 
00245                         inline void encInt16(short x) {
00246                                 writeInternal((char *)&x, 2);
00247                         }
00248 
00249                         inline void encUInt16(unsigned short x) {
00250                                 writeInternal((char *)&x, 2);
00251                         }
00252 
00253                         inline void encInt32(long x) {
00254                                 writeInternal((char *)&x, 4);
00255                         }
00256 
00257                         inline void encUInt32(unsigned long x) {
00258                                 writeInternal((char *)&x, 4);
00259                         }
00260 
00261                         inline void encInt64(long long x) {
00262                                 writeInternal((char *)&x, 8);
00263                         }
00264 
00265                         inline void encUInt64(unsigned long long x) {
00266                                 writeInternal((char *)&x, 8);
00267                         }
00268 
00269                         inline void encFloat(float x) {
00270                                 writeInternal((char *)&x, 4);
00271                         }
00272 
00273                         /*inline void encDouble(double x) {
00274                                 writeInternal((char *)&x, 8);
00275                         }*/
00276                         inline void encDouble(double x) {
00277                                 float y = (float)x;
00278                                 writeInternal((char *)&y, 4);
00279                         }
00280 
00281                         inline void encString(const std::string x) {
00282                                 if (this->mode != encode) return;
00283                                 encLength(x.size());
00284                                 writeInternal(x.c_str(), x.size(), true);
00285                         }
00286 
00287                         inline void encAddress(const castor::net::NetAddress &x) {
00288 
00289                                 if (this->mode != encode) return;
00290                                 BytesPtr b = x.getBytes();
00291                                 encLength(b->size());
00292                                 writeInternal(&((*b)[0]), b->size(), true);
00293                         }
00294 
00295                         inline void encBytes(const Bytes &x) {
00296                                 writeInternal(&x[0], x.size(), true);
00297                         }
00298 
00299                         inline void encBytes(const Bytes &x, size_t offset, size_t length) {
00300                                 if (this->mode != encode) return;
00301 
00302                                 if (length + offset > x.size()) {
00303                                         throw EncodingException("CNER: offset + length > x.size()");
00304                                 }
00305                                 writeInternal(&x[offset], length, true);
00306                         }
00307 
00308                         inline void encBytes(const char *x, size_t length) {
00309                                 writeInternal(x, length, true);
00310                         }
00311 
00312                         inline void encBytes(const char *x, size_t offset, size_t length) {
00313                                 writeInternal(&(x[offset]), length, true);
00314                         }
00315 
00316                         inline size_t decLength() {
00317                                 if (this->mode != decode) return 0;
00318 
00319                                 int bitsRead = 0;
00320                                 size_t result = 0;
00321                                 char c = 0;
00322 
00323                                 // Read until the end of the length field is reached
00324                                 do {
00325 
00326                                         c = this->buffer.get();
00327 
00328                                         // If more than 9 bytes were read (9 * 7 Bit = 63 Bit), abort
00329                                         if (bitsRead >= 64) {
00330                                                 throw EncodingException("CNER: length field overflow (> 2^64)");
00331                                         }
00332 
00333                                         result |= (static_cast<size_t>(c & 0x7f) << bitsRead);
00334                                         bitsRead += 7;
00335 
00336                                         // Continue until the highest ordered bit is 0
00337 
00338                                 } while ((c & 0x80) != 0);
00339 
00340                                 return result;
00341                         }
00342 
00343                         inline bool decBool() {
00344                                 if (this->mode != decode) return false;
00345                                 return static_cast<bool>(this->buffer.get());
00346                         }
00347 
00348                         inline char decInt8() {
00349                                 if (this->mode != decode) return 0;
00350                                 return this->buffer.get();
00351                         }
00352 
00353                         inline unsigned char decUInt8() {
00354                                 if (this->mode != decode) return 0;
00355                                 return static_cast<unsigned char>(this->buffer.get());
00356                         }
00357 
00358                         inline short decInt16() {
00359                                 short x = 0;
00360                                 readInternal((char *)&x, 2);
00361                                 return x;
00362                         }
00363 
00364                         inline unsigned short decUInt16() {
00365                                 unsigned short x = 0;
00366                                 readInternal((char *)&x, 2);
00367                                 return x;
00368                         }
00369 
00370                         inline long decInt32() {
00371                                 long x = 0;
00372                                 readInternal((char *)&x, 4);
00373                                 return x;
00374                         }
00375 
00376                         inline unsigned long decUInt32() {
00377                                 unsigned long x = 0;
00378                                 readInternal((char *)&x, 4);
00379                                 return x;
00380                         }
00381 
00382                         inline long long decInt64() {
00383                                 long long x = 0;
00384                                 readInternal((char *)&x, 8);
00385                                 return x;
00386                         }
00387 
00388                         inline unsigned long long decUInt64() {
00389                                 unsigned long long x = 0;
00390                                 readInternal((char *)&x, 8);
00391                                 return x;
00392                         }
00393 
00394                         inline float decFloat() {
00395                                 float x = 0;
00396                                 readInternal((char *)&x, 4);
00397                                 return x;
00398                         }
00399 
00400                         /*inline double decDouble() {
00401                                 double x = 0;
00402                                 readInternal((char *)&x, 8);
00403                                 return x;
00404                         }*/
00405                         inline double decDouble() {
00406                                 float x = 0;
00407                                 readInternal((char *)&x, 4);
00408                                 return (double)x;
00409                         }
00410                         
00411                         inline std::string decString() {
00412                                 size_t length = decLength();
00413                                 char x[length];
00414                                 readInternal(x, length, true);
00415                                 return std::string(x, length);
00416                         }
00417 
00418                         inline castor::net::NetAddress decAddress() {
00419                                 if (this->mode != decode) return castor::net::NetAddress();
00420 
00421                                 size_t length = decLength();
00422                                 BytesPtr x(new Bytes(length, 0));
00423                                 readInternal(&((*x)[0]), length, true);
00424                                 return castor::net::NetAddress(x);
00425                         }
00426 
00427                         inline BytesPtr decBytes(size_t length) {
00428                                 if (this->mode != decode) return BytesPtr();
00429                                 BytesPtr x(new Bytes(length, 0));
00430                                 readInternal(&((*x)[0]), length, true);
00431                                 return x;
00432                         }
00433         };
00434 
00435 } }
00436 
00437 #endif /* CASTOR_ENCODING_CNER_H */
00438 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines


Castor
Author(s): Carpe Noctem
autogenerated on Fri Nov 8 2013 11:05:39