00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043 #include <stdlib.h>
00044 #include <stdio.h>
00045
00046 #include "OSGConfig.h"
00047 #include "OSGLog.h"
00048 #include "OSGBinaryDataHandler.h"
00049 #include "OSGBaseFunctions.h"
00050
00051 OSG_USING_NAMESPACE
00052
00053
00054
00055
00056
00057 BinaryDataHandler::BinaryDataHandler(UInt32 zeroCopyThreshold,
00058 bool networkOrder ) :
00059 _readBuffers ( ),
00060 _writeBuffers ( ),
00061 _zeroCopyBuffers ( ),
00062 _zeroCopyThreshold (zeroCopyThreshold),
00063 _freeMem ( ),
00064 _currentReadBuffer ( ),
00065 _currentReadBufferPos (0 ),
00066 _currentWriteBuffer ( ),
00067 _currentWriteBufferPos(0 ),
00068 _networkOrder (networkOrder )
00069 {
00070 }
00071
00072
00073
00074
00075 BinaryDataHandler::~BinaryDataHandler(void)
00076 {
00077 freeMem();
00078 }
00079
00080
00081
00082
00083 void BinaryDataHandler::put(void const *src, UInt32 size)
00084 {
00085 UInt8 const *data = static_cast<UInt8 const *>(src);
00086
00087 if(_zeroCopyThreshold && size >= _zeroCopyThreshold)
00088 {
00089 if(_zeroCopyThreshold == 1)
00090 {
00091 write(const_cast<MemoryHandle>(data), size);
00092 }
00093 else
00094 {
00095 UInt8 tag = 1;
00096
00097
00098
00099 put(&tag, sizeof(tag));
00100
00101 _zeroCopyBuffers.push_back(
00102 MemoryBlock(const_cast<MemoryHandle>(data), size, size));
00103 }
00104 }
00105 else
00106 {
00107 UInt32 copySize;
00108
00109 while(size != 0)
00110 {
00111 if(_currentWriteBuffer == writeBufEnd())
00112 {
00113 pushBuffer();
00114 }
00115
00116 copySize = osgMin((_currentWriteBuffer->getSize() -
00117 _currentWriteBufferPos),
00118 size);
00119
00120 memcpy(_currentWriteBuffer->getMem() + _currentWriteBufferPos,
00121 data,
00122 copySize);
00123
00124 size -= copySize;
00125 _currentWriteBufferPos += copySize;
00126 data += copySize;
00127
00128
00129 if(_currentWriteBufferPos == _currentWriteBuffer->getSize())
00130 {
00131 _currentWriteBuffer->setDataSize(_currentWriteBufferPos);
00132 _currentWriteBuffer++;
00133 _currentWriteBufferPos = 0;
00134 }
00135 }
00136 }
00137 }
00138
00144 void BinaryDataHandler::putAndFree(MemoryHandle src, UInt32 size)
00145 {
00146 put(src, size);
00147
00148 if(_zeroCopyThreshold && size > _zeroCopyThreshold)
00149 {
00150 _freeMem.push_back(src);
00151 }
00152 else
00153 {
00154 delete [] src;
00155 }
00156 }
00157
00158
00159
00160
00161 void BinaryDataHandler::get(void *dst, UInt32 size)
00162 {
00163 MemoryHandle data = static_cast<MemoryHandle>(dst);
00164
00165 if(_zeroCopyThreshold && size >= _zeroCopyThreshold)
00166 {
00167 if(_zeroCopyThreshold > 1)
00168 {
00169 UInt8 tag;
00170
00171
00172
00173 get(&tag, sizeof(tag));
00174 }
00175
00176
00177 read(data, size);
00178 }
00179 else
00180 {
00181 UInt32 copySize;
00182
00183 while(size != 0)
00184 {
00185
00186 if(_currentReadBuffer == readBufEnd())
00187 {
00188 pullBuffer();
00189 }
00190
00191
00192 copySize = osgMin((_currentReadBuffer->getDataSize() -
00193 _currentReadBufferPos),
00194 size);
00195
00196
00197 if(copySize != 0)
00198 {
00199 memcpy( data,
00200 _currentReadBuffer->getMem() + _currentReadBufferPos,
00201 copySize);
00202
00203 size -= copySize;
00204 _currentReadBufferPos += copySize;
00205 data += copySize;
00206 }
00207
00208
00209 if(_currentReadBufferPos == _currentReadBuffer->getDataSize())
00210 {
00211 _currentReadBuffer++;
00212 _currentReadBufferPos = 0;
00213 }
00214 }
00215 }
00216 }
00217
00227 void BinaryDataHandler::getAndAlloc(MemoryHandle &src, UInt32 size)
00228 {
00229 src = new UInt8[size];
00230
00231 get(src, size);
00232 }
00233
00234
00235
00236
00238
00239 void BinaryDataHandler::flush(void)
00240 {
00241 if(_currentWriteBuffer != writeBufEnd())
00242 {
00243
00244 _currentWriteBuffer->setDataSize(_currentWriteBufferPos);
00245 _currentWriteBuffer++;
00246
00247 while(_currentWriteBuffer != writeBufEnd())
00248 {
00249 _currentWriteBuffer->setDataSize(0);
00250 _currentWriteBuffer++;
00251 }
00252 }
00253
00254 pushBuffer();
00255 }
00256
00260 void BinaryDataHandler::forceCopy(void)
00261 {
00262 _zeroCopyThreshold = 0;
00263 }
00264
00268 void BinaryDataHandler::forceDirectIO(void)
00269 {
00270 _zeroCopyThreshold = 1;
00271 }
00272
00273
00274
00275
00276
00277 void BinaryDataHandler::setNetworkOrder(bool value)
00278 {
00279 _networkOrder = value;
00280 }
00281
00282 bool BinaryDataHandler::getNetworkOrder(void)
00283 {
00284 return _networkOrder;
00285 }
00286
00287
00288
00289
00290 void BinaryDataHandler::readBufAdd(MemoryHandle mem,
00291 UInt32 size,
00292 UInt32 dataSize)
00293 {
00294 MemoryBlock memBlock(mem, size, dataSize);
00295
00296 _readBuffers.push_back(memBlock);
00297
00298 _currentReadBuffer = readBufEnd();
00299 }
00300
00301 void BinaryDataHandler::readBufClear(void)
00302 {
00303 _readBuffers.clear();
00304
00305 _currentReadBuffer=readBufEnd();
00306 }
00307
00308
00309
00310
00311 void BinaryDataHandler::writeBufAdd(MemoryHandle mem,
00312 UInt32 size,
00313 UInt32 dataSize)
00314 {
00315 MemoryBlock memBlock(mem, size, dataSize);
00316
00317 _writeBuffers.push_back(memBlock);
00318
00319 _currentWriteBuffer = writeBufBegin();
00320 _currentWriteBufferPos = 0;
00321 }
00322
00323 void BinaryDataHandler::writeBufClear(void)
00324 {
00325 _writeBuffers.clear();
00326
00327 _currentWriteBuffer = writeBufEnd();
00328 }
00329
00330
00331
00332
00333
00342 #ifdef OSG_WIN32_ICL
00343 #pragma warning (disable : 383)
00344 #endif
00345
00346 void BinaryDataHandler::readBuffer(void)
00347 {
00348 BuffersT::iterator i;
00349 UInt32 size,nsize;
00350 UInt32 readSize;
00351
00352
00353 read((MemoryHandle) &nsize, sizeof(UInt32));
00354 size = osgntohl(nsize);
00355
00356
00357 for(i = readBufBegin(); size != 0; ++i)
00358 {
00359 if(i == readBufEnd())
00360 {
00361 SFATAL << "Read buffer is to small. " << size
00362 << "bytes missing" << std::endl;
00363
00364 throw ReadError("Read buffer to small for whole block");
00365 }
00366
00367 readSize = osgMin(size, i->getSize());
00368
00369 read(i->getMem(), readSize);
00370
00371 i->setDataSize(readSize);
00372
00373 size -= readSize;
00374 }
00375
00376 for(; i != readBufEnd(); ++i)
00377 {
00378 i->setDataSize(0);
00379 }
00380 }
00381
00382 #ifdef OSG_WIN32_ICL
00383 #pragma warning (default : 383)
00384 #endif
00385
00389 void BinaryDataHandler::read(MemoryHandle OSG_CHECK_ARG(src ),
00390 UInt32 OSG_CHECK_ARG(size))
00391 {
00392 SWARNING << "BinaryDataHandler::read(MemoryHandle src,int size) called"
00393 << std::endl;
00394 }
00395
00396
00397
00398
00402 void BinaryDataHandler::writeBuffer(void)
00403 {
00404 BuffersT::iterator i;
00405 UInt32 size = 0;
00406 UInt32 nsize;
00407
00408
00409 for(i = writeBufBegin(); i != writeBufEnd(); ++i)
00410 {
00411 size += i->getDataSize();
00412 }
00413
00414
00415 nsize = osghtonl(size);
00416
00417 write((MemoryHandle) &nsize, sizeof(UInt32));
00418
00419
00420 for(i = writeBufBegin(); i != writeBufEnd(); ++i)
00421 {
00422 if(i->getDataSize() != 0)
00423 {
00424 write(i->getMem(), i->getDataSize());
00425 }
00426 }
00427 }
00428
00431 bool BinaryDataHandler::isReadBufferEmpty(void)
00432 {
00433 if(_zeroCopyThreshold == 1)
00434 return true;
00435 if(_currentReadBuffer == readBufEnd())
00436 return true;
00437 return false;
00438 }
00439
00440
00441
00442
00446 void BinaryDataHandler::write(MemoryHandle OSG_CHECK_ARG(src ),
00447 UInt32 OSG_CHECK_ARG(size))
00448 {
00449 SWARNING << "BinaryDataHandler::write(MemoryHandle mem,int size) called"
00450 << std::endl;
00451 }
00452
00453
00454 void BinaryDataHandler::pushBuffer()
00455 {
00456 BuffersT::iterator i;
00457
00458 writeBuffer();
00459
00460
00461 for( i = _zeroCopyBuffers.begin();
00462 i != _zeroCopyBuffers.end ();
00463 ++i)
00464 {
00465 write(i->getMem(), i->getDataSize());
00466 }
00467
00468 _zeroCopyBuffers.clear();
00469
00470
00471 freeMem();
00472
00473
00474 _currentWriteBuffer = writeBufBegin();
00475 _currentWriteBufferPos = 0;
00476
00477 _currentWriteBuffer->setDataSize(0);
00478 }
00479
00480 void BinaryDataHandler::pullBuffer()
00481 {
00482 readBuffer();
00483
00484 _currentReadBuffer = readBufBegin();
00485 _currentReadBufferPos = 0;
00486 }
00487
00488 void BinaryDataHandler::freeMem()
00489 {
00490 for(FreeMemT::iterator i= _freeMem.begin(); i!= _freeMem.end(); ++i)
00491 {
00492 delete [] *i;
00493 }
00494
00495 _freeMem.clear();
00496 }
00497
00498
00499
00500
00501
00502 #ifdef __sgi
00503 #pragma set woff 1174
00504 #endif
00505
00506 #ifdef OSG_LINUX_ICC
00507 #pragma warning( disable : 177 )
00508 #endif
00509
00510 namespace
00511 {
00512 static Char8 cvsid_cpp[] = "@(#)$Id: $";
00513 static Char8 cvsid_hpp[] = OSGBINARYDATAHANDLER_HEADER_CVSID;
00514 static Char8 cvsid_inl[] = OSGBINARYDATAHANDLER_INLINE_CVSID;
00515 }
00516
00517
00518
00519