TBuffer.cxx

Go to the documentation of this file.
00001 // @(#)root/base:$Id: TBuffer.cxx 36594 2010-11-11 13:51:16Z pcanal $
00002 // Author: Fons Rademakers   04/05/96
00003 
00004 /*************************************************************************
00005  * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
00006  * All rights reserved.                                                  *
00007  *                                                                       *
00008  * For the licensing terms see $ROOTSYS/LICENSE.                         *
00009  * For the list of contributors see $ROOTSYS/README/CREDITS.             *
00010  *************************************************************************/
00011 
00012 //////////////////////////////////////////////////////////////////////////
00013 //                                                                      //
00014 // TBuffer                                                              //
00015 //                                                                      //
00016 // Buffer base class used for serializing objects.                      //
00017 //                                                                      //
00018 //////////////////////////////////////////////////////////////////////////
00019 
00020 #include "TBuffer.h"
00021 #include "TClass.h"
00022 #include "TProcessID.h"
00023 
00024 const Int_t  kExtraSpace        = 8;   // extra space at end of buffer (used for free block count)
00025 
00026 ClassImp(TBuffer)
00027 
00028 //______________________________________________________________________________
00029 static char *R__NoReAllocChar(char *, size_t, size_t)
00030 {
00031    // The user has provided memory than we don't own, thus we can not extent it
00032    // either.
00033    return 0;
00034 }
00035 
00036 //______________________________________________________________________________
00037 static inline ULong_t Void_Hash(const void *ptr)
00038 {
00039    // Return hash value for this object.
00040 
00041    return TString::Hash(&ptr, sizeof(void*));
00042 }
00043 
00044 
00045 //______________________________________________________________________________
00046 TBuffer::TBuffer(EMode mode)
00047 {
00048    // Create an I/O buffer object. Mode should be either TBuffer::kRead or
00049    // TBuffer::kWrite. By default the I/O buffer has a size of
00050    // TBuffer::kInitialSize (1024) bytes.
00051 
00052    fBufSize      = kInitialSize;
00053    fMode         = mode;
00054    fVersion      = 0;
00055    fParent       = 0;
00056 
00057    SetBit(kIsOwner);
00058 
00059    fBuffer = new char[fBufSize+kExtraSpace];
00060 
00061    fBufCur = fBuffer;
00062    fBufMax = fBuffer + fBufSize;
00063    
00064    SetReAllocFunc( 0 );
00065 }
00066 
00067 //______________________________________________________________________________
00068 TBuffer::TBuffer(EMode mode, Int_t bufsiz)
00069 {
00070    // Create an I/O buffer object. Mode should be either TBuffer::kRead or
00071    // TBuffer::kWrite.
00072 
00073    if (bufsiz < kMinimalSize) bufsiz = kMinimalSize;
00074    fBufSize  = bufsiz;
00075    fMode     = mode;
00076    fVersion  = 0;
00077    fParent   = 0;
00078 
00079    SetBit(kIsOwner);
00080 
00081    fBuffer = new char[fBufSize+kExtraSpace];
00082 
00083    fBufCur = fBuffer;
00084    fBufMax = fBuffer + fBufSize;
00085 
00086    SetReAllocFunc( 0 );
00087 }
00088 
00089 //______________________________________________________________________________
00090 TBuffer::TBuffer(EMode mode, Int_t bufsiz, void *buf, Bool_t adopt, ReAllocCharFun_t reallocfunc)
00091 {
00092    // Create an I/O buffer object. Mode should be either TBuffer::kRead or
00093    // TBuffer::kWrite. By default the I/O buffer has a size of
00094    // TBuffer::kInitialSize (1024) bytes. An external buffer can be passed
00095    // to TBuffer via the buf argument. By default this buffer will be adopted
00096    // unless adopt is false.
00097    // If the new buffer is _not_ adopted and no memory allocation routine
00098    // is provided, a Fatal error will be issued if the Buffer attempts to
00099    // expand.
00100    
00101    fBufSize  = bufsiz;
00102    fMode     = mode;
00103    fVersion  = 0;
00104    fParent   = 0;
00105 
00106    SetBit(kIsOwner);
00107 
00108    if (buf) {
00109       fBuffer = (char *)buf;
00110       if ( (fMode&kWrite)!=0 ) {
00111          fBufSize -= kExtraSpace;
00112       }
00113       if (!adopt) ResetBit(kIsOwner);
00114    } else {
00115       if (fBufSize < kMinimalSize) {
00116          fBufSize = kMinimalSize;
00117       }
00118       fBuffer = new char[fBufSize+kExtraSpace];
00119    }
00120    fBufCur = fBuffer;
00121    fBufMax = fBuffer + fBufSize;
00122    
00123    SetReAllocFunc( reallocfunc );
00124 
00125    if (buf && ( (fMode&kWrite)!=0 ) && fBufSize < 0) {
00126       Expand( kMinimalSize );
00127    }
00128 }
00129 
00130 //______________________________________________________________________________
00131 TBuffer::~TBuffer()
00132 {
00133    // Delete an I/O buffer object.
00134 
00135    if (TestBit(kIsOwner)) {
00136       //printf("Deleting fBuffer=%lx\n", fBuffer);
00137       delete [] fBuffer;
00138    }
00139    fBuffer = 0;
00140    fParent = 0;
00141 }
00142 
00143 //______________________________________________________________________________
00144 void TBuffer::SetBuffer(void *buf, UInt_t newsiz, Bool_t adopt, ReAllocCharFun_t reallocfunc)
00145 {
00146    // Sets a new buffer in an existing TBuffer object. If newsiz=0 then the
00147    // new buffer is expected to have the same size as the previous buffer.
00148    // The current buffer position is reset to the start of the buffer.
00149    // If the TBuffer owned the previous buffer, it will be deleted prior
00150    // to accepting the new buffer. By default the new buffer will be
00151    // adopted unless adopt is false.
00152    // If the new buffer is _not_ adopted and no memory allocation routine
00153    // is provided, a Fatal error will be issued if the Buffer attempts to
00154    // expand.
00155 
00156    if (fBuffer && TestBit(kIsOwner))
00157       delete [] fBuffer;
00158 
00159    if (adopt)
00160       SetBit(kIsOwner);
00161    else
00162       ResetBit(kIsOwner);
00163 
00164    fBuffer = (char *)buf;
00165    fBufCur = fBuffer;
00166    if (newsiz > 0) {
00167       if ( (fMode&kWrite)!=0 ) {
00168          fBufSize = newsiz - kExtraSpace;
00169       } else {
00170          fBufSize = newsiz;
00171       }         
00172    }
00173    fBufMax = fBuffer + fBufSize;
00174    
00175    SetReAllocFunc( reallocfunc );
00176 
00177    if (buf && ( (fMode&kWrite)!=0 ) && fBufSize < 0) {
00178       Expand( kMinimalSize );
00179    }
00180 }
00181 
00182 //______________________________________________________________________________
00183 void TBuffer::Expand(Int_t newsize)
00184 {
00185    // Expand the I/O buffer to newsize bytes.
00186 
00187    Int_t l  = Length();
00188    if ( (fMode&kWrite)!=0 ) {
00189       fBuffer  = fReAllocFunc(fBuffer, newsize+kExtraSpace,
00190                               fBufSize+kExtraSpace);
00191    } else {
00192       fBuffer  = fReAllocFunc(fBuffer, newsize,
00193                               fBufSize);
00194    }
00195    if (fBuffer == 0) {
00196       if (fReAllocFunc == TStorage::ReAllocChar) {
00197          Fatal("Expand","Failed to expand the data buffer using TStorage::ReAllocChar.");
00198       } if (fReAllocFunc == R__NoReAllocChar) {
00199          Fatal("Expand","Failed to expand the data buffer because TBuffer does not own it and no custom memory reallocator was provided.");         
00200       } else {
00201          Fatal("Expand","Failed to expand the data buffer using custom memory reallocator 0x%lx.", (Long_t)fReAllocFunc);
00202       }
00203    }
00204    fBufSize = newsize;
00205    fBufCur  = fBuffer + l;
00206    fBufMax  = fBuffer + fBufSize;
00207 }
00208 
00209 //______________________________________________________________________________
00210 TObject *TBuffer::GetParent() const
00211 {
00212    // Return pointer to parent of this buffer.
00213 
00214    return fParent;
00215 }
00216 
00217 //______________________________________________________________________________
00218 void TBuffer::SetParent(TObject *parent)
00219 {
00220    // Set parent owning this buffer.
00221 
00222    fParent = parent;
00223 }
00224 //______________________________________________________________________________
00225 ReAllocCharFun_t TBuffer::GetReAllocFunc() const
00226 {
00227    // Return the reallocation method currently used.
00228    return fReAllocFunc;
00229 }
00230 
00231 //______________________________________________________________________________
00232 void  TBuffer::SetReAllocFunc(ReAllocCharFun_t reallocfunc )
00233 {
00234    // Set which memory reallocation method to use.  If reallocafunc is null,
00235    // reset it to the defaul value (TStorage::ReAlloc)
00236    
00237    if (reallocfunc) {
00238       fReAllocFunc = reallocfunc;
00239    } else {
00240       if (TestBit(kIsOwner)) {
00241          fReAllocFunc = TStorage::ReAllocChar;
00242       } else {
00243          fReAllocFunc = R__NoReAllocChar;
00244       }
00245    }
00246 }
00247 
00248 //______________________________________________________________________________
00249 void TBuffer::SetReadMode()
00250 {
00251    // Set buffer in read mode.
00252 
00253    fMode = kRead;
00254 }
00255 
00256 //______________________________________________________________________________
00257 void TBuffer::SetWriteMode()
00258 {
00259    // Set buffer in write mode.
00260 
00261    fMode = kWrite;
00262 }
00263 
00264 //______________________________________________________________________________
00265 TClass *TBuffer::GetClass(const type_info &typeinfo)
00266 {
00267    // Forward to TROOT::GetClass().
00268 
00269    return TClass::GetClass(typeinfo);
00270 }
00271 
00272 //______________________________________________________________________________
00273 TClass *TBuffer::GetClass(const char *className)
00274 {
00275    // Forward to TROOT::GetClass().
00276 
00277    return TClass::GetClass(className);
00278 }
00279 
00280 //______________________________________________________________________________
00281 TProcessID *TBuffer::ReadProcessID(UShort_t pidf)
00282 {
00283    // Return the current PRocessID.
00284 
00285    if (!pidf) return TProcessID::GetPID(); //may happen when cloning an object
00286    return 0;
00287 }
00288 
00289 //______________________________________________________________________________
00290 UShort_t TBuffer::WriteProcessID(TProcessID *)
00291 {
00292    // Always return 0 (current processID).
00293 
00294    return 0;
00295 }
00296 
00297 //______________________________________________________________________________
00298 void TBuffer::PushDataCache(TVirtualArray *obj)
00299 {
00300    // Push a new data cache area onto the list of area to be used for
00301    // temporarily store 'missing' data members.
00302    
00303    fCacheStack.push_back(obj);
00304 }
00305 
00306 //______________________________________________________________________________
00307 TVirtualArray *TBuffer::PeekDataCache() const
00308 {
00309    // Return the 'current' data cache area from the list of area to be used for
00310    // temporarily store 'missing' data members.
00311    
00312    if (fCacheStack.empty()) return 0;
00313    return fCacheStack.back();
00314 }
00315 
00316 //______________________________________________________________________________
00317 TVirtualArray *TBuffer::PopDataCache()
00318 {
00319    // Pop and Return the 'current' data cache area from the list of area to be used for
00320    // temporarily store 'missing' data members.
00321    
00322    TVirtualArray *val = PeekDataCache();
00323    fCacheStack.pop_back();
00324    return val;
00325 }
00326 

Generated on Tue Jul 5 14:11:19 2011 for ROOT_528-00b_version by  doxygen 1.5.1