Logo ROOT   6.08/07
Reference Guide
TBuffer.cxx
Go to the documentation of this file.
1 // @(#)root/base:$Id: 6da0b5b613bbcfaa3a5cd4074e7b2be2448dfb31 $
2 // Author: Fons Rademakers 04/05/96
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. *
6  * All rights reserved. *
7  * *
8  * For the licensing terms see $ROOTSYS/LICENSE. *
9  * For the list of contributors see $ROOTSYS/README/CREDITS. *
10  *************************************************************************/
11 
12 /** \class TBuffer
13 \ingroup Base
14 
15 Buffer base class used for serializing objects.
16 */
17 
18 #include "TBuffer.h"
19 #include "TClass.h"
20 #include "TProcessID.h"
21 
22 const Int_t kExtraSpace = 8; // extra space at end of buffer (used for free block count)
23 
25 
26 ////////////////////////////////////////////////////////////////////////////////
27 /// The user has provided memory than we don't own, thus we can not extent it
28 /// either.
29 
30 static char *R__NoReAllocChar(char *, size_t, size_t)
31 {
32  return 0;
33 }
34 
35 ////////////////////////////////////////////////////////////////////////////////
36 /// Create an I/O buffer object. Mode should be either TBuffer::kRead or
37 /// TBuffer::kWrite. By default the I/O buffer has a size of
38 /// TBuffer::kInitialSize (1024) bytes.
39 
41 {
43  fMode = mode;
44  fVersion = 0;
45  fParent = 0;
46 
48 
49  fBuffer = new char[fBufSize+kExtraSpace];
50 
51  fBufCur = fBuffer;
53 
54  SetReAllocFunc( 0 );
55 }
56 
57 ////////////////////////////////////////////////////////////////////////////////
58 /// Create an I/O buffer object. Mode should be either TBuffer::kRead or
59 /// TBuffer::kWrite.
60 
62 {
63  if (bufsiz < kMinimalSize) bufsiz = kMinimalSize;
64  fBufSize = bufsiz;
65  fMode = mode;
66  fVersion = 0;
67  fParent = 0;
68 
70 
71  fBuffer = new char[fBufSize+kExtraSpace];
72 
73  fBufCur = fBuffer;
75 
76  SetReAllocFunc( 0 );
77 }
78 
79 ////////////////////////////////////////////////////////////////////////////////
80 /// Create an I/O buffer object. Mode should be either TBuffer::kRead or
81 /// TBuffer::kWrite. By default the I/O buffer has a size of
82 /// TBuffer::kInitialSize (1024) bytes. An external buffer can be passed
83 /// to TBuffer via the buf argument. By default this buffer will be adopted
84 /// unless adopt is false.
85 ///
86 /// If the new buffer is _not_ adopted and no memory allocation routine
87 /// is provided, a Fatal error will be issued if the Buffer attempts to
88 /// expand.
89 
90 TBuffer::TBuffer(EMode mode, Int_t bufsiz, void *buf, Bool_t adopt, ReAllocCharFun_t reallocfunc)
91 {
92  fBufSize = bufsiz;
93  fMode = mode;
94  fVersion = 0;
95  fParent = 0;
96 
98 
99  if (buf) {
100  fBuffer = (char *)buf;
101  if ( (fMode&kWrite)!=0 ) {
103  }
104  if (!adopt) ResetBit(kIsOwner);
105  } else {
106  if (fBufSize < kMinimalSize) {
108  }
109  fBuffer = new char[fBufSize+kExtraSpace];
110  }
111  fBufCur = fBuffer;
113 
114  SetReAllocFunc( reallocfunc );
115 
116  if (buf && ( (fMode&kWrite)!=0 ) && fBufSize < 0) {
117  Expand( kMinimalSize );
118  }
119 }
120 
121 ////////////////////////////////////////////////////////////////////////////////
122 /// Delete an I/O buffer object.
123 
125 {
126  if (TestBit(kIsOwner)) {
127  //printf("Deleting fBuffer=%lx\n", fBuffer);
128  delete [] fBuffer;
129  }
130  fBuffer = 0;
131  fParent = 0;
132 }
133 
134 ////////////////////////////////////////////////////////////////////////////////
135 /// Automatically calculate a new size and expand the buffer to fit at least size_needed.
136 /// The goals is to minimize the number of memory allocation and the memory allocation
137 /// which avoiding too much memory wastage.
138 ///
139 /// If the size_needed is larger than the current size, the policy
140 /// is to expand to double the current size or the size_needed which ever is largest.
141 
142 void TBuffer::AutoExpand(Int_t size_needed)
143 {
144  if (size_needed > fBufSize) {
145  if (size_needed > 2*fBufSize) {
146  Expand(size_needed);
147  } else {
148  Expand(2*fBufSize);
149  }
150  }
151 }
152 
153 ////////////////////////////////////////////////////////////////////////////////
154 /// Sets a new buffer in an existing TBuffer object. If newsiz=0 then the
155 /// new buffer is expected to have the same size as the previous buffer.
156 /// The current buffer position is reset to the start of the buffer.
157 /// If the TBuffer owned the previous buffer, it will be deleted prior
158 /// to accepting the new buffer. By default the new buffer will be
159 /// adopted unless adopt is false.
160 ///
161 /// If the new buffer is _not_ adopted and no memory allocation routine
162 /// is provided, a Fatal error will be issued if the Buffer attempts to
163 /// expand.
164 
165 void TBuffer::SetBuffer(void *buf, UInt_t newsiz, Bool_t adopt, ReAllocCharFun_t reallocfunc)
166 {
167  if (fBuffer && TestBit(kIsOwner))
168  delete [] fBuffer;
169 
170  if (adopt)
171  SetBit(kIsOwner);
172  else
174 
175  fBuffer = (char *)buf;
176  fBufCur = fBuffer;
177  if (newsiz > 0) {
178  if ( (fMode&kWrite)!=0 ) {
179  fBufSize = newsiz - kExtraSpace;
180  } else {
181  fBufSize = newsiz;
182  }
183  }
185 
186  SetReAllocFunc( reallocfunc );
187 
188  if (buf && ( (fMode&kWrite)!=0 ) && fBufSize < 0) {
189  Expand( kMinimalSize );
190  }
191 }
192 
193 ////////////////////////////////////////////////////////////////////////////////
194 /// Expand (or shrink) the I/O buffer to newsize bytes.
195 /// If copy is true (the default), the existing content of the
196 /// buffer is preserved, otherwise the buffer is returned zero-ed out.
197 ///
198 /// In order to avoid losing data, if the current length is greater than
199 /// the requested size, we only shrink down to the current length.
200 
201 void TBuffer::Expand(Int_t newsize, Bool_t copy)
202 {
203  Int_t l = Length();
204  if ( (l > newsize) && copy ) {
205  newsize = l;
206  }
207  if ( (fMode&kWrite)!=0 ) {
209  copy ? fBufSize+kExtraSpace : 0);
210  } else {
211  fBuffer = fReAllocFunc(fBuffer, newsize,
212  copy ? fBufSize : 0);
213  }
214  if (fBuffer == 0) {
216  Fatal("Expand","Failed to expand the data buffer using TStorage::ReAllocChar.");
217  } else if (fReAllocFunc == R__NoReAllocChar) {
218  Fatal("Expand","Failed to expand the data buffer because TBuffer does not own it and no custom memory reallocator was provided.");
219  } else {
220  Fatal("Expand","Failed to expand the data buffer using custom memory reallocator 0x%lx.", (Long_t)fReAllocFunc);
221  }
222  }
223  fBufSize = newsize;
224  fBufCur = fBuffer + l;
226 }
227 
228 ////////////////////////////////////////////////////////////////////////////////
229 /// Return pointer to parent of this buffer.
230 
232 {
233  return fParent;
234 }
235 
236 ////////////////////////////////////////////////////////////////////////////////
237 /// Set parent owning this buffer.
238 
240 {
241  fParent = parent;
242 }
243 ////////////////////////////////////////////////////////////////////////////////
244 /// Return the reallocation method currently used.
245 
247 {
248  return fReAllocFunc;
249 }
250 
251 ////////////////////////////////////////////////////////////////////////////////
252 /// Set which memory reallocation method to use. If reallocafunc is null,
253 /// reset it to the default value (TStorage::ReAlloc)
254 
256 {
257  if (reallocfunc) {
258  fReAllocFunc = reallocfunc;
259  } else {
260  if (TestBit(kIsOwner)) {
262  } else {
264  }
265  }
266 }
267 
268 ////////////////////////////////////////////////////////////////////////////////
269 /// Set buffer in read mode.
270 
272 {
273  if ( (fMode&kWrite)!=0 ) {
274  // We had reserved space for the free block count,
275  // release it,
277  }
278  fMode = kRead;
279 }
280 
281 ////////////////////////////////////////////////////////////////////////////////
282 /// Set buffer in write mode.
283 
285 {
286  if ( (fMode&kWrite)==0 ) {
287  // We had not yet reserved space for the free block count,
288  // reserve it now.
290  }
291  fMode = kWrite;
292 }
293 
294 ////////////////////////////////////////////////////////////////////////////////
295 /// Forward to TROOT::GetClass().
296 
297 TClass *TBuffer::GetClass(const std::type_info &typeinfo)
298 {
299  return TClass::GetClass(typeinfo);
300 }
301 
302 ////////////////////////////////////////////////////////////////////////////////
303 /// Forward to TROOT::GetClass().
304 
305 TClass *TBuffer::GetClass(const char *className)
306 {
307  return TClass::GetClass(className);
308 }
309 
310 ////////////////////////////////////////////////////////////////////////////////
311 /// Return the current Process-ID.
312 
314 {
315  if (!pidf) return TProcessID::GetPID(); //may happen when cloning an object
316  return 0;
317 }
318 
319 ////////////////////////////////////////////////////////////////////////////////
320 /// Always return 0 (current processID).
321 
323 {
324  return 0;
325 }
326 
327 ////////////////////////////////////////////////////////////////////////////////
328 /// Push a new data cache area onto the list of area to be used for
329 /// temporarily store 'missing' data members.
330 
332 {
333  fCacheStack.push_back(obj);
334 }
335 
336 ////////////////////////////////////////////////////////////////////////////////
337 /// Return the 'current' data cache area from the list of area to be used for
338 /// temporarily store 'missing' data members.
339 
341 {
342  if (fCacheStack.empty()) return 0;
343  return fCacheStack.back();
344 }
345 
346 ////////////////////////////////////////////////////////////////////////////////
347 /// Pop and Return the 'current' data cache area from the list of area to be used for
348 /// temporarily store 'missing' data members.
349 
351 {
352  TVirtualArray *val = PeekDataCache();
353  fCacheStack.pop_back();
354  return val;
355 }
356 
static TProcessID * GetPID()
static: returns pointer to current TProcessID
Definition: TProcessID.cxx:313
char * fBuffer
Definition: TBuffer.h:50
virtual ~TBuffer()
Delete an I/O buffer object.
Definition: TBuffer.cxx:124
const Int_t kExtraSpace
Definition: TBuffer.cxx:22
TObject * GetParent() const
Return pointer to parent of this buffer.
Definition: TBuffer.cxx:231
Bool_t fMode
Definition: TBuffer.h:47
unsigned short UShort_t
Definition: RtypesCore.h:36
Bool_t TestBit(UInt_t f) const
Definition: TObject.h:157
ReAllocCharFun_t fReAllocFunc
Definition: TBuffer.h:54
char *(* ReAllocCharFun_t)(char *, size_t, size_t)
Definition: TStorage.h:30
Buffer base class used for serializing objects.
Definition: TBuffer.h:42
int Int_t
Definition: RtypesCore.h:41
bool Bool_t
Definition: RtypesCore.h:59
void SetParent(TObject *parent)
Set parent owning this buffer.
Definition: TBuffer.cxx:239
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
Definition: TObject.cxx:739
Int_t Length() const
Definition: TBuffer.h:96
virtual TProcessID * ReadProcessID(UShort_t pidf)=0
Return the current Process-ID.
Definition: TBuffer.cxx:313
static char * ReAllocChar(char *vp, size_t size, size_t oldsize)
Reallocate (i.e.
Definition: TStorage.cxx:260
static TClass * GetClass(const std::type_info &typeinfo)
Forward to TROOT::GetClass().
Definition: TBuffer.cxx:297
static char * R__NoReAllocChar(char *, size_t, size_t)
The user has provided memory than we don&#39;t own, thus we can not extent it either. ...
Definition: TBuffer.cxx:30
A TProcessID identifies a ROOT job in a unique way in time and space.
Definition: TProcessID.h:73
virtual UShort_t WriteProcessID(TProcessID *pid)=0
Always return 0 (current processID).
Definition: TBuffer.cxx:322
void Expand(Int_t newsize, Bool_t copy=kTRUE)
Expand (or shrink) the I/O buffer to newsize bytes.
Definition: TBuffer.cxx:201
CacheList_t fCacheStack
Realloc function to be used when extending the buffer.
Definition: TBuffer.h:55
Int_t fVersion
Definition: TBuffer.h:48
Wrapper around an object and giving indirect access to its content even if the object is not of a cla...
Definition: TVirtualArray.h:26
unsigned int UInt_t
Definition: RtypesCore.h:42
virtual TVirtualArray * PeekDataCache() const
Return the &#39;current&#39; data cache area from the list of area to be used for temporarily store &#39;missing&#39;...
Definition: TBuffer.cxx:340
void SetReadMode()
Set buffer in read mode.
Definition: TBuffer.cxx:271
TLine * l
Definition: textangle.C:4
The ROOT global object gROOT contains a list of all defined classes.
Definition: TClass.h:81
char * fBufCur
Definition: TBuffer.h:51
long Long_t
Definition: RtypesCore.h:50
TObject * fParent
Definition: TBuffer.h:53
virtual TVirtualArray * PopDataCache()
Pop and Return the &#39;current&#39; data cache area from the list of area to be used for temporarily store &#39;...
Definition: TBuffer.cxx:350
ReAllocCharFun_t GetReAllocFunc() const
Return the reallocation method currently used.
Definition: TBuffer.cxx:246
#define ClassImp(name)
Definition: Rtypes.h:279
virtual void PushDataCache(TVirtualArray *)
Push a new data cache area onto the list of area to be used for temporarily store &#39;missing&#39; data memb...
Definition: TBuffer.cxx:331
static TClass * GetClass(const char *name, Bool_t load=kTRUE, Bool_t silent=kFALSE)
Static method returning pointer to TClass of the specified class name.
Definition: TClass.cxx:2893
Mother of all ROOT objects.
Definition: TObject.h:37
TBuffer()
Definition: TBuffer.h:58
Int_t fBufSize
Definition: TBuffer.h:49
void ResetBit(UInt_t f)
Definition: TObject.h:156
virtual void Fatal(const char *method, const char *msgfmt,...) const
Issue fatal error message.
Definition: TObject.cxx:953
void SetReAllocFunc(ReAllocCharFun_t reallocfunc=0)
Set which memory reallocation method to use.
Definition: TBuffer.cxx:255
char * fBufMax
Definition: TBuffer.h:52
void AutoExpand(Int_t size_needed)
Automatically calculate a new size and expand the buffer to fit at least size_needed.
Definition: TBuffer.cxx:142
void SetWriteMode()
Set buffer in write mode.
Definition: TBuffer.cxx:284
void SetBuffer(void *buf, UInt_t bufsiz=0, Bool_t adopt=kTRUE, ReAllocCharFun_t reallocfunc=0)
Sets a new buffer in an existing TBuffer object.
Definition: TBuffer.cxx:165