Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

OSGBinaryDataHandler.cpp

Go to the documentation of this file.
00001 /*---------------------------------------------------------------------------*\
00002  *                                OpenSG                                     *
00003  *                                                                           *
00004  *                                                                           *
00005  *             Copyright (C) 2000-2002 by the OpenSG Forum                   *
00006  *                                                                           *
00007  *                            www.opensg.org                                 *
00008  *                                                                           *
00009  *   contact: dirk@opensg.org, gerrit.voss@vossg.org, jbehr@zgdv.de          *
00010  *                                                                           *
00011 \*---------------------------------------------------------------------------*/
00012 /*---------------------------------------------------------------------------*\
00013  *                                License                                    *
00014  *                                                                           *
00015  * This library is free software; you can redistribute it and/or modify it   *
00016  * under the terms of the GNU Library General Public License as published    *
00017  * by the Free Software Foundation, version 2.                               *
00018  *                                                                           *
00019  * This library is distributed in the hope that it will be useful, but       *
00020  * WITHOUT ANY WARRANTY; without even the implied warranty of                *
00021  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU         *
00022  * Library General Public License for more details.                          *
00023  *                                                                           *
00024  * You should have received a copy of the GNU Library General Public         *
00025  * License along with this library; if not, write to the Free Software       *
00026  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.                 *
00027  *                                                                           *
00028 \*---------------------------------------------------------------------------*/
00029 /*---------------------------------------------------------------------------*\
00030  *                                Changes                                    *
00031  *                                                                           *
00032  *                                                                           *
00033  *                                                                           *
00034  *                                                                           *
00035  *                                                                           *
00036  *                                                                           *
00037 \*---------------------------------------------------------------------------*/
00038 
00039 //---------------------------------------------------------------------------
00040 //  Includes
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 /*                            Constructors                                 */
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 /*                             Destructor                                  */
00074 
00075 BinaryDataHandler::~BinaryDataHandler(void)
00076 {
00077     freeMem();
00078 }
00079 
00080 /*-------------------------------------------------------------------------*/
00081 /*                                Put                                      */
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             // we have to write a tag, to indicate the membership
00098             // of this zero copy block to the current data block
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             // skip to next buffer if current buffer is full
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 /*                                Put                                      */
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             // we have to read the tag, to force reading of data blocks
00172             // if the first data field was zero copied
00173             get(&tag, sizeof(tag));
00174         }
00175 
00176         // read direct into destination
00177         read(data, size);
00178     }
00179     else
00180     {
00181         UInt32 copySize;
00182 
00183         while(size != 0)
00184         {
00185             // read new data if nothing left
00186             if(_currentReadBuffer == readBufEnd())
00187             {
00188                 pullBuffer();
00189             }
00190 
00191             // num bytes to copy
00192             copySize = osgMin((_currentReadBuffer->getDataSize() -
00193                                _currentReadBufferPos),
00194                               size);
00195 
00196             // no data in buffer ?
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             // skip to next buffer if current buffer is full
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 /*                              Flush                                      */
00236 
00238 
00239 void BinaryDataHandler::flush(void)
00240 {
00241     if(_currentWriteBuffer != writeBufEnd())
00242     {
00243         // mark rest of buffer as empty
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 /*                             NetworkOrder mode                            */
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 /*                               Read                                      */
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 /*                               Write                                     */
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 /*                               Read                                      */
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     // read buffer size
00353     read((MemoryHandle) &nsize, sizeof(UInt32));
00354     size = osgntohl(nsize);
00355 
00356     // read rest of buffer
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 /*                               Write                                     */
00398 
00402 void BinaryDataHandler::writeBuffer(void)
00403 {
00404     BuffersT::iterator i;
00405     UInt32             size = 0;
00406     UInt32             nsize;
00407 
00408     // calculate blocksize
00409     for(i = writeBufBegin(); i != writeBufEnd(); ++i)
00410     {
00411         size += i->getDataSize();
00412     }
00413 
00414     // write buffer size
00415     nsize = osghtonl(size);
00416 
00417     write((MemoryHandle) &nsize, sizeof(UInt32));
00418 
00419     // write buffers
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 /*                               Handle Buffer                             */
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     // direct write zero copy buffers
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     // remove buffers given with getAndFree
00471     freeMem();
00472 
00473     // reset buffer pos
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 /*                              cvs id's                                   */
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 

Generated on Thu Aug 25 04:01:18 2005 for OpenSG by  doxygen 1.4.3