ndatastream.cpp

Go to the documentation of this file.
00001 // LICENSE: (Please see the file COPYING for details)
00002 //
00003 // NUS - Nemesis Utilities System: A C++ application development framework 
00004 // Copyright (C) 2006, 2008 Otavio Rodolfo Piske
00005 //
00006 //  This file is part of NUS
00007 //
00008 //  This library is free software; you can redistribute it and/or
00009 //  modify it under the terms of the GNU Lesser General Public
00010 //  License as published by the Free Software Foundation version 2.1
00011 //  of the License.
00012 //
00013 //  This library is distributed in the hope that it will be useful,
00014 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
00015 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00016 //  Lesser General Public License for more details.
00017 //
00018 //  You should have received a copy of the GNU Lesser General Public
00019 //  License along with this library; if not, write to the Free Software
00020 //  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
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 }

Generated on Wed Mar 5 23:10:35 2008 for NemesisUtilitiesSystem by  doxygen 1.5.4