$search
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