Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
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
15Buffer base class used for serializing objects.
16*/
17
18#include "TBuffer.h"
19#include "TClass.h"
20#include "TProcessID.h"
21
22constexpr Int_t kExtraSpace = 8; // extra space at end of buffer (used for free block count)
23constexpr Int_t kMaxBufferSize = 0x7FFFFFFE; // largest possible size.
24
25
26
27/// Default streamer implementation used by ClassDefInline to avoid
28/// requirement to include TBuffer.h
30{
31 if (R__b.IsReading())
32 R__b.ReadClassBuffer(cl, objpointer);
33 else
34 R__b.WriteClassBuffer(cl, objpointer);
35}
36
37////////////////////////////////////////////////////////////////////////////////
38/// The user has provided memory than we don't own, thus we can not extent it
39/// either.
40
41static char *R__NoReAllocChar(char *, size_t, size_t)
42{
43 return nullptr;
44}
45
46////////////////////////////////////////////////////////////////////////////////
47/// Create an I/O buffer object. Mode should be either TBuffer::kRead or
48/// TBuffer::kWrite. By default the I/O buffer has a size of
49/// TBuffer::kInitialSize (1024) bytes.
50
52{
54 fMode = mode;
55 fVersion = 0;
56 fParent = nullptr;
57
59
60 fBuffer = new char[fBufSize+kExtraSpace];
61
64
65 SetReAllocFunc( nullptr );
66}
67
68////////////////////////////////////////////////////////////////////////////////
69/// Create an I/O buffer object. Mode should be either TBuffer::kRead or
70/// TBuffer::kWrite.
71
73{
74 if (bufsize < 0)
75 Fatal("TBuffer","Request to create a buffer with a negative size, likely due to an integer overflow: 0x%x for a max of 0x%x.", bufsize, kMaxBufferSize);
78 fMode = mode;
79 fVersion = 0;
80 fParent = nullptr;
81
83
84 fBuffer = new char[fBufSize+kExtraSpace];
85
88
89 SetReAllocFunc( nullptr );
90}
91
92////////////////////////////////////////////////////////////////////////////////
93/// Create an I/O buffer object. Mode should be either TBuffer::kRead or
94/// TBuffer::kWrite. By default the I/O buffer has a size of
95/// TBuffer::kInitialSize (1024) bytes. An external buffer can be passed
96/// to TBuffer via the buf argument. By default this buffer will be adopted
97/// unless adopt is false.
98///
99/// If the new buffer is _not_ adopted and no memory allocation routine
100/// is provided, a Fatal error will be issued if the Buffer attempts to
101/// expand.
102
104{
105 if (bufsize < 0)
106 Fatal("TBuffer","Request to create a buffer with a negative size, likely due to an integer overflow: 0x%x for a max of 0x%x.", bufsize, kMaxBufferSize);
108 fMode = mode;
109 fVersion = 0;
110 fParent = nullptr;
111
113
114 if (buf) {
115 fBuffer = (char *)buf;
116 if ( (fMode&kWrite)!=0 ) {
118 }
119 if (!adopt) ResetBit(kIsOwner);
120 } else {
121 if (fBufSize < kMinimalSize) {
123 }
125 }
128
130
131 if (buf && ( (fMode&kWrite)!=0 ) && fBufSize < 0) {
133 }
134}
135
136////////////////////////////////////////////////////////////////////////////////
137/// Delete an I/O buffer object.
138
140{
141 if (TestBit(kIsOwner)) {
142 //printf("Deleting fBuffer=%lx\n", fBuffer);
143 delete [] fBuffer;
144 }
145 fBuffer = nullptr;
146 fParent = nullptr;
147}
148
149////////////////////////////////////////////////////////////////////////////////
150/// Automatically calculate a new size and expand the buffer to fit at least size_needed.
151/// The goals is to minimize the number of memory allocation and the memory allocation
152/// which avoiding too much memory wastage.
153///
154/// If the size_needed is larger than the current size, the policy
155/// is to expand to double the current size or the size_needed which ever is largest.
156
158{
159 if (size_needed < 0) {
160 Fatal("AutoExpand","Request to expand to a negative size, likely due to an integer overflow: 0x%x for a max of 0x%x.", size_needed, kMaxBufferSize);
161 }
162 if (size_needed > fBufSize) {
163 Long64_t doubling = 2LLU * fBufSize;
166 if (size_needed > doubling) {
168 } else {
170 }
171 }
172}
173
174////////////////////////////////////////////////////////////////////////////////
175/// Sets a new buffer in an existing TBuffer object. If newsiz=0 then the
176/// new buffer is expected to have the same size as the previous buffer.
177/// The current buffer position is reset to the start of the buffer.
178/// If the TBuffer owned the previous buffer, it will be deleted prior
179/// to accepting the new buffer. By default the new buffer will be
180/// adopted unless adopt is false.
181///
182/// If the new buffer is _not_ adopted and no memory allocation routine
183/// is provided, a Fatal error will be issued if the Buffer attempts to
184/// expand.
185
187{
188 if (fBuffer && TestBit(kIsOwner))
189 delete [] fBuffer;
190
191 if (adopt)
193 else
195
196 fBuffer = (char *)buf;
198 if (newsiz > 0) {
199 if ( (fMode&kWrite)!=0 ) {
201 } else {
203 }
204 }
206
208
209 if (buf && ( (fMode&kWrite)!=0 ) && fBufSize < 0) {
211 }
212}
213
214////////////////////////////////////////////////////////////////////////////////
215/// Expand (or shrink) the I/O buffer to newsize bytes.
216/// If copy is true (the default), the existing content of the
217/// buffer is preserved, otherwise the buffer is returned zero-ed out.
218///
219/// In order to avoid losing data, if the current length is greater than
220/// the requested size, we only shrink down to the current length.
221
223{
224 Int_t l = Length();
225 if ( (l > newsize) && copy ) {
226 newsize = l;
227 }
228 const Int_t extraspace = (fMode&kWrite)!=0 ? kExtraSpace : 0;
229
231 if (l < kMaxBufferSize) {
233 } else {
234 Fatal("Expand","Requested size (%d) is too large (max is %d).", newsize, kMaxBufferSize);
235 }
236 }
237 if ( (fMode&kWrite)!=0 ) {
239 copy ? fBufSize+kExtraSpace : 0);
240 } else {
242 copy ? fBufSize : 0);
243 }
244 if (fBuffer == nullptr) {
246 Fatal("Expand","Failed to expand the data buffer using TStorage::ReAllocChar.");
247 } else if (fReAllocFunc == R__NoReAllocChar) {
248 Fatal("Expand","Failed to expand the data buffer because TBuffer does not own it and no custom memory reallocator was provided.");
249 } else {
250 Fatal("Expand","Failed to expand the data buffer using custom memory reallocator 0x%zx.", (size_t)fReAllocFunc);
251 }
252 }
254 fBufCur = fBuffer + l;
256}
257
258////////////////////////////////////////////////////////////////////////////////
259/// Return pointer to parent of this buffer.
260
262{
263 return fParent;
264}
265
266////////////////////////////////////////////////////////////////////////////////
267/// Set parent owning this buffer.
268
270{
271 fParent = parent;
272}
273////////////////////////////////////////////////////////////////////////////////
274/// Return the reallocation method currently used.
275
280
281////////////////////////////////////////////////////////////////////////////////
282/// Set which memory reallocation method to use. If reallocafunc is null,
283/// reset it to the default value (TStorage::ReAlloc)
284
286{
287 if (reallocfunc) {
289 } else {
290 if (TestBit(kIsOwner)) {
292 } else {
294 }
295 }
296}
297
298////////////////////////////////////////////////////////////////////////////////
299/// Set buffer in read mode.
300
302{
303 if ( (fMode&kWrite)!=0 ) {
304 // We had reserved space for the free block count,
305 // release it,
307 }
308 fMode = kRead;
309}
310
311////////////////////////////////////////////////////////////////////////////////
312/// Set buffer in write mode.
313
315{
316 if ( (fMode&kWrite)==0 ) {
317 // We had not yet reserved space for the free block count,
318 // reserve it now.
320 }
321 fMode = kWrite;
322}
323
324////////////////////////////////////////////////////////////////////////////////
325/// Forward to TROOT::GetClass().
326
327TClass *TBuffer::GetClass(const std::type_info &typeinfo)
328{
330}
331
332////////////////////////////////////////////////////////////////////////////////
333/// Forward to TROOT::GetClass().
334
335TClass *TBuffer::GetClass(const char *className)
336{
337 return TClass::GetClass(className);
338}
339
340////////////////////////////////////////////////////////////////////////////////
341/// Return the current Process-ID.
342
344{
345 if (!pidf) return TProcessID::GetPID(); //may happen when cloning an object
346 return nullptr;
347}
348
349////////////////////////////////////////////////////////////////////////////////
350/// Always return 0 (current processID).
351
353{
354 return 0;
355}
356
357////////////////////////////////////////////////////////////////////////////////
358/// Push a new data cache area onto the list of area to be used for
359/// temporarily store 'missing' data members.
360
362{
363 fCacheStack.push_back(obj);
364}
365
366////////////////////////////////////////////////////////////////////////////////
367/// Return the 'current' data cache area from the list of area to be used for
368/// temporarily store 'missing' data members.
369
371{
372 if (fCacheStack.empty()) return nullptr;
373 return fCacheStack.back();
374}
375
376////////////////////////////////////////////////////////////////////////////////
377/// Pop and Return the 'current' data cache area from the list of area to be used for
378/// temporarily store 'missing' data members.
379
381{
383 fCacheStack.pop_back();
384 return val;
385}
386
387////////////////////////////////////////////////////////////////////////////////
388/// Byte-swap N primitive-elements in the buffer.
389/// Bulk API relies on this function.
390
392{
393 char *input_buf = GetCurrent();
395#ifdef R__BYTESWAP
396 Short_t *buf __attribute__((aligned(8))) = reinterpret_cast<Short_t*>(input_buf);
397 for (int idx=0; idx<n; idx++) {
398 Short_t tmp = *reinterpret_cast<Short_t*>(buf + idx); // Makes a copy of the values; frombuf can't handle aliasing.
399 char *tmp_ptr = reinterpret_cast<char *>(&tmp);
400 frombuf(tmp_ptr, buf + idx);
401 }
402#endif
403 } else if ((type == EDataType::kFloat_t) || (type == EDataType::kInt_t) || (type == EDataType::kUInt_t)) {
404#ifdef R__BYTESWAP
405 Float_t *buf __attribute__((aligned(8))) = reinterpret_cast<Float_t*>(input_buf);
406 for (int idx=0; idx<n; idx++) {
407 Float_t tmp = *reinterpret_cast<Float_t*>(buf + idx); // Makes a copy of the values; frombuf can't handle aliasing.
408 char *tmp_ptr = reinterpret_cast<char *>(&tmp);
409 frombuf(tmp_ptr, buf + idx);
410 }
411#endif
413#ifdef R__BYTESWAP
414 Double_t *buf __attribute__((aligned(8))) = reinterpret_cast<Double_t*>(input_buf);
415 for (int idx=0; idx<n; idx++) {
416 Double_t tmp = *reinterpret_cast<Double_t*>(buf + idx); // Makes a copy of the values; frombuf can't handle aliasing.
417 char *tmp_ptr = reinterpret_cast<char*>(&tmp);
418 frombuf(tmp_ptr, buf + idx);
419 }
420#endif
421 } else {
422 return false;
423 }
424
425 return true;
426}
void frombuf(char *&buf, Bool_t *x)
Definition Bytes.h:278
unsigned short UShort_t
Unsigned Short integer 2 bytes (unsigned short)
Definition RtypesCore.h:54
int Int_t
Signed integer 4 bytes (int)
Definition RtypesCore.h:59
float Float_t
Float 4 bytes (float)
Definition RtypesCore.h:71
short Short_t
Signed Short integer 2 bytes (short)
Definition RtypesCore.h:53
long long Long64_t
Portable signed long integer 8 bytes.
Definition RtypesCore.h:83
constexpr Int_t kExtraSpace
Definition TBuffer.cxx:22
constexpr Int_t kMaxBufferSize
Definition TBuffer.cxx:23
static char * R__NoReAllocChar(char *, size_t, size_t)
The user has provided memory than we don't own, thus we can not extent it either.
Definition TBuffer.cxx:41
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
EDataType
Definition TDataType.h:28
@ kFloat_t
Definition TDataType.h:31
@ kULong64_t
Definition TDataType.h:32
@ kInt_t
Definition TDataType.h:30
@ kShort_t
Definition TDataType.h:29
@ kLong64_t
Definition TDataType.h:32
@ kUShort_t
Definition TDataType.h:29
@ kDouble_t
Definition TDataType.h:31
@ kUInt_t
Definition TDataType.h:30
Option_t Option_t TPoint TPoint const char mode
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t type
char *(* ReAllocCharFun_t)(char *, size_t, size_t)
Definition TStorage.h:30
Buffer base class used for serializing objects.
Definition TBuffer.h:43
TBuffer()
Definition TBuffer.h:59
void SetWriteMode()
Set buffer in write mode.
Definition TBuffer.cxx:314
Bool_t ByteSwapBuffer(Long64_t n, EDataType type)
Byte-swap N primitive-elements in the buffer.
Definition TBuffer.cxx:391
CacheList_t fCacheStack
Realloc function to be used when extending the buffer.
Definition TBuffer.h:56
virtual TProcessID * ReadProcessID(UShort_t pidf)=0
Return the current Process-ID.
Definition TBuffer.cxx:343
virtual UShort_t WriteProcessID(TProcessID *pid)=0
Always return 0 (current processID).
Definition TBuffer.cxx:352
Int_t fBufSize
Definition TBuffer.h:50
void SetParent(TObject *parent)
Set parent owning this buffer.
Definition TBuffer.cxx:269
TObject * GetParent() const
Return pointer to parent of this buffer.
Definition TBuffer.cxx:261
char * GetCurrent() const
Definition TBuffer.h:97
void Expand(Int_t newsize, Bool_t copy=kTRUE)
Expand (or shrink) the I/O buffer to newsize bytes.
Definition TBuffer.cxx:222
@ kIsOwner
Definition TBuffer.h:75
virtual void PushDataCache(TVirtualArray *)
Push a new data cache area onto the list of area to be used for temporarily store 'missing' data memb...
Definition TBuffer.cxx:361
void SetReAllocFunc(ReAllocCharFun_t reallocfunc=nullptr)
Set which memory reallocation method to use.
Definition TBuffer.cxx:285
virtual TVirtualArray * PopDataCache()
Pop and Return the 'current' data cache area from the list of area to be used for temporarily store '...
Definition TBuffer.cxx:380
@ kWrite
Definition TBuffer.h:73
@ kRead
Definition TBuffer.h:73
char * fBufMax
Definition TBuffer.h:53
char * fBufCur
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:157
virtual TVirtualArray * PeekDataCache() const
Return the 'current' data cache area from the list of area to be used for temporarily store 'missing'...
Definition TBuffer.cxx:370
@ kMinimalSize
Definition TBuffer.h:78
@ kInitialSize
Definition TBuffer.h:78
virtual ~TBuffer()
Delete an I/O buffer object.
Definition TBuffer.cxx:139
void SetBuffer(void *buf, UInt_t bufsize=0, Bool_t adopt=kTRUE, ReAllocCharFun_t reallocfunc=nullptr)
Sets a new buffer in an existing TBuffer object.
Definition TBuffer.cxx:186
static TClass * GetClass(const std::type_info &typeinfo)
Forward to TROOT::GetClass().
Definition TBuffer.cxx:327
Bool_t fMode
Definition TBuffer.h:48
ReAllocCharFun_t GetReAllocFunc() const
Return the reallocation method currently used.
Definition TBuffer.cxx:276
ReAllocCharFun_t fReAllocFunc
Definition TBuffer.h:55
char * fBuffer
Definition TBuffer.h:51
TObject * fParent
Definition TBuffer.h:54
void SetReadMode()
Set buffer in read mode.
Definition TBuffer.cxx:301
Int_t fVersion
Definition TBuffer.h:49
Int_t Length() const
Definition TBuffer.h:100
TClass instances represent classes, structs and namespaces in the ROOT type system.
Definition TClass.h:84
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:2973
Mother of all ROOT objects.
Definition TObject.h:41
R__ALWAYS_INLINE Bool_t TestBit(UInt_t f) const
Definition TObject.h:202
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
Definition TObject.cxx:864
virtual void Fatal(const char *method, const char *msgfmt,...) const
Issue fatal error message.
Definition TObject.cxx:1099
void ResetBit(UInt_t f)
Definition TObject.h:201
A TProcessID identifies a ROOT job in a unique way in time and space.
Definition TProcessID.h:74
static TProcessID * GetPID()
static: returns pointer to current TProcessID
static char * ReAllocChar(char *vp, size_t size, size_t oldsize)
Reallocate (i.e.
Definition TStorage.cxx:227
Wrapper around an object and giving indirect access to its content even if the object is not of a cla...
const Int_t n
Definition legend1.C:16
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:29
TLine l
Definition textangle.C:4