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