00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "ndatastream.h"
00023
00028 const nuint32 NDataStream::ALLOC_SIZE = 512;
00029
00030 NDataStream::NDataStream(void)
00031 : m_bo(BIGENDIAN),
00032 m_data(NULL),
00033 m_used(0),
00034 m_allocated(0)
00035 {
00036 realloc(ALLOC_SIZE);
00037 }
00038
00039 NDataStream::NDataStream(const NDataStream &stream)
00040 : m_bo(BIGENDIAN),
00041 m_data(NULL),
00042 m_used(0),
00043 m_allocated(0)
00044 {
00045 set(stream.toString());
00046 }
00047
00048
00049 NDataStream::NDataStream(const char *str)
00050 : m_bo(BIGENDIAN),
00051 m_data(NULL),
00052 m_used(0),
00053 m_allocated(0)
00054 {
00055 set(str);
00056 }
00057
00058 NDataStream::~NDataStream(void) {
00059 delete[] static_cast<char *>(m_data);
00060 }
00061
00062 inline bool NDataStream::needsMemory(nuint32 bytes) {
00063 if (bytes > m_allocated) {
00064 return true;
00065 }
00066
00067 if (bytes > (m_allocated - m_used)) {
00068 return true;
00069 }
00070
00071 return false;
00072 }
00073
00074 nuint32 NDataStream::calculateBlocks(nuint32 bytes) {
00075 nuint32 blocks = 0;
00076 nuint32 mod = 0;
00077
00078 blocks = bytes / ALLOC_SIZE;
00079 mod = bytes % ALLOC_SIZE;
00080 if (blocks == 0) {
00081 blocks = 1;
00082 }
00083
00084 if (mod > 0) {
00085 blocks++;
00086 }
00087
00088 return blocks;
00089 }
00090
00091
00092 void NDataStream::memcopy(void *dest) {
00093 assert(dest);
00094
00095 if (m_data) {
00096 memcpy(dest, m_data, m_used);
00097 delete[] static_cast<char *>(m_data);
00098 }
00099
00100 m_data = dest;
00101 }
00102
00103
00104 void NDataStream::realloc(nuint32 bytes) {
00105 nuint32 blocks = 0;
00106 nuint32 streamSize = 0;
00107 void *data_ptr = NULL;
00108
00109 if (!needsMemory(bytes)) {
00110 return;
00111 }
00112
00113 blocks = calculateBlocks(bytes + m_used);
00114 streamSize = blocks * ALLOC_SIZE;
00115
00116 data_ptr = new char[streamSize];
00117 memcopy(data_ptr);
00118 m_allocated = streamSize;
00119 }
00120
00121
00122 inline nuint32 NDataStream::freeBytes(void) const {
00123 return m_allocated - m_used;
00124 }
00125
00126 void NDataStream::setByteOrder(NDataStream::ByteOrder bo) {
00127 m_bo = bo;
00128 }
00129
00130 NDataStream::ByteOrder NDataStream::getByteOrder(void) const {
00131 return m_bo;
00132 }
00133
00134
00135 NDataStream &NDataStream::set(const char *str) {
00136 unsigned int len = 0;
00137
00138 assert(str);
00139
00140 len = strlen(str);
00141 if (m_allocated < len) {
00142 realloc(len);
00143 }
00144 memcpy(m_data, str, len);
00145 m_used = len;
00146
00147 return *this;
00148 }
00149
00150
00151 NDataStream &NDataStream::set(const NString &str) {
00152 return set(str.toChar());
00153 }
00154
00155
00156 NDataStream &NDataStream::set(const void *src, nuint32 bytes) {
00157 assert(src);
00158
00159 if (m_allocated < bytes) {
00160 realloc(bytes);
00161 }
00162 memcpy(m_data, src, bytes);
00163 m_used = bytes;
00164
00165 return *this;
00166 }
00167
00168 template<typename T>
00169 NDataStream &NDataStream::set(T val) {
00170 unsigned char c[sizeof(T)];
00171 nuint32 i = 0;
00172 int shift = 0;
00173 const int num_bits = 8;
00174
00175 if (getByteOrder() == LITTLEENDIAN) {
00176 do {
00177 c[i] = val >> shift;
00178 shift += num_bits;
00179 i++;
00180 } while (i < sizeof(T));
00181 }
00182 else {
00183 shift = (sizeof(T) * num_bits) - num_bits;
00184 do {
00185 c[i] = val >> shift;
00186 shift -= num_bits;
00187 i++;
00188 } while (i < sizeof(T));
00189 }
00190
00191 memset(m_data, 0, m_allocated);
00192 memcpy(m_data, c, sizeof(c));
00193 m_used = sizeof(T);
00194 return *this;
00195 }
00196
00197
00198 NDataStream &NDataStream::set(const nint16 val) {
00199 return set<nint16>(val);
00200 }
00201
00202
00203 NDataStream &NDataStream::set(const nuint16 val) {
00204 return set<nuint16>(val);
00205 }
00206
00207
00208
00209 NDataStream &NDataStream::set(const nint32 val) {
00210 return set<nint32>(val);
00211 }
00212
00213
00214 NDataStream &NDataStream::set(const nuint32 val) {
00215 return set<nuint32>(val);
00216 }
00217
00218
00219 NDataStream &NDataStream::set(const nint64 val) {
00220 nint32 a = 0;
00221 nint32 b = 0;
00222 const int num_bits = 8;
00223
00224 a |= val;
00225 b |= val >> (sizeof(nint64) * num_bits) / 2;
00226
00227 set<nint32>(a);
00228 return append<nint32>(b);
00229 }
00230
00231
00232 NDataStream &NDataStream::set(const nuint64 val) {
00233 nuint32 a = 0;
00234 nuint32 b = 0;
00235 const int num_bits = 8;
00236
00237 a |= val;
00238 b |= val >> (sizeof(nint64) * num_bits) / 2;
00239
00240 set<nint32>(a);
00241 return append<nuint32>(b);
00242 }
00243
00244
00245 NDataStream &NDataStream::append(const void *src, nuint32 bytes) {
00246
00247 assert(src);
00248
00249 if (freeBytes() < bytes) {
00250 realloc(bytes);
00251 }
00252
00253 memcat(m_data, m_used, src, bytes);
00254 m_used += bytes;
00255 return *this;
00256 }
00257
00258
00259 NDataStream &NDataStream::append(const char *str) {
00260 assert(str);
00261
00262 return append(str, strlen(str));
00263 }
00264
00265
00266 NDataStream &NDataStream::append(const NString &str) {
00267 return append(str.toChar());
00268 }
00269
00270
00271 template<typename T>
00272 NDataStream &NDataStream::append(T val) {
00273 unsigned char c[sizeof(T)];
00274 nuint32 i = 0;
00275 int shift = 0;
00276 const int num_bits = 8;
00277
00278 if (getByteOrder() == LITTLEENDIAN) {
00279 do {
00280 c[i] = val >> shift;
00281 shift += num_bits;
00282 i++;
00283 } while (i < sizeof(T));
00284 }
00285 else {
00286 shift = (sizeof(T) * num_bits) - num_bits;
00287 do {
00288 c[i] = val >> shift;
00289 shift -= num_bits;
00290 i++;
00291 } while (i < sizeof(T));
00292 }
00293
00294 memcat(m_data, m_used, c, sizeof(c));
00295 m_used += sizeof(T);
00296
00297 return *this;
00298 }
00299
00300 NDataStream &NDataStream::append(const nint16 val) {
00301 return append<nint16>(val);
00302 }
00303
00304
00305 NDataStream &NDataStream::append(const nuint16 val) {
00306 return append<nuint16>(val);
00307 }
00308
00309
00310 NDataStream &NDataStream::append(const nint32 val) {
00311 return append<nint32>(val);
00312 }
00313
00314
00315 NDataStream &NDataStream::append(const nuint32 val) {
00316 return append<nuint32>(val);
00317 }
00318
00319
00320 NDataStream &NDataStream::append(const nint64 val) {
00321 nint32 a = 0;
00322 nint32 b = 0;
00323 const int num_bits = 8;
00324
00325 a |= val;
00326 b |= val >> (sizeof(nint64) * num_bits) / 2;
00327
00328 append<nint32>(a);
00329 return append<nint32>(b);
00330 }
00331
00332
00333 NDataStream &NDataStream::append(const nuint64 val) {
00334 nuint32 a = 0;
00335 nuint32 b = 0;
00336 const int num_bits = 8;
00337
00338 a |= val;
00339 b |= val >> (sizeof(nint64) * num_bits) / 2;
00340
00341 append<nuint32>(a);
00342 return set<nuint32>(b);
00343 }
00344
00345 bool NDataStream::withinLimits(nuint32 start, nuint32 bytes) const {
00346 if (start > m_used) {
00347 return false;
00348 }
00349
00350 if (bytes > m_used) {
00351 return false;
00352 }
00353
00354 if ((start + bytes) > m_used) {
00355 return false;
00356 }
00357
00358 return true;
00359 }
00360
00361
00362 NString NDataStream::toString(nuint32 start, nuint32 bytes) const {
00363 NString ret;
00364 char *tmp = NULL;
00365
00366 if (!withinLimits(start, bytes)) {
00367 throw NException(N_OUTOFBOUNDS, NException::BASE,
00368 NException::EX_OUT_OF_BOUNDS);
00369 }
00370 tmp = new char[bytes + 1];
00371
00372 memset(tmp, 0, bytes + 1);
00373 memcpy(tmp, static_cast<char *>(m_data) + start, bytes);
00374 if (tmp[bytes] != '\0') {
00375 tmp[bytes] = '\0';
00376 }
00377
00378 ret.set(tmp);
00379 delete[] tmp;
00380
00381 return ret;
00382 }
00383
00384
00385 NString NDataStream::toString(nuint32 bytes) const {
00386 return toString(0, bytes);
00387 }
00388
00389 NString NDataStream::toString(void) const {
00390 return toString(m_used);
00391 }
00392
00393
00394 unsigned char NDataStream::toChar(void) const {
00395 return toChar(0);
00396 }
00397
00398 unsigned char NDataStream::toChar(nuint32 pos) const {
00399 return static_cast<char *>(m_data)[pos];
00400 }
00401
00402 template<typename T>
00403 T NDataStream::to(void) const {
00404 T ret = 0;
00405 int pos = 0;
00406 const int num_bits = 8;
00407
00408 if (getByteOrder() == LITTLEENDIAN) {
00409 pos = (sizeof(T) - 1);
00410 do {
00411 ret |= toChar(pos);
00412 if (pos != 0) {
00413 ret <<= num_bits;
00414 }
00415 pos--;
00416 }
00417 while (pos >= 0);
00418 }
00419 else {
00420 pos = 0;
00421 do {
00422 ret |= toChar(pos);
00423
00424 if (pos != (sizeof(T) - 1)) {
00425 ret <<= num_bits;
00426 }
00427 pos++;
00428 } while (pos != sizeof(T));
00429 }
00430
00431 return ret;
00432 }
00433
00434
00435 nint16 NDataStream::toInt16(void) const {
00436 return to<nint16>();
00437
00438 }
00439
00440
00441
00442 nint32 NDataStream::toInt32(void) const {
00443 return to<nint32>();
00444 }
00445
00446
00447
00448 nint64 NDataStream::toInt64(void) const {
00449 return to<nint32>();
00450 }
00451
00452 bool NDataStream::isNull(void) const {
00453 if (m_used == 0) {
00454 return true;
00455 }
00456
00457 return false;
00458 }
00459
00460 nuint32 NDataStream::size(void) const {
00461 return m_used;
00462 }
00463
00464
00465 const void *NDataStream::data(void) const {
00466 return m_data;
00467 }
00468
00469
00470 bool NDataStream::operator==(const NDataStream &rhs) const {
00471 if (size() != rhs.size()) {
00472 return false;
00473 }
00474
00475 if (memcmp(m_data, rhs.m_data, size()) == 0) {
00476 return true;
00477 }
00478
00479 return false;
00480 }
00481
00482 bool NDataStream::operator!=(const NDataStream &rhs) const {
00483 if (size() != rhs.size()) {
00484 return true;
00485 }
00486
00487 if (memcmp(m_data, rhs.m_data, size()) == 0) {
00488 return false;
00489 }
00490
00491 return true;
00492 }
00493
00494 NDataStream &NDataStream::operator=(const char *str) {
00495 return set(str);
00496 }
00497
00498 NDataStream &NDataStream::operator=(const NString &str) {
00499 return set(str);
00500 }
00501
00502 NDataStream &NDataStream::operator=(const NDataStream &str) {
00503 return set(str.toString());
00504 }
00505
00506 NDataStream &NDataStream::operator=(const nint16 val) {
00507 return set(val);
00508 }
00509
00510 NDataStream &NDataStream::operator=(const nuint16 val) {
00511 return set(val);
00512 }
00513
00514 NDataStream &NDataStream::operator=(const nint32 val) {
00515 return set(val);
00516 }
00517
00518 NDataStream &NDataStream::operator=(const nuint32 val) {
00519 return set(val);
00520 }
00521
00522 NDataStream &NDataStream::operator=(const nint64 val) {
00523 return set(val);
00524 }
00525
00526 NDataStream &NDataStream::operator=(const nuint64 val) {
00527 return set(val);
00528 }
00529
00530 NDataStream &NDataStream::operator+=(const char *str) {
00531 return append(str);
00532 }
00533
00534 NDataStream &NDataStream::operator+=(const NString &str) {
00535 return append(str);
00536 }
00537
00538 NDataStream &NDataStream::operator+=(const NDataStream &str) {
00539 return append(str.toString());
00540 }
00541
00542 NDataStream &NDataStream::operator+=(const nint16 val) {
00543 return append(val);
00544 }
00545
00546 NDataStream &NDataStream::operator+=(const nuint16 val) {
00547 return append(val);
00548 }
00549
00550 NDataStream &NDataStream::operator+=(const nint32 val) {
00551 return append(val);
00552 }
00553
00554 NDataStream &NDataStream::operator+=(const nuint32 val) {
00555 return append(val);
00556 }
00557
00558 NDataStream &NDataStream::operator+=(const nint64 val) {
00559 return append(val);
00560 }
00561
00562 NDataStream &NDataStream::operator+=(const nuint64 val) {
00563 return append(val);
00564 }
00565
00566 NDataStream NDataStream::operator+(const char *str) {
00567 return append(str);
00568 }
00569
00570 NDataStream NDataStream::operator+(const NString &str) {
00571 return append(str);
00572 }
00573
00574 NDataStream NDataStream::operator+(const NDataStream &str) {
00575 return append(str.toString());
00576 }
00577
00578 NDataStream NDataStream::operator+(const nint16 val) {
00579 return append(val);
00580 }
00581
00582 NDataStream NDataStream::operator+(const nuint16 val) {
00583 return append(val);
00584 }
00585
00586 NDataStream NDataStream::operator+(const nint32 val) {
00587 return append(val);
00588 }
00589
00590 NDataStream NDataStream::operator+(const nuint32 val) {
00591 return append(val);
00592 }
00593
00594 NDataStream NDataStream::operator+(const nint64 val) {
00595 return append(val);
00596 }
00597
00598 NDataStream NDataStream::operator+(const nuint64 val) {
00599 return append(val);
00600 }
00601
00602 unsigned char NDataStream::operator[](nuint32 pos) {
00603 if (pos >= m_used) {
00604 return 0;
00605 }
00606
00607 return static_cast<char *>(m_data)[pos];
00608 }