22 constexpr Int_t kExtraSpace = 8;
23 constexpr Int_t kMaxBufferSize = 0x7FFFFFFE;
30 void ROOT::Internal::DefaultStreamer(TBuffer &R__b,
const TClass *cl,
void *objpointer)
33 R__b.ReadClassBuffer(cl, objpointer);
35 R__b.WriteClassBuffer(cl, objpointer);
42 static char *R__NoReAllocChar(
char *,
size_t,
size_t)
52 TBuffer::TBuffer(EMode mode)
54 fBufSize = kInitialSize;
61 fBuffer =
new char[fBufSize+kExtraSpace];
64 fBufMax = fBuffer + fBufSize;
73 TBuffer::TBuffer(EMode mode, Int_t bufsiz)
76 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.", bufsiz, kMaxBufferSize);
77 if (bufsiz < kMinimalSize) bufsiz = kMinimalSize;
85 fBuffer =
new char[fBufSize+kExtraSpace];
88 fBufMax = fBuffer + fBufSize;
104 TBuffer::TBuffer(EMode mode, Int_t bufsiz,
void *buf, Bool_t adopt, ReAllocCharFun_t reallocfunc)
107 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.", bufsiz, kMaxBufferSize);
116 fBuffer = (
char *)buf;
117 if ( (fMode&kWrite)!=0 ) {
118 fBufSize -= kExtraSpace;
120 if (!adopt) ResetBit(kIsOwner);
122 if (fBufSize < kMinimalSize) {
123 fBufSize = kMinimalSize;
125 fBuffer =
new char[(Long64_t)fBufSize+kExtraSpace];
128 fBufMax = fBuffer + fBufSize;
130 SetReAllocFunc( reallocfunc );
132 if (buf && ( (fMode&kWrite)!=0 ) && fBufSize < 0) {
133 Expand( kMinimalSize );
142 if (TestBit(kIsOwner)) {
158 void TBuffer::AutoExpand(Int_t size_needed)
160 if (size_needed < 0) {
161 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);
163 if (size_needed > fBufSize) {
164 Long64_t doubling = 2LLU * fBufSize;
165 if (doubling > kMaxBufferSize)
166 doubling = kMaxBufferSize;
167 if (size_needed > doubling) {
187 void TBuffer::SetBuffer(
void *buf, UInt_t newsiz, Bool_t adopt, ReAllocCharFun_t reallocfunc)
189 if (fBuffer && TestBit(kIsOwner))
197 fBuffer = (
char *)buf;
200 if ( (fMode&kWrite)!=0 ) {
201 fBufSize = newsiz - kExtraSpace;
206 fBufMax = fBuffer + fBufSize;
208 SetReAllocFunc( reallocfunc );
210 if (buf && ( (fMode&kWrite)!=0 ) && fBufSize < 0) {
211 Expand( kMinimalSize );
223 void TBuffer::Expand(Int_t newsize, Bool_t copy)
226 if ( (l > newsize) && copy ) {
229 const Int_t extraspace = (fMode&kWrite)!=0 ? kExtraSpace : 0;
231 if ( ((Long64_t)newsize+extraspace) > kMaxBufferSize) {
232 if (l < kMaxBufferSize) {
233 newsize = kMaxBufferSize - extraspace;
235 Fatal(
"Expand",
"Requested size (%d) is too large (max is %d).", newsize, kMaxBufferSize);
238 if ( (fMode&kWrite)!=0 ) {
239 fBuffer = fReAllocFunc(fBuffer, newsize+kExtraSpace,
240 copy ? fBufSize+kExtraSpace : 0);
242 fBuffer = fReAllocFunc(fBuffer, newsize,
243 copy ? fBufSize : 0);
246 if (fReAllocFunc == TStorage::ReAllocChar) {
247 Fatal(
"Expand",
"Failed to expand the data buffer using TStorage::ReAllocChar.");
248 }
else if (fReAllocFunc == R__NoReAllocChar) {
249 Fatal(
"Expand",
"Failed to expand the data buffer because TBuffer does not own it and no custom memory reallocator was provided.");
251 Fatal(
"Expand",
"Failed to expand the data buffer using custom memory reallocator 0x%lx.", (Long_t)fReAllocFunc);
255 fBufCur = fBuffer + l;
256 fBufMax = fBuffer + fBufSize;
262 TObject *TBuffer::GetParent()
const
270 void TBuffer::SetParent(TObject *parent)
277 ReAllocCharFun_t TBuffer::GetReAllocFunc()
const
286 void TBuffer::SetReAllocFunc(ReAllocCharFun_t reallocfunc )
289 fReAllocFunc = reallocfunc;
291 if (TestBit(kIsOwner)) {
292 fReAllocFunc = TStorage::ReAllocChar;
294 fReAllocFunc = R__NoReAllocChar;
302 void TBuffer::SetReadMode()
304 if ( (fMode&kWrite)!=0 ) {
307 fBufSize += kExtraSpace;
315 void TBuffer::SetWriteMode()
317 if ( (fMode&kWrite)==0 ) {
320 fBufSize -= kExtraSpace;
328 TClass *TBuffer::GetClass(
const std::type_info &typeinfo)
330 return TClass::GetClass(typeinfo);
336 TClass *TBuffer::GetClass(
const char *className)
338 return TClass::GetClass(className);
344 TProcessID *TBuffer::ReadProcessID(UShort_t pidf)
346 if (!pidf)
return TProcessID::GetPID();
353 UShort_t TBuffer::WriteProcessID(TProcessID *)
362 void TBuffer::PushDataCache(TVirtualArray *obj)
364 fCacheStack.push_back(obj);
371 TVirtualArray *TBuffer::PeekDataCache()
const
373 if (fCacheStack.empty())
return 0;
374 return fCacheStack.back();
381 TVirtualArray *TBuffer::PopDataCache()
383 TVirtualArray *val = PeekDataCache();
384 fCacheStack.pop_back();
392 Bool_t TBuffer::ByteSwapBuffer(Long64_t n, EDataType type)
394 char *input_buf = GetCurrent();
395 if ((type == EDataType::kShort_t) || (type == EDataType::kUShort_t)) {
397 Short_t *buf __attribute__((aligned(8))) =
reinterpret_cast<Short_t*
>(input_buf);
398 for (
int idx=0; idx<n; idx++) {
399 Short_t tmp = *
reinterpret_cast<Short_t*
>(buf + idx);
400 char *tmp_ptr =
reinterpret_cast<char *
>(&tmp);
401 frombuf(tmp_ptr, buf + idx);
404 }
else if ((type == EDataType::kFloat_t) || (type == EDataType::kInt_t) || (type == EDataType::kUInt_t)) {
406 Float_t *buf __attribute__((aligned(8))) =
reinterpret_cast<Float_t*
>(input_buf);
407 for (
int idx=0; idx<n; idx++) {
408 Float_t tmp = *
reinterpret_cast<Float_t*
>(buf + idx);
409 char *tmp_ptr =
reinterpret_cast<char *
>(&tmp);
410 frombuf(tmp_ptr, buf + idx);
413 }
else if ((type == EDataType::kDouble_t) || (type == EDataType::kLong64_t) || (type == EDataType::kULong64_t)) {
415 Double_t *buf __attribute__((aligned(8))) =
reinterpret_cast<Double_t*
>(input_buf);
416 for (
int idx=0; idx<n; idx++) {
417 Double_t tmp = *
reinterpret_cast<Double_t*
>(buf + idx);
418 char *tmp_ptr =
reinterpret_cast<char*
>(&tmp);
419 frombuf(tmp_ptr, buf + idx);