00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "MessageBuffer.hh"
00023 #include "Exception.hh"
00024 #include "PrettyDebug.hh"
00025 #include <cassert>
00026 #include <sstream>
00027 #include <iomanip>
00028 #include <cstring>
00029
00030 namespace certi {
00031
00032 static PrettyDebug D("MB","MB::");
00033
00034 const bool
00035 MessageBuffer::HostIsBigEndian() {
00036 #ifdef HOST_IS_BIG_ENDIAN
00037 return true;
00038 #else
00039 return false;
00040 #endif
00041 }
00042
00043 const bool
00044 MessageBuffer::HostIsLittleEndian() {
00045 #ifdef HOST_IS_BIG_ENDIAN
00046 return false;
00047 #else
00048 return true;
00049 #endif
00050 }
00051
00052 void
00053 MessageBuffer::show(const void* data, uint32_t n) {
00054 uint32_t i;
00055 const uint8_t* u8data = reinterpret_cast<const uint8_t*>(data);
00056 for (i=0;i<n;++i) {
00057 if ((0==(i%2))&&(i>0)) {
00058 printf(" ");
00059 }
00060 printf("%02X",u8data[i]);
00061 }
00062 }
00063
00064 const uint8_t MessageBuffer::reservedBytes = 5;
00065
00066 void MessageBuffer::initialize() {
00067 buffer = NULL;
00068 bufferMaxSize = DEFAULT_MESSAGE_BUFFER_SIZE;
00069 bufferHasMyEndianness = true;
00070 writeOffset = reservedBytes;
00071 readOffset = reservedBytes;
00072 }
00073
00074 MessageBuffer::MessageBuffer() {
00075 initialize();
00076 reallocate(DEFAULT_MESSAGE_BUFFER_SIZE);
00077 }
00078
00079 MessageBuffer::MessageBuffer(uint32_t n) {
00080 initialize();
00081 reallocate(n);
00082 }
00083
00084
00085
00086
00087
00088 void MessageBuffer::reallocate(uint32_t n) {
00089 uint8_t* oldbuf = buffer;
00090
00091
00092
00093
00094
00095 if ((NULL==buffer) || (n > bufferMaxSize)) {
00096
00097
00098 buffer = new uint8_t[n];
00099 bufferMaxSize = n;
00100
00101
00102
00103
00104
00105 if (NULL!=oldbuf) {
00106 memcpy(buffer, oldbuf, writeOffset);
00107 delete[] oldbuf;
00108 oldbuf = NULL;
00109 } else {
00110 updateReservedBytes();
00111 }
00112 }
00113 }
00114
00115 MessageBuffer::~MessageBuffer() {
00116 if (NULL!=buffer) {
00117 delete[] buffer;
00118 }
00119 }
00120
00121 uint32_t MessageBuffer::size() const {
00122 return writeOffset;
00123 }
00124
00125 uint32_t MessageBuffer::maxSize() const {
00126 return bufferMaxSize;
00127 }
00128
00129 void MessageBuffer::assumeBufferIsBigEndian() {
00130 this->bufferHasMyEndianness = HostIsBigEndian();
00131 buffer[0] = 0x01;
00132 }
00133
00134 void MessageBuffer::assumeBufferIsLittleEndian() {
00135 this->bufferHasMyEndianness = HostIsLittleEndian();
00136 buffer[0] = 0x00;
00137 }
00138
00139 void MessageBuffer::reset() {
00140 bufferHasMyEndianness = true;
00141 writeOffset = reservedBytes;
00142 readOffset = reservedBytes;
00143 updateReservedBytes();
00144 }
00145
00146 uint32_t MessageBuffer::resize(uint32_t newSize) {
00147 reallocate(newSize);
00148 return bufferMaxSize;
00149 }
00150
00151 void MessageBuffer::assumeSize(uint32_t size) {
00152
00153
00154
00155
00156 if (size <= bufferMaxSize) {
00157 writeOffset = size;
00158 } else {
00159 writeOffset = bufferMaxSize;
00160 }
00161 }
00162
00163 void MessageBuffer::assumeSizeFromReservedBytes() {
00164 uint32_t toBeAssumedSize;
00165
00166 if (buffer[0]==0x01) {
00167 assumeBufferIsBigEndian();
00168 } else {
00169 assumeBufferIsLittleEndian();
00170 }
00171
00172 readOffset = 1;
00173 toBeAssumedSize = this->read_uint32();
00174
00175 reallocate(toBeAssumedSize);
00176 assumeSize(toBeAssumedSize);
00177 }
00178
00179 void MessageBuffer::setSizeInReservedBytes(uint32_t n) {
00180 uint32_t oldWR_Offset;
00181
00182 oldWR_Offset = writeOffset;
00183
00184 writeOffset = 1;
00185 D.Out(pdTrace,"setSizeInReservedBytes(%u)",n);
00186 write_uint32(n);
00187
00188 writeOffset = oldWR_Offset;
00189 }
00190
00191 int32_t MessageBuffer::write_uint8s(const uint8_t* data, uint32_t n) {
00192 D.Out(pdTrace,"write_uint8s(%p = [%u ...] , %d)",data,n>0?data[0]:0,n);
00193
00194 if (n >= (bufferMaxSize - writeOffset)) {
00195
00196 reallocate(bufferMaxSize+ (n-(bufferMaxSize-writeOffset))
00197 + DEFAULT_MESSAGE_BUFFER_SIZE);
00198 }
00199
00200 memcpy(buffer+writeOffset, data, n);
00201
00202 writeOffset += n;
00203 return (writeOffset-n);
00204 }
00205
00206 int32_t MessageBuffer::read_uint8s(uint8_t* data, uint32_t n) {
00207 if (n + readOffset > writeOffset) {
00208 std::stringstream smsg;
00209 smsg << "read_uint8s::invalid read of size <" << n
00210 << "> inside a buffer of readable size <"
00211 << (int32_t)writeOffset-readOffset << "> (writeOffset="
00212 <<writeOffset << ",readOffset="<<readOffset <<").";
00213 throw RTIinternalError(smsg.str().c_str());
00214 }
00215
00216 memcpy(data, buffer+readOffset, n);
00217 readOffset += n;
00218 D.Out(pdTrace,"read_uint8s(%p = [%u ...], %d)",data,n>0?data[0]:0,n);
00219 return (readOffset-n);
00220 }
00221
00222 int32_t MessageBuffer::write_uint16s(const uint16_t* data, uint32_t n) {
00223 uint32_t i;
00224 uint16_t an_uint16;
00225 D.Out(pdTrace,"write_uint16s(%p = [%u ...], %d)",data,n>0?data[0]:0,n);
00226
00227 if ((2*n) >= (bufferMaxSize - writeOffset)) {
00228
00229 reallocate(bufferMaxSize+ (2*n)-(bufferMaxSize - writeOffset)
00230 + DEFAULT_MESSAGE_BUFFER_SIZE);
00231 }
00232
00233
00234 if (bufferHasMyEndianness) {
00235 memcpy(buffer+writeOffset, data, 2*n);
00236 writeOffset += 2*n;
00237 } else {
00238 for (i=0; i<n; ++i) {
00239 an_uint16 = CERTI_UINT16_SWAP_BYTES(data[i]);
00240 memcpy(buffer+writeOffset, &an_uint16, 2);
00241 writeOffset += 2;
00242 }
00243 }
00244 return (writeOffset-2*n);
00245 }
00246
00247 int32_t MessageBuffer::read_uint16s(uint16_t* data, uint32_t n) {
00248 uint32_t i;
00249 uint16_t an_uint16;
00250
00251 if (2*n + readOffset > writeOffset) {
00252 std::stringstream smsg;
00253 smsg << "read_uint16s::invalid read of size <" << 2*n
00254 << "> inside a buffer of readable size <"
00255 << (int32_t)writeOffset-readOffset << "> (writeOffset="
00256 <<writeOffset << ",readOffset="<<readOffset <<").";
00257 throw RTIinternalError(smsg.str().c_str());
00258 }
00259
00260
00261 if (bufferHasMyEndianness) {
00262 memcpy(data, buffer+readOffset, 2*n);
00263 readOffset += 2*n;
00264 } else {
00265 for (i=0; i<n; ++i) {
00266 memcpy(&an_uint16, buffer+readOffset,2);
00267 data[i] = CERTI_UINT16_SWAP_BYTES(an_uint16);
00268 readOffset += 2;
00269 }
00270 }
00271
00272 D.Out(pdTrace,"read_uint16s(%p = [%u ...], %d)",data,n>0?data[0]:0,n);
00273 return (readOffset-2*n);
00274 }
00275
00276 int32_t MessageBuffer::write_uint32s(const uint32_t* data, uint32_t n) {
00277 uint32_t i;
00278 uint32_t an_uint32;
00279 D.Out(pdTrace,"write_uint32s(%p = [%u ...] , %d)",data,n>0?data[0]:0,n);
00280
00281 if ((4*n) >= (bufferMaxSize - writeOffset)) {
00282
00283 reallocate(bufferMaxSize+ (4*n)-(bufferMaxSize - writeOffset)
00284 + DEFAULT_MESSAGE_BUFFER_SIZE);
00285 }
00286
00287
00288 if (bufferHasMyEndianness) {
00289 memcpy(buffer+writeOffset, data, 4*n);
00290 writeOffset += 4*n;
00291 } else {
00292 for (i=0; i<n; ++i) {
00293 an_uint32 = CERTI_UINT32_SWAP_BYTES(data[i]);
00294 memcpy(buffer+writeOffset,&an_uint32,4);
00295 writeOffset += 4;
00296 }
00297 }
00298 return (writeOffset-4*n);
00299 }
00300
00301 int32_t MessageBuffer::read_uint32s(uint32_t* data, uint32_t n) {
00302 uint32_t i;
00303 uint32_t an_uint32;
00304
00305 if (4*n + readOffset > writeOffset) {
00306 std::stringstream smsg;
00307 smsg << "read_uint32s::invalid read of size <" << 4*n
00308 << "> inside a buffer of readable size <"
00309 << (int32_t)writeOffset-readOffset << "> (writeOffset="
00310 <<writeOffset << ",readOffset="<<readOffset <<").";
00311 throw RTIinternalError(smsg.str().c_str());
00312 }
00313
00314
00315 if (bufferHasMyEndianness) {
00316 memcpy(data, buffer+readOffset, 4*n);
00317 readOffset += 4*n;
00318 } else {
00319 for (i=0; i<n; ++i) {
00320 memcpy(&an_uint32,buffer+readOffset,4);
00321 data[i] = CERTI_UINT32_SWAP_BYTES(an_uint32);
00322 readOffset += 4;
00323 }
00324 }
00325 D.Out(pdTrace,"read_uint32s(%p = [%u ...], %d)",data,n>0?data[0]:0,n);
00326 return (readOffset-4*n);
00327 }
00328
00329 int32_t MessageBuffer::write_uint64s(const uint64_t* data, uint32_t n) {
00330 uint32_t i;
00331 union deux32 {
00332 uint32_t ui32[2];
00333 uint64_t ui64;
00334 } a_deux32;
00335 uint32_t an_uint32;
00336
00337 D.Out(pdTrace,"write_uint64s(%p , %d)",data,n);
00338
00339 if ((8*n) >= (bufferMaxSize - writeOffset)) {
00340
00341 reallocate(bufferMaxSize+ (8*n)-(bufferMaxSize - writeOffset)
00342 + DEFAULT_MESSAGE_BUFFER_SIZE);
00343 }
00344
00345
00346 if (bufferHasMyEndianness) {
00347 memcpy(buffer+writeOffset, data, 8*n);
00348 writeOffset += 8*n;
00349 } else {
00350 for (i=0; i<n; ++i) {
00351 a_deux32.ui64 = data[i];
00352 an_uint32 = CERTI_UINT32_SWAP_BYTES(a_deux32.ui32[1]);
00353 memcpy(buffer+writeOffset,&an_uint32,4);
00354 writeOffset += 4;
00355 an_uint32 = CERTI_UINT32_SWAP_BYTES(a_deux32.ui32[0]);
00356 memcpy(buffer+writeOffset,&an_uint32,4);
00357 writeOffset += 4;
00358 }
00359 }
00360 return (writeOffset-8*n);
00361 }
00362
00363 int32_t MessageBuffer::read_uint64s(uint64_t* data, uint32_t n) {
00364 uint32_t i;
00365 union deux32 {
00366 uint32_t ui32[2];
00367 uint64_t ui64;
00368 } a_deux32;
00369 uint32_t an_uint32;
00370 D.Out(pdTrace,"read_uint64s(%p , %d)",data,n);
00371
00372 if (8*n + readOffset > writeOffset) {
00373 std::stringstream smsg;
00374 smsg << "read_uint64s::invalid read of size <" << 4*n
00375 << "> inside a buffer of readable size <"
00376 << (int32_t)writeOffset-readOffset << "> (writeOffset="
00377 <<writeOffset << ",readOffset="<<readOffset <<").";
00378 throw RTIinternalError(smsg.str().c_str());
00379 }
00380
00381
00382 if (bufferHasMyEndianness) {
00383 memcpy(data, buffer+readOffset, 8*n);
00384 readOffset += 8*n;
00385 } else {
00386 for (i=0; i<n; ++i) {
00387 memcpy(&an_uint32,buffer+readOffset,4);
00388 a_deux32.ui32[1] = CERTI_UINT32_SWAP_BYTES(an_uint32);
00389 readOffset += 4;
00390
00391 memcpy(&an_uint32,buffer+readOffset,4);
00392 a_deux32.ui32[0] = CERTI_UINT32_SWAP_BYTES(an_uint32);
00393 readOffset += 4;
00394
00395 data[i] = a_deux32.ui64;
00396 }
00397 }
00398 return (readOffset-8*n);
00399 }
00400
00401 int32_t MessageBuffer::write_floats(const float* data, uint32_t n) {
00402 const uint32_t* data32;
00403 D.Out(pdTrace,"write_floats(%p = [%f ...], %d)",data,n>0?data[0]:0,n);
00404 data32 = reinterpret_cast<const uint32_t*>(data);
00405 return write_uint32s(data32,n);
00406 }
00407
00408 int32_t MessageBuffer::read_floats(float* data, uint32_t n) {
00409 uint32_t* data32;
00410 D.Out(pdTrace,"read_floats(%p , %d)",data,n);
00411 data32 = reinterpret_cast<uint32_t*>(data);
00412 return read_uint32s(data32,n);
00413 }
00414
00415 int32_t MessageBuffer::write_doubles(const double* data, uint32_t n) {
00416 const uint64_t* data64;
00417 D.Out(pdTrace,"write_doubles(%p = [%f ...], %d)",data,n>0?data[0]:0,n);
00418 data64 = reinterpret_cast<const uint64_t*>(data);
00419 return write_uint64s(data64,n);
00420 }
00421
00422 int32_t MessageBuffer::read_doubles(double* data, uint32_t n) {
00423 uint64_t* data64;
00424 D.Out(pdTrace,"read_doubles(%p , %d)",data,n);
00425 data64 = reinterpret_cast<uint64_t*>(data);
00426 return read_uint64s(data64,n);
00427 }
00428
00429 int32_t
00430 MessageBuffer::write_string(const std::string& str) {
00431 write_int32(str.length());
00432 return write_chars(str.data(),str.length());
00433 }
00434
00435 std::string
00436 MessageBuffer::read_string() {
00437 std::string retval;
00438 int32_t len;
00439 char* buf;
00440
00441 read_int32(&len);
00442 buf = new char[len];
00443 read_chars(buf,len);
00444 retval.assign(buf,len);
00445 delete[] buf;
00446 return retval;
00447 }
00448
00449 void MessageBuffer::updateReservedBytes() {
00450
00451 if ((HostIsBigEndian() && bufferHasMyEndianness) ||
00452 (HostIsLittleEndian() && !bufferHasMyEndianness)) {
00453 buffer[0] = 0x01;
00454 } else {
00455 buffer[0] = 0x00;
00456 }
00457
00458 setSizeInReservedBytes(size());
00459 }
00460
00461 void*
00462 MessageBuffer::operator ()(uint32_t offset) {
00463 return buffer+offset;
00464 }
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475 }
00476