Logo ROOT   6.08/07
Reference Guide
TBufferJSON.cxx
Go to the documentation of this file.
1 //
2 // Author: Sergey Linev 4.03.2014
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2004, 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 //________________________________________________________________________
13 //
14 // TBufferJSON
15 //
16 // Class for serializing object into JavaScript Object Notation (JSON) format.
17 // It creates such object representation, which can be directly
18 // used in JavaScript ROOT (JSROOT) for drawing.
19 //
20 // TBufferJSON implements TBuffer interface, therefore most of
21 // ROOT and user classes can be converted into JSON.
22 // There are certain limitations for classes with custom streamers,
23 // which should be equipped specially for this purposes (see TCanvas::Streamer() as example).
24 //
25 // To perform conversion, one should use TBufferJSON::ConvertToJSON method like:
26 //
27 // TH1* h1 = new TH1I("h1","title",100, 0, 10);
28 // h1->FillRandom("gaus",10000);
29 // TString json = TBufferJSON::ConvertToJSON(h1);
30 //
31 //________________________________________________________________________
32 
33 
34 #include "TBufferJSON.h"
35 
36 #include <typeinfo>
37 #include <string>
38 #include <string.h>
39 #include <locale.h>
40 
41 #include "Compression.h"
42 
43 #include "TArrayI.h"
44 #include "TObjArray.h"
45 #include "TROOT.h"
46 #include "TClass.h"
47 #include "TClassTable.h"
48 #include "TClassEdit.h"
49 #include "TDataType.h"
50 #include "TRealData.h"
51 #include "TDataMember.h"
52 #include "TExMap.h"
53 #include "TMethodCall.h"
54 #include "TStreamerInfo.h"
55 #include "TStreamerElement.h"
56 #include "TProcessID.h"
57 #include "TFile.h"
58 #include "TMemberStreamer.h"
59 #include "TStreamer.h"
60 #include "TStreamerInfoActions.h"
61 #include "RVersion.h"
62 #include "Riostream.h"
63 #include "TClonesArray.h"
64 #include "TVirtualMutex.h"
65 #include "TInterpreter.h"
66 
67 #ifdef R__VISUAL_CPLUSPLUS
68 #define FLong64 "%I64d"
69 #define FULong64 "%I64u"
70 #else
71 #define FLong64 "%lld"
72 #define FULong64 "%llu"
73 #endif
74 
76 
77 
78 const char *TBufferJSON::fgFloatFmt = "%e";
79 const char *TBufferJSON::fgDoubleFmt = "%.14e";
80 
81 
82 // TJSONStackObj is used to keep stack of object hierarchy,
83 // stored in TBuffer. For instance, data for parent class(es)
84 // stored in subnodes, but initial object node will be kept.
85 
86 class TJSONStackObj : public TObject {
87 public:
88  TStreamerInfo *fInfo; //!
89  TStreamerElement *fElem; //! element in streamer info
90  Int_t fElemNumber; //! number of streamer element in streamer info
91  Bool_t fIsStreamerInfo; //!
92  Bool_t fIsElemOwner; //!
93  Bool_t fIsPostProcessed;//! indicate that value is written
94  Bool_t fIsObjStarted; //! indicate that object writing started, should be closed in postprocess
95  Bool_t fAccObjects; //! if true, accumulate whole objects in values
96  TObjArray fValues; //! raw values
97  Int_t fLevel; //! indent level
98 
99  TJSONStackObj() :
100  TObject(),
101  fInfo(0),
102  fElem(0),
103  fElemNumber(0),
104  fIsStreamerInfo(kFALSE),
105  fIsElemOwner(kFALSE),
106  fIsPostProcessed(kFALSE),
107  fIsObjStarted(kFALSE),
108  fAccObjects(kFALSE),
109  fValues(),
110  fLevel(0)
111  {
112  fValues.SetOwner(kTRUE);
113  }
114 
115  virtual ~TJSONStackObj()
116  {
117  if (fIsElemOwner) delete fElem;
118  }
119 
120  Bool_t IsStreamerInfo() const
121  {
122  return fIsStreamerInfo;
123  }
124  Bool_t IsStreamerElement() const
125  {
126  return !fIsStreamerInfo && (fElem != 0);
127  }
128 
129  void PushValue(TString &v)
130  {
131  fValues.Add(new TObjString(v));
132  v.Clear();
133  }
134 };
135 
136 
137 ////////////////////////////////////////////////////////////////////////////////
138 /// Creates buffer object to serialize data into json.
139 
141  TBuffer(TBuffer::kWrite),
142  fOutBuffer(),
143  fOutput(0),
144  fValue(),
145  fJsonrMap(),
146  fJsonrCnt(0),
147  fStack(),
148  fExpectedChain(kFALSE),
149  fCompact(0),
150  fSemicolon(" : "),
151  fArraySepar(", "),
152  fNumericLocale()
153 {
154  fBufSize = 1000000000;
155 
156  SetParent(0);
158  //SetBit(kTextBasedStreaming);
159 
160  fOutBuffer.Capacity(10000);
161  fValue.Capacity(1000);
162  fOutput = &fOutBuffer;
163 
164  // checks if setlocale(LC_NUMERIC) returns others than "C"
165  // in this case locale will be changed and restored at the end of object conversion
166 
167  char* loc = setlocale(LC_NUMERIC, 0);
168  if ((loc!=0) && (strcmp(loc,"C")!=0)) {
169  fNumericLocale = loc;
170  setlocale(LC_NUMERIC, "C");
171  }
172 }
173 
174 ////////////////////////////////////////////////////////////////////////////////
175 /// destroy buffer
176 
178 {
179  fStack.Delete();
180 
181  if (fNumericLocale.Length()>0)
182  setlocale(LC_NUMERIC, fNumericLocale.Data());
183 }
184 
185 ////////////////////////////////////////////////////////////////////////////////
186 /// converts object, inherited from TObject class, to JSON string
187 
188 TString TBufferJSON::ConvertToJSON(const TObject *obj, Int_t compact, const char *member_name)
189 {
190  TClass *clActual = 0;
191  void *ptr = (void *) obj;
192 
193  if (obj!=0) {
194  clActual = TObject::Class()->GetActualClass(obj);
195  if (!clActual) clActual = TObject::Class(); else
196  if (clActual != TObject::Class())
197  ptr = (void *) ((Long_t) obj - clActual->GetBaseClassOffset(TObject::Class()));
198  }
199 
200  return ConvertToJSON(ptr, clActual, compact, member_name);
201 }
202 
203 ////////////////////////////////////////////////////////////////////////////////
204 /// Set level of space/newline compression
205 /// 0 - no any compression
206 /// 1 - exclude spaces in the begin
207 /// 2 - remove newlines
208 /// 3 - exclude spaces as much as possible
209 
210 void TBufferJSON::SetCompact(int level)
211 {
212  fCompact = level;
213  fSemicolon = fCompact > 2 ? ":" : " : ";
214  fArraySepar = fCompact > 2 ? "," : ", ";
215 }
216 
217 
218 ////////////////////////////////////////////////////////////////////////////////
219 /// Converts any type of object to JSON string
220 /// One should provide pointer on object and its class name
221 /// Following values of compact parameter can be used
222 /// 0 - no any compression
223 /// 1 - exclude spaces in the begin
224 /// 2 - remove newlines
225 /// 3 - exclude spaces as much as possible
226 /// When member_name specified, converts only this data member
227 
228 TString TBufferJSON::ConvertToJSON(const void *obj, const TClass *cl,
229  Int_t compact, const char *member_name)
230 {
231  if ((member_name!=0) && (obj!=0)) {
232  TRealData *rdata = cl->GetRealData(member_name);
233  if (rdata==0) return TString();
234  TDataMember *member = rdata->GetDataMember();
235  if (member==0) return TString();
236 
237  Int_t arraylen = -1;
238  if (member->GetArrayIndex()!=0) {
239  TRealData *idata = cl->GetRealData(member->GetArrayIndex());
240  TDataMember *imember = (idata!=0) ? idata->GetDataMember() : 0;
241  if ((imember!=0) && (strcmp(imember->GetTrueTypeName(),"int")==0)) {
242  arraylen = *((int *) ((char *) obj + idata->GetThisOffset()));
243  }
244  }
245 
246  void *ptr = (char *) obj + rdata->GetThisOffset();
247  if (member->IsaPointer()) ptr = *((char **) ptr);
248 
249  return TBufferJSON::ConvertToJSON(ptr, member, compact, arraylen);
250  }
251 
252  TBufferJSON buf;
253 
254  buf.SetCompact(compact);
255 
256  buf.JsonWriteObject(obj, cl);
257 
258  return buf.fOutBuffer.Length() ? buf.fOutBuffer : buf.fValue;
259 }
260 
261 ////////////////////////////////////////////////////////////////////////////////
262 /// Converts selected data member into json
263 /// Parameter ptr specifies address in memory, where data member is located
264 /// compact parameter defines compactness of produced JSON (from 0 to 3)
265 /// arraylen (when specified) is array length for this data member, //[fN] case
266 
268  Int_t compact, Int_t arraylen)
269 {
270  if ((ptr == 0) || (member == 0)) return TString("null");
271 
272  Bool_t stlstring = !strcmp(member->GetTrueTypeName(), "string");
273 
274  Int_t isstl = member->IsSTLContainer();
275 
276  TClass *mcl = member->IsBasic() ? 0 : gROOT->GetClass(member->GetTypeName());
277 
278  if ((mcl != 0) && (mcl != TString::Class()) && !stlstring && !isstl &&
279  (mcl->GetBaseClassOffset(TArray::Class()) != 0))
280  return TBufferJSON::ConvertToJSON(ptr, mcl, compact);
281 
282  TBufferJSON buf;
283 
284  buf.SetCompact(compact);
285 
286  return buf.JsonWriteMember(ptr, member, mcl, arraylen);
287 }
288 
289 ////////////////////////////////////////////////////////////////////////////////
290 /// Convert object into JSON and store in text file
291 /// Returns size of the produce file
292 /// Used in TObject::SaveAs()
293 
294 Int_t TBufferJSON::ExportToFile(const char* filename, const TObject *obj, const char* option)
295 {
296  if (!obj || !filename || (*filename==0)) return 0;
297 
298  Int_t compact = 0;
299  if (option && (*option >= '0') && (*option <='3')) compact = TString(option,1).Atoi();
300 
301  TString json = TBufferJSON::ConvertToJSON(obj, compact);
302 
303  std::ofstream ofs (filename);
304  ofs << json.Data();
305  ofs.close();
306 
307  return json.Length();
308 }
309 
310 ////////////////////////////////////////////////////////////////////////////////
311 /// Convert object into JSON and store in text file
312 /// Returns size of the produce file
313 
314 Int_t TBufferJSON::ExportToFile(const char* filename, const void *obj, const TClass *cl, const char* option)
315 {
316  if (!obj || !cl || !filename || (*filename==0)) return 0;
317 
318  Int_t compact = 0;
319  if (option && (*option >= '0') && (*option <='3')) compact = TString(option,1).Atoi();
320 
321  TString json = TBufferJSON::ConvertToJSON(obj, cl, compact);
322 
323  std::ofstream ofs (filename);
324  ofs << json.Data();
325  ofs.close();
326 
327  return json.Length();
328 }
329 
330 ////////////////////////////////////////////////////////////////////////////////
331 /// Convert single data member to JSON structures
332 /// Returns string with converted member
333 
335  TClass *memberClass, Int_t arraylen)
336 {
337  if (member == 0) return "null";
338 
339  if (gDebug > 2)
340  Info("JsonWriteMember", "Write member %s type %s ndim %d",
341  member->GetName(), member->GetTrueTypeName(), member->GetArrayDim());
342 
343  PushStack(0);
344  fValue.Clear();
345 
346  if (member->IsBasic()) {
347 
348  Int_t tid = member->GetDataType() ? member->GetDataType()->GetType() : kNoType_t;
349 
350  if (ptr == 0) {
351  fValue = "null";
352  } else if ((member->GetArrayDim() == 0) && (arraylen<0)) {
353  switch (tid) {
354  case kChar_t:
355  JsonWriteBasic(*((Char_t *)ptr));
356  break;
357  case kShort_t:
358  JsonWriteBasic(*((Short_t *)ptr));
359  break;
360  case kInt_t:
361  JsonWriteBasic(*((Int_t *)ptr));
362  break;
363  case kLong_t:
364  JsonWriteBasic(*((Long_t *)ptr));
365  break;
366  case kFloat_t:
367  JsonWriteBasic(*((Float_t *)ptr));
368  break;
369  case kCounter:
370  JsonWriteBasic(*((Int_t *)ptr));
371  break;
372  case kCharStar:
373  WriteCharP((Char_t *)ptr);
374  break;
375  case kDouble_t:
376  JsonWriteBasic(*((Double_t *)ptr));
377  break;
378  case kDouble32_t:
379  JsonWriteBasic(*((Double_t *)ptr));
380  break;
381  case kchar:
382  JsonWriteBasic(*((char *)ptr));
383  break;
384  case kUChar_t:
385  JsonWriteBasic(*((UChar_t *)ptr));
386  break;
387  case kUShort_t:
388  JsonWriteBasic(*((UShort_t *)ptr));
389  break;
390  case kUInt_t:
391  JsonWriteBasic(*((UInt_t *)ptr));
392  break;
393  case kULong_t:
394  JsonWriteBasic(*((ULong_t *)ptr));
395  break;
396  case kBits:
397  JsonWriteBasic(*((UInt_t *)ptr));
398  break;
399  case kLong64_t:
400  JsonWriteBasic(*((Long64_t *)ptr));
401  break;
402  case kULong64_t:
403  JsonWriteBasic(*((ULong64_t *)ptr));
404  break;
405  case kBool_t:
406  JsonWriteBasic(*((Bool_t *)ptr));
407  break;
408  case kFloat16_t:
409  JsonWriteBasic(*((Float_t *)ptr));
410  break;
411  case kOther_t:
412  case kNoType_t:
413  case kVoid_t:
414  break;
415  }
416  } else if ((member->GetArrayDim() == 1) || (arraylen>=0)) {
417  Int_t n = (arraylen>=0) ? arraylen : member->GetMaxIndex(0);
418  switch (tid) {
419  case kChar_t:
420  WriteFastArray((Char_t *)ptr, n);
421  break;
422  case kShort_t:
423  WriteFastArray((Short_t *)ptr, n);
424  break;
425  case kInt_t:
426  WriteFastArray((Int_t *)ptr, n);
427  break;
428  case kLong_t:
429  WriteFastArray((Long_t *)ptr, n);
430  break;
431  case kFloat_t:
432  WriteFastArray((Float_t *)ptr, n);
433  break;
434  case kCounter:
435  WriteFastArray((Int_t *)ptr, n);
436  break;
437  case kCharStar:
438  WriteFastArray((Char_t *)ptr, n);
439  break;
440  case kDouble_t:
441  WriteFastArray((Double_t *)ptr, n);
442  break;
443  case kDouble32_t:
444  WriteFastArray((Double_t *)ptr, n);
445  break;
446  case kchar:
447  WriteFastArray((char *)ptr, n);
448  break;
449  case kUChar_t:
450  WriteFastArray((UChar_t *)ptr, n);
451  break;
452  case kUShort_t:
453  WriteFastArray((UShort_t *)ptr, n);
454  break;
455  case kUInt_t:
456  WriteFastArray((UInt_t *)ptr, n);
457  break;
458  case kULong_t:
459  WriteFastArray((ULong_t *)ptr, n);
460  break;
461  case kBits:
462  WriteFastArray((UInt_t *)ptr, n);
463  break;
464  case kLong64_t:
465  WriteFastArray((Long64_t *)ptr, n);
466  break;
467  case kULong64_t:
468  WriteFastArray((ULong64_t *)ptr, n);
469  break;
470  case kBool_t:
471  WriteFastArray((Bool_t *)ptr, n);
472  break;
473  case kFloat16_t:
474  WriteFastArray((Float_t *)ptr, n);
475  break;
476  case kOther_t:
477  case kNoType_t:
478  case kVoid_t:
479  break;
480  }
481  } else {
482  // here generic code to write n-dimensional array
483 
484  TArrayI indexes(member->GetArrayDim() - 1);
485  indexes.Reset(0);
486 
487  Int_t cnt = 0;
488  while (cnt >= 0) {
489  if (indexes[cnt] >= member->GetMaxIndex(cnt)) {
490  fOutBuffer.Append(" ]");
491  indexes[cnt--] = 0;
492  if (cnt >= 0) indexes[cnt]++;
493  continue;
494  }
495 
496  if (indexes[cnt] > 0)
498  else
499  fOutBuffer.Append("[ ");
500 
501  if (++cnt == indexes.GetSize()) {
502  Int_t shift = 0;
503  for (Int_t k = 0; k < indexes.GetSize(); k++) {
504  shift = shift * member->GetMaxIndex(k) + indexes[k];
505  }
506 
507  Int_t len = member->GetMaxIndex(indexes.GetSize());
508  shift *= len;
509 
510  fValue.Clear();
511 
512  switch (tid) {
513  case kChar_t:
514  WriteFastArray((Char_t *)ptr + shift, len);
515  break;
516  case kShort_t:
517  WriteFastArray((Short_t *)ptr + shift, len);
518  break;
519  case kInt_t:
520  WriteFastArray((Int_t *)ptr + shift, len);
521  break;
522  case kLong_t:
523  WriteFastArray((Long_t *)ptr + shift, len);
524  break;
525  case kFloat_t:
526  WriteFastArray((Float_t *)ptr + shift, len);
527  break;
528  case kCounter:
529  WriteFastArray((Int_t *)ptr + shift, len);
530  break;
531  case kCharStar:
532  WriteFastArray((Char_t *)ptr + shift, len);
533  break;
534  case kDouble_t:
535  WriteFastArray((Double_t *)ptr + shift, len);
536  break;
537  case kDouble32_t:
538  WriteFastArray((Double_t *)ptr + shift, len);
539  break;
540  case kchar:
541  WriteFastArray((char *)ptr + shift, len);
542  break;
543  case kUChar_t:
544  WriteFastArray((UChar_t *)ptr + shift, len);
545  break;
546  case kUShort_t:
547  WriteFastArray((UShort_t *)ptr + shift, len);
548  break;
549  case kUInt_t:
550  WriteFastArray((UInt_t *)ptr + shift, len);
551  break;
552  case kULong_t:
553  WriteFastArray((ULong_t *)ptr + shift, len);
554  break;
555  case kBits:
556  WriteFastArray((UInt_t *)ptr + shift, len);
557  break;
558  case kLong64_t:
559  WriteFastArray((Long64_t *)ptr + shift, len);
560  break;
561  case kULong64_t:
562  WriteFastArray((ULong64_t *)ptr + shift, len);
563  break;
564  case kBool_t:
565  WriteFastArray((Bool_t *)ptr + shift, len);
566  break;
567  case kFloat16_t:
568  WriteFastArray((Float_t *)ptr + shift, len);
569  break;
570  case kOther_t:
571  case kNoType_t:
572  case kVoid_t:
573  fValue = "null";
574  break;
575  }
576 
578  indexes[--cnt]++;
579  }
580  }
581 
582  fValue = fOutBuffer;
583  }
584  } else if (memberClass == TString::Class()) {
585  TString *str = (TString *) ptr;
586  fValue.Append("\"");
587  if (str != 0) fValue.Append(*str);
588  fValue.Append("\"");
589  } else if ((member->IsSTLContainer() == ROOT::kSTLvector) ||
590  (member->IsSTLContainer() == ROOT::kSTLlist) ||
591  (member->IsSTLContainer() == ROOT::kSTLforwardlist)) {
592 
593  if (memberClass)
594  ((TClass *)memberClass)->Streamer((void *)ptr, *this);
595  else
596  fValue = "[]";
597 
598  if (fValue == "0") fValue = "[]";
599 
600  } else if (memberClass && memberClass->GetBaseClassOffset(TArray::Class()) == 0) {
601  TArray *arr = (TArray *) ptr;
602  if ((arr != 0) && (arr->GetSize() > 0)) {
603  arr->Streamer(*this);
604  // WriteFastArray(arr->GetArray(), arr->GetSize());
605  if (Stack()->fValues.GetLast() > 0) {
606  Warning("TBufferJSON", "When streaming TArray, more than 1 object in the stack, use second item");
607  fValue = Stack()->fValues.At(1)->GetName();
608  }
609  } else
610  fValue = "[]";
611  } else if (memberClass && !strcmp(memberClass->GetName(), "string")) {
612  // here value contains quotes, stack can be ignored
613  ((TClass *)memberClass)->Streamer((void *)ptr, *this);
614  }
615  PopStack();
616 
617  if (fValue.Length()) return fValue;
618 
619  if ((memberClass == 0) || (member->GetArrayDim() > 0)) return "\"not supported\"";
620 
621  return TBufferJSON::ConvertToJSON(ptr, memberClass);
622 }
623 
624 
625 ////////////////////////////////////////////////////////////////////////////////
626 /// Check that object already stored in the buffer
627 
629 {
630  if (obj == 0) return kTRUE;
631 
632  return fJsonrMap.find(obj) != fJsonrMap.end();
633 }
634 
635 ////////////////////////////////////////////////////////////////////////////////
636 /// Check that object already stored in the buffer
637 
638 Bool_t TBufferJSON::CheckObject(const void *ptr, const TClass * /*cl*/)
639 {
640  if (ptr == 0) return kTRUE;
641 
642  return fJsonrMap.find(ptr) != fJsonrMap.end();
643 }
644 
645 ////////////////////////////////////////////////////////////////////////////////
646 /// Convert object into json structures.
647 /// !!! Should be used only by TBufferJSON itself.
648 /// Use ConvertToJSON() methods to convert object to json
649 /// Redefined here to avoid gcc 3.x warning
650 
652 {
653  if (gDebug > 1)
654  Info("WriteObject", "Object %p", obj);
655 
657 }
658 
659 ////////////////////////////////////////////////////////////////////////////////
660 /// add new level to the structures stack
661 
662 TJSONStackObj *TBufferJSON::PushStack(Int_t inclevel)
663 {
664  TJSONStackObj *curr = Stack();
665  TJSONStackObj *stack = new TJSONStackObj();
666  stack->fLevel = (curr ? curr->fLevel : 0) + inclevel;
667  fStack.Add(stack);
668  return stack;
669 }
670 
671 ////////////////////////////////////////////////////////////////////////////////
672 /// remove one level from stack
673 
674 TJSONStackObj *TBufferJSON::PopStack()
675 {
676  TObject *last = fStack.Last();
677  if (last != 0) {
678  fStack.Remove(last);
679  delete last;
680  fStack.Compress();
681  }
682  return dynamic_cast<TJSONStackObj *>(fStack.Last());
683 }
684 
685 ////////////////////////////////////////////////////////////////////////////////
686 /// return stack object of specified depth
687 
688 TJSONStackObj *TBufferJSON::Stack(Int_t depth)
689 {
690  TJSONStackObj *stack = 0;
691  if (depth <= fStack.GetLast())
692  stack = dynamic_cast<TJSONStackObj *>(fStack.At(fStack.GetLast() - depth));
693  return stack;
694 }
695 
696 ////////////////////////////////////////////////////////////////////////////////
697 /// Info("AppendOutput"," '%s' '%s'", line0, line1?line1 : "---");
698 
699 void TBufferJSON::AppendOutput(const char *line0, const char *line1)
700 {
701  if (line0 != 0) fOutput->Append(line0);
702 
703  if (line1 != 0) {
704  if (fCompact < 2) fOutput->Append("\n");
705 
706  if (strlen(line1) > 0) {
707  if (fCompact < 1) {
708  TJSONStackObj *stack = Stack();
709  if ((stack != 0) && (stack->fLevel > 0))
710  fOutput->Append(' ', stack->fLevel);
711  }
712  fOutput->Append(line1);
713  }
714  }
715 }
716 
717 ////////////////////////////////////////////////////////////////////////////////
718 
719 void TBufferJSON::JsonStartElement(const TStreamerElement *elem, const TClass *base_class)
720 {
721  const char *elem_name = 0;
722 
723  if (base_class == 0) {
724  elem_name = elem->GetName();
725  } else {
726  switch (JsonSpecialClass(base_class)) {
727  case TClassEdit::kVector :
728  elem_name = "fVector";
729  break;
730  case TClassEdit::kList :
731  elem_name = "fList";
732  break;
733  case TClassEdit::kDeque :
734  elem_name = "fDeque";
735  break;
736  case TClassEdit::kMap :
737  elem_name = "fMap";
738  break;
739  case TClassEdit::kMultiMap :
740  elem_name = "fMultiMap";
741  break;
742  case TClassEdit::kSet :
743  elem_name = "fSet";
744  break;
745  case TClassEdit::kMultiSet :
746  elem_name = "fMultiSet";
747  break;
748  case TClassEdit::kBitSet :
749  elem_name = "fBitSet";
750  break;
751  case 100:
752  elem_name = "fArray";
753  break;
754  case 110:
755  case 120:
756  elem_name = "fString";
757  break;
758  }
759  }
760 
761  if (elem_name != 0) {
762  AppendOutput(",", "\"");
763  AppendOutput(elem_name);
764  AppendOutput("\"");
766  }
767 }
768 
769 ////////////////////////////////////////////////////////////////////////////////
770 
772 {
773  TJSONStackObj *stack = Stack();
774  if (stack != 0) stack->fIsPostProcessed = kTRUE;
775 }
776 
777 ////////////////////////////////////////////////////////////////////////////////
778 /// return non-zero value when class has special handling in JSON
779 /// it is TCollection (-130), TArray (100), TString (110), std::string (120) and STL containers (1..6)
780 
782 {
783  if (cl == 0) return 0;
784 
785  Bool_t isarray = strncmp("TArray", cl->GetName(), 6) == 0;
786  if (isarray) isarray = ((TClass *)cl)->GetBaseClassOffset(TArray::Class()) == 0;
787  if (isarray) return 100;
788 
789  // negative value used to indicate that collection stored as object
790  if (((TClass *)cl)->GetBaseClassOffset(TCollection::Class()) == 0) return -130;
791 
792  // special case for TString - it is saved as string in JSON
793  if (cl == TString::Class()) return 110;
794 
795  bool isstd = TClassEdit::IsStdClass(cl->GetName());
796  int isstlcont(ROOT::kNotSTL);
797  if (isstd) isstlcont = cl->GetCollectionType();
798  if (isstlcont > 0) return isstlcont;
799 
800  // also special handling for STL string, which handled similar to TString
801  if (isstd && !strcmp(cl->GetName(), "string")) return 120;
802 
803  return 0;
804 }
805 
806 ////////////////////////////////////////////////////////////////////////////////
807 /// Write object to buffer
808 /// If object was written before, only pointer will be stored
809 /// If check_map==kFALSE, object will be stored in any case and pointer will not be registered in the map
810 
811 void TBufferJSON::JsonWriteObject(const void *obj, const TClass *cl, Bool_t check_map)
812 {
813  // static int cnt = 0;
814 
815  if (!cl) obj = 0;
816 
817  //if (cnt++>100) return;
818 
819  if (gDebug > 0)
820  Info("JsonWriteObject", "Object %p class %s check_map %s", obj, cl ? cl->GetName() : "null", check_map ? "true" : "false");
821 
822  Int_t special_kind = JsonSpecialClass(cl);
823 
824  TString fObjectOutput, *fPrevOutput(0);
825 
826  TJSONStackObj *stack = Stack();
827 
828  if (stack && stack->fAccObjects && ((fValue.Length() > 0) || (stack->fValues.GetLast() >= 0))) {
829  // accumulate data of super-object in stack
830 
831  if (fValue.Length() > 0) {
832  stack->fValues.Add(new TObjString(fValue));
833  fValue.Clear();
834  }
835 
836  // redirect output to local buffer, use it later as value
837  fPrevOutput = fOutput;
838  fOutput = &fObjectOutput;
839  } else if ((special_kind <= 0) || (special_kind > 100)) {
840  // FIXME: later post processing should be active for all special classes, while they all keep output in the value
842  }
843 
844  if (obj == 0) {
845  AppendOutput("null");
846  goto post_process;
847  }
848 
849  if (special_kind <= 0) {
850  // add element name which should correspond to the object
851  if (check_map) {
852  std::map<const void *, unsigned>::const_iterator iter = fJsonrMap.find(obj);
853  if (iter != fJsonrMap.end()) {
854  // old-style refs, coded into string like "$ref12"
855  AppendOutput(Form("\"$ref:%u\"", iter->second));
856  // new-style refs, coded into extra object {"$ref":12}, auto-detected by JSROOT
857  //AppendOutput(Form("{\"$ref\":%u}", iter->second));
858  goto post_process;
859  }
860  fJsonrMap[obj] = fJsonrCnt;
861  }
862 
863  fJsonrCnt++; // object counts is important in dereferencing part
864 
865  stack = PushStack(2);
866  AppendOutput("{", "\"_typename\"");
868  AppendOutput("\"");
869  AppendOutput(cl->GetName());
870  AppendOutput("\"");
871  } else {
872  // for array, string and STL collections different handling -
873  // they not recognized at the end as objects in JSON
874  stack = PushStack(0);
875  }
876 
877  if (gDebug > 3)
878  Info("JsonWriteObject", "Starting object %p write for class: %s",
879  obj, cl->GetName());
880 
881  stack->fAccObjects = special_kind < 10;
882 
883  if (special_kind == -130)
884  JsonStreamCollection((TCollection *) obj, cl);
885  else
886  ((TClass *)cl)->Streamer((void *)obj, *this);
887 
888  if (gDebug > 3)
889  Info("JsonWriteObject", "Done object %p write for class: %s",
890  obj, cl->GetName());
891 
892  if (special_kind == 100) {
893  if (stack->fValues.GetLast() != 0)
894  Error("JsonWriteObject", "Problem when writing array");
895  stack->fValues.Delete();
896  } else if ((special_kind == 110) || (special_kind == 120)) {
897  if (stack->fValues.GetLast() > 1)
898  Error("JsonWriteObject", "Problem when writing TString or std::string");
899  stack->fValues.Delete();
901  fValue.Clear();
902  } else if ((special_kind > 0) && (special_kind <= TClassEdit::kBitSet)) {
903  // here make STL container processing
904 
905  if (stack->fValues.GetLast() < 0) {
906  // empty container
907  if (fValue != "0") Error("JsonWriteObject", "With empty stack fValue!=0");
908  fValue = "[]";
909  } else if (stack->fValues.GetLast() == 0) {
910  // case of simple vector, array already in the value
911  stack->fValues.Delete();
912  if (fValue.Length() == 0) {
913  Error("JsonWriteObject", "Empty value when it should contain something");
914  fValue = "[]";
915  }
916 
917  } else {
918  const char *separ = "[";
919 
920  if (fValue.Length() > 0) {
921  stack->fValues.Add(new TObjString(fValue));
922  fValue.Clear();
923  }
924 
925  Int_t size = TString(stack->fValues.At(0)->GetName()).Atoi();
926 
927  if ((size * 2 == stack->fValues.GetLast()) &&
928  ((special_kind == TClassEdit::kMap) || (special_kind == TClassEdit::kMultiMap))) {
929  // special handling for std::map. Create entries like { 'first' : key, 'second' : value }
930  for (Int_t k = 1; k < stack->fValues.GetLast(); k += 2) {
931  fValue.Append(separ);
932  separ = fArraySepar.Data();
933  fJsonrCnt++; // account each entry in map, can conflict with objects inside values
934  fValue.Append("{");
935  fValue.Append("\"first\"");
937  fValue.Append(stack->fValues.At(k)->GetName());
939  fValue.Append("\"second\"");
941  fValue.Append(stack->fValues.At(k + 1)->GetName());
942  fValue.Append("}");
943  }
944  } else {
945  // for most stl containers write just like blob, but skipping first element with size
946  for (Int_t k = 1; k <= stack->fValues.GetLast(); k++) {
947  fValue.Append(separ);
948  separ = fArraySepar.Data();
949  fValue.Append(stack->fValues.At(k)->GetName());
950  }
951  }
952 
953  fValue.Append("]");
954  stack->fValues.Delete();
955  }
956  }
957 
958  if ((special_kind == 0) &&
959  ((stack->fValues.GetLast() >= 0) || (fValue.Length() > 0))) {
960  if (gDebug > 0)
961  Info("JsonWriteObject", "Create blob value for class %s", cl->GetName());
962 
963  AppendOutput(fArraySepar.Data(), "\"_blob\"");
965 
966  const char *separ = "[";
967 
968  for (Int_t k = 0; k <= stack->fValues.GetLast(); k++) {
969  AppendOutput(separ);
970  separ = fArraySepar.Data();
971  AppendOutput(stack->fValues.At(k)->GetName());
972  }
973 
974  if (fValue.Length() > 0) {
975  AppendOutput(separ);
977  }
978 
979  AppendOutput("]");
980 
981  fValue.Clear();
982  stack->fValues.Delete();
983  }
984 
985  PopStack();
986 
987  if (special_kind <= 0) {
988  AppendOutput(0, "}");
989  }
990 
991 post_process:
992 
993  if (fPrevOutput != 0) {
994  fOutput = fPrevOutput;
995  // for STL containers and TArray object in fValue itself
996  if ((special_kind <= 0) || (special_kind > 100))
997  fValue = fObjectOutput;
998  else if (fObjectOutput.Length() != 0)
999  Error("JsonWriteObject", "Non-empty object output for special class %s", cl->GetName());
1000  }
1001 }
1002 
1003 ////////////////////////////////////////////////////////////////////////////////
1004 /// store content of collection
1005 
1007 {
1008  AppendOutput(",", "\"name\"");
1010  AppendOutput("\"");
1011  AppendOutput(col->GetName());
1012  AppendOutput("\",", "\"arr\"");
1014 
1015  // collection treated as JS Array and its reference kept in the objects map
1016  AppendOutput("["); // fJsonrCnt++; // account array of objects
1017 
1018  bool islist = col->InheritsFrom(TList::Class());
1019  TString sopt;
1020  sopt.Capacity(500);
1021  sopt = "[";
1022 
1023  TIter iter(col);
1024  TObject *obj;
1025  Bool_t first = kTRUE;
1026  while ((obj = iter()) != 0) {
1027  if (!first) {
1029  sopt.Append(fArraySepar.Data());
1030  }
1031  if (islist) {
1032  sopt.Append("\"");
1033  sopt.Append(iter.GetOption());
1034  sopt.Append("\"");
1035  }
1036 
1038 
1039  first = kFALSE;
1040  }
1041 
1042  sopt.Append("]");
1043 
1044  AppendOutput("]");
1045 
1046  if (islist) {
1047  AppendOutput(",", "\"opt\"");
1049  AppendOutput(sopt.Data());
1050  /* fJsonrCnt++; */ // account array of options
1051  }
1052  fValue.Clear();
1053 }
1054 
1055 
1056 ////////////////////////////////////////////////////////////////////////////////
1057 /// Function is called from TStreamerInfo WriteBuffer and ReadBuffer functions
1058 /// and indent new level in json structure.
1059 /// This call indicates, that TStreamerInfo functions starts streaming
1060 /// object data of correspondent class
1061 
1063 {
1064  if (gDebug > 2)
1065  Info("IncrementLevel", "Class: %s", (info ? info->GetClass()->GetName() : "custom"));
1066 
1067  WorkWithClass((TStreamerInfo *)info);
1068 }
1069 
1070 ////////////////////////////////////////////////////////////////////////////////
1071 /// Prepares buffer to stream data of specified class
1072 
1074 {
1076 
1077  if (sinfo != 0) cl = sinfo->GetClass();
1078 
1079  if (cl == 0) return;
1080 
1081  if (gDebug > 3) Info("WorkWithClass", "Class: %s", cl->GetName());
1082 
1083  TJSONStackObj *stack = Stack();
1084 
1085  if ((stack != 0) && stack->IsStreamerElement() && !stack->fIsObjStarted &&
1086  ((stack->fElem->GetType() == TStreamerInfo::kObject) ||
1087  (stack->fElem->GetType() == TStreamerInfo::kAny))) {
1088 
1089  stack->fIsObjStarted = kTRUE;
1090 
1091  fJsonrCnt++; // count object, but do not keep reference
1092 
1093  stack = PushStack(2);
1094  AppendOutput("{", "\"_typename\"");
1096  AppendOutput("\"");
1097  AppendOutput(cl->GetName());
1098  AppendOutput("\"");
1099  } else {
1100  stack = PushStack(0);
1101  }
1102 
1103  stack->fInfo = sinfo;
1104  stack->fIsStreamerInfo = kTRUE;
1105 }
1106 
1107 ////////////////////////////////////////////////////////////////////////////////
1108 /// Function is called from TStreamerInfo WriteBuffer and ReadBuffer functions
1109 /// and decrease level in json structure.
1110 
1112 {
1114 
1115  if (gDebug > 2)
1116  Info("DecrementLevel", "Class: %s",
1117  (info ? info->GetClass()->GetName() : "custom"));
1118 
1119  TJSONStackObj *stack = Stack();
1120 
1121  if (stack->IsStreamerElement()) {
1122  if (gDebug > 3)
1123  Info("DecrementLevel", " Perform post-processing elem: %s",
1124  stack->fElem->GetName());
1125 
1126  PerformPostProcessing(stack);
1127 
1128  stack = PopStack(); // remove stack of last element
1129  }
1130 
1131  if (stack->fInfo != (TStreamerInfo *) info)
1132  Error("DecrementLevel", " Mismatch of streamer info");
1133 
1134  PopStack(); // back from data of stack info
1135 
1136  if (gDebug > 3)
1137  Info("DecrementLevel", "Class: %s done",
1138  (info ? info->GetClass()->GetName() : "custom"));
1139 }
1140 
1141 ////////////////////////////////////////////////////////////////////////////////
1142 /// Function is called from TStreamerInfo WriteBuffer and Readbuffer functions
1143 /// and add/verify next element of json structure
1144 /// This calls allows separate data, correspondent to one class member, from another
1145 
1147 {
1148  if (gDebug > 3)
1149  Info("SetStreamerElementNumber", "Element name %s", elem->GetName());
1150 
1151  WorkWithElement(elem, comp_type);
1152 }
1153 
1154 ////////////////////////////////////////////////////////////////////////////////
1155 /// This is call-back from streamer which indicates
1156 /// that class member will be streamed
1157 /// Name of element used in JSON
1158 
1160 {
1162 
1163  TJSONStackObj *stack = Stack();
1164  if (stack == 0) {
1165  Error("WorkWithElement", "stack is empty");
1166  return;
1167  }
1168 
1169  if (gDebug > 0)
1170  Info("WorkWithElement", " Start element %s type %d typename %s",
1171  elem ? elem->GetName() : "---", elem ? elem->GetType() : -1, elem ? elem->GetTypeName() : "---");
1172 
1173  if (stack->IsStreamerElement()) {
1174  // this is post processing
1175 
1176  if (gDebug > 3)
1177  Info("WorkWithElement", " Perform post-processing elem: %s",
1178  stack->fElem->GetName());
1179 
1180  PerformPostProcessing(stack);
1181 
1182  stack = PopStack(); // go level back
1183  }
1184 
1185  fValue.Clear();
1186 
1187  if (stack == 0) {
1188  Error("WorkWithElement", "Lost of stack");
1189  return;
1190  }
1191 
1192  TStreamerInfo *info = stack->fInfo;
1193  if (!stack->IsStreamerInfo()) {
1194  Error("WorkWithElement", "Problem in Inc/Dec level");
1195  return;
1196  }
1197 
1198  Int_t number = info ? info->GetElements()->IndexOf(elem) : -1;
1199 
1200  if (elem == 0) {
1201  Error("WorkWithElement", "streamer info returns elem = 0");
1202  return;
1203  }
1204 
1205  Bool_t isBasicType = (elem->GetType() > 0) && (elem->GetType() < 20);
1206 
1207  fExpectedChain = isBasicType && (comp_type - elem->GetType() == TStreamerInfo::kOffsetL);
1208 
1209  if (fExpectedChain && (gDebug > 3))
1210  Info("WorkWithElement", " Expects chain for elem %s number %d",
1211  elem->GetName(), number);
1212 
1213  TClass *base_class = elem->IsBase() ? elem->GetClassPointer() : 0;
1214 
1215  stack = PushStack(0);
1216  stack->fElem = (TStreamerElement *) elem;
1217  stack->fElemNumber = number;
1218  stack->fIsElemOwner = (number < 0);
1219 
1220  JsonStartElement(elem, base_class);
1221 }
1222 
1223 ////////////////////////////////////////////////////////////////////////////////
1224 /// Should be called in the beginning of custom class streamer.
1225 /// Informs buffer data about class which will be streamed now.
1226 ///
1227 /// ClassBegin(), ClassEnd() and ClassMemeber() should be used in
1228 /// custom class streamers to specify which kind of data are
1229 /// now streamed. Such information is used to correctly
1230 /// convert class data to JSON. Without that functions calls
1231 /// classes with custom streamers cannot be used with TBufferJSON
1232 
1234 {
1235  WorkWithClass(0, cl);
1236 }
1237 
1238 ////////////////////////////////////////////////////////////////////////////////
1239 /// Should be called at the end of custom streamer
1240 /// See TBufferJSON::ClassBegin for more details
1241 
1243 {
1244  DecrementLevel(0);
1245 }
1246 
1247 ////////////////////////////////////////////////////////////////////////////////
1248 /// Method indicates name and typename of class member,
1249 /// which should be now streamed in custom streamer
1250 /// Following combinations are supported:
1251 /// 1. name = "ClassName", typeName = 0 or typename==ClassName
1252 /// This is a case, when data of parent class "ClassName" should be streamed.
1253 /// For instance, if class directly inherited from TObject, custom
1254 /// streamer should include following code:
1255 /// b.ClassMember("TObject");
1256 /// TObject::Streamer(b);
1257 /// 2. Basic data type
1258 /// b.ClassMember("fInt","Int_t");
1259 /// b >> fInt;
1260 /// 3. Array of basic data types
1261 /// b.ClassMember("fArr","Int_t", 5);
1262 /// b.ReadFastArray(fArr, 5);
1263 /// 4. Object as data member
1264 /// b.ClassMemeber("fName","TString");
1265 /// fName.Streamer(b);
1266 /// 5. Pointer on object as data member
1267 /// b.ClassMemeber("fObj","TObject*");
1268 /// b.StreamObject(fObj);
1269 /// arrsize1 and arrsize2 arguments (when specified) indicate first and
1270 /// second dimension of array. Can be used for array of basic types.
1271 /// See ClassBegin() method for more details.
1272 
1273 void TBufferJSON::ClassMember(const char *name, const char *typeName,
1274  Int_t arrsize1, Int_t arrsize2)
1275 {
1276  if (typeName == 0) typeName = name;
1277 
1278  if ((name == 0) || (strlen(name) == 0)) {
1279  Error("ClassMember", "Invalid member name");
1280  return;
1281  }
1282 
1283  TString tname = typeName;
1284 
1285  Int_t typ_id = -1;
1286 
1287  if (strcmp(typeName, "raw:data") == 0)
1288  typ_id = TStreamerInfo::kMissing;
1289 
1290  if (typ_id < 0) {
1291  TDataType *dt = gROOT->GetType(typeName);
1292  if (dt != 0)
1293  if ((dt->GetType() > 0) && (dt->GetType() < 20))
1294  typ_id = dt->GetType();
1295  }
1296 
1297  if (typ_id < 0)
1298  if (strcmp(name, typeName) == 0) {
1299  TClass *cl = TClass::GetClass(tname.Data());
1300  if (cl != 0) typ_id = TStreamerInfo::kBase;
1301  }
1302 
1303  if (typ_id < 0) {
1304  Bool_t isptr = kFALSE;
1305  if (tname[tname.Length() - 1] == '*') {
1306  tname.Resize(tname.Length() - 1);
1307  isptr = kTRUE;
1308  }
1309  TClass *cl = TClass::GetClass(tname.Data());
1310  if (cl == 0) {
1311  Error("ClassMember", "Invalid class specifier %s", typeName);
1312  return;
1313  }
1314 
1315  if (cl->IsTObject())
1317  else
1318  typ_id = isptr ? TStreamerInfo::kAnyp : TStreamerInfo::kAny;
1319 
1320  if ((cl == TString::Class()) && !isptr)
1321  typ_id = TStreamerInfo::kTString;
1322  }
1323 
1324  TStreamerElement *elem = 0;
1325 
1326  if (typ_id == TStreamerInfo::kMissing) {
1327  elem = new TStreamerElement(name, "title", 0, typ_id, "raw:data");
1328  } else if (typ_id == TStreamerInfo::kBase) {
1329  TClass *cl = TClass::GetClass(tname.Data());
1330  if (cl != 0) {
1331  TStreamerBase *b = new TStreamerBase(tname.Data(), "title", 0);
1332  b->SetBaseVersion(cl->GetClassVersion());
1333  elem = b;
1334  }
1335  } else if ((typ_id > 0) && (typ_id < 20)) {
1336  elem = new TStreamerBasicType(name, "title", 0, typ_id, typeName);
1337  } else if ((typ_id == TStreamerInfo::kObject) ||
1338  (typ_id == TStreamerInfo::kTObject) ||
1339  (typ_id == TStreamerInfo::kTNamed)) {
1340  elem = new TStreamerObject(name, "title", 0, tname.Data());
1341  } else if (typ_id == TStreamerInfo::kObjectp) {
1342  elem = new TStreamerObjectPointer(name, "title", 0, tname.Data());
1343  } else if (typ_id == TStreamerInfo::kAny) {
1344  elem = new TStreamerObjectAny(name, "title", 0, tname.Data());
1345  } else if (typ_id == TStreamerInfo::kAnyp) {
1346  elem = new TStreamerObjectAnyPointer(name, "title", 0, tname.Data());
1347  } else if (typ_id == TStreamerInfo::kTString) {
1348  elem = new TStreamerString(name, "title", 0);
1349  }
1350 
1351  if (elem == 0) {
1352  Error("ClassMember", "Invalid combination name = %s type = %s",
1353  name, typeName);
1354  return;
1355  }
1356 
1357  if (arrsize1 > 0) {
1358  elem->SetArrayDim(arrsize2 > 0 ? 2 : 1);
1359  elem->SetMaxIndex(0, arrsize1);
1360  if (arrsize2 > 0)
1361  elem->SetMaxIndex(1, arrsize2);
1362  }
1363 
1364  // we indicate that there is no streamerinfo
1365  WorkWithElement(elem, -1);
1366 }
1367 
1368 ////////////////////////////////////////////////////////////////////////////////
1369 /// Function is converts TObject and TString structures to more compact representation
1370 
1371 void TBufferJSON::PerformPostProcessing(TJSONStackObj *stack,
1372  const TStreamerElement *elem)
1373 {
1374  if ((elem == 0) && stack->fIsPostProcessed) return;
1375  if (elem == 0) elem = stack->fElem;
1376  if (elem == 0) return;
1377 
1378  if (gDebug > 3)
1379  Info("PerformPostProcessing", "Element %s type %s",
1380  elem->GetName(), elem->GetTypeName());
1381 
1382  stack->fIsPostProcessed = kTRUE;
1383 
1384  // when element was written as separate object, close only braces and exit
1385  if (stack->fIsObjStarted) {
1386  AppendOutput("", "}");
1387  return;
1388  }
1389 
1390  const char *typname = elem->IsBase() ? elem->GetName() : elem->GetTypeName();
1391  Bool_t isTObject = (elem->GetType() == TStreamerInfo::kTObject) || (strcmp("TObject", typname) == 0);
1392  Bool_t isTString = elem->GetType() == TStreamerInfo::kTString;
1393  Bool_t isSTLstring = elem->GetType() == TStreamerInfo::kSTLstring;
1394  Bool_t isOffsetPArray = (elem->GetType() > TStreamerInfo::kOffsetP) && (elem->GetType() < TStreamerInfo::kOffsetP + 20);
1395 
1396  Bool_t isTArray = (strncmp("TArray", typname, 6) == 0);
1397 
1398  if (isTString || isSTLstring) {
1399  // just remove all kind of string length information
1400 
1401  if (gDebug > 3)
1402  Info("PerformPostProcessing", "reformat string value = '%s'", fValue.Data());
1403 
1404  stack->fValues.Delete();
1405  } else if (isOffsetPArray) {
1406  // basic array with [fN] comment
1407 
1408  if ((stack->fValues.GetLast() < 0) && (fValue == "0")) {
1409  fValue = "[]";
1410  } else if ((stack->fValues.GetLast() == 0) &&
1411  (strcmp(stack->fValues.Last()->GetName(), "1") == 0)) {
1412  stack->fValues.Delete();
1413  } else {
1414  Error("PerformPostProcessing", "Wrong values for kOffsetP type %s name %s",
1415  typname, (elem ? elem->GetName() : "---"));
1416  stack->fValues.Delete();
1417  fValue = "[]";
1418  }
1419  } else if (isTObject) {
1420  if (stack->fValues.GetLast() != 0) {
1421  if (gDebug > 0)
1422  Error("PerformPostProcessing", "When storing TObject, number of items %d not equal to 2", stack->fValues.GetLast());
1423  AppendOutput(",", "\"dummy\"");
1425  } else {
1426  AppendOutput(",", "\"fUniqueID\"");
1428  AppendOutput(stack->fValues.At(0)->GetName());
1429  AppendOutput(",", "\"fBits\"");
1431  }
1432 
1433  stack->fValues.Delete();
1434  } else if (isTArray) {
1435  // for TArray one deletes complete stack
1436  stack->fValues.Delete();
1437  }
1438 
1439  if (elem->IsBase() && (fValue.Length() == 0)) {
1440  // here base class data already completely stored
1441  return;
1442  }
1443 
1444  if (stack->fValues.GetLast() >= 0) {
1445  // append element blob data just as abstract array, user is responsible to decode it
1446  AppendOutput("[");
1447  for (Int_t n = 0; n <= stack->fValues.GetLast(); n++) {
1448  AppendOutput(stack->fValues.At(n)->GetName());
1450  }
1451  }
1452 
1453  if (fValue.Length() == 0) {
1454  AppendOutput("null");
1455  } else {
1457  fValue.Clear();
1458  }
1459 
1460  if (stack->fValues.GetLast() >= 0)
1461  AppendOutput("]");
1462 }
1463 
1464 ////////////////////////////////////////////////////////////////////////////////
1465 /// suppressed function of TBuffer
1466 
1468 {
1469  return 0;
1470 }
1471 
1472 ////////////////////////////////////////////////////////////////////////////////
1473 /// suppressed function of TBuffer
1474 
1476 {
1477 }
1478 
1479 ////////////////////////////////////////////////////////////////////////////////
1480 /// suppressed function of TBuffer
1481 
1483  const TClass * /*cl*/)
1484 {
1485  return 0;
1486 }
1487 
1488 ////////////////////////////////////////////////////////////////////////////////
1489 /// suppressed function of TBuffer
1490 
1492 {
1493  return 0;
1494 }
1495 
1496 ////////////////////////////////////////////////////////////////////////////////
1497 /// suppressed function of TBuffer
1498 
1500 {
1501 }
1502 
1503 ////////////////////////////////////////////////////////////////////////////////
1504 /// Skip class version from I/O buffer.
1505 
1507 {
1508  ReadVersion(0, 0, cl);
1509 }
1510 
1511 ////////////////////////////////////////////////////////////////////////////////
1512 /// read version value from buffer
1513 
1515  const TClass * /*cl*/)
1516 {
1517  Version_t res = 0;
1518 
1519  if (start) *start = 0;
1520  if (bcnt) *bcnt = 0;
1521 
1522  if (gDebug > 3) Info("ReadVersion", "Version = %d", res);
1523 
1524  return res;
1525 }
1526 
1527 ////////////////////////////////////////////////////////////////////////////////
1528 /// Ignored in TBufferJSON
1529 
1530 UInt_t TBufferJSON::WriteVersion(const TClass * /*cl*/, Bool_t /* useBcnt */)
1531 {
1532  return 0;
1533 }
1534 
1535 ////////////////////////////////////////////////////////////////////////////////
1536 /// Read object from buffer. Only used from TBuffer
1537 
1539 {
1540  return 0;
1541 }
1542 
1543 ////////////////////////////////////////////////////////////////////////////////
1544 /// Skip any kind of object from buffer
1545 
1547 {
1548 }
1549 
1550 ////////////////////////////////////////////////////////////////////////////////
1551 /// Write object to buffer. Only used from TBuffer
1552 
1553 void TBufferJSON::WriteObjectClass(const void *actualObjStart,
1554  const TClass *actualClass)
1555 {
1556  if (gDebug > 3)
1557  Info("WriteObjectClass", "Class %s", (actualClass ? actualClass->GetName() : " null"));
1558 
1559  JsonWriteObject(actualObjStart, actualClass);
1560 }
1561 
1562 #define TJSONPushValue() \
1563  if (fValue.Length() > 0) Stack()->PushValue(fValue);
1564 
1565 
1566 // macro to read array, which include size attribute
1567 #define TBufferJSON_ReadArray(tname, vname) \
1568  { \
1569  if (!vname) return 0; \
1570  return 1; \
1571  }
1572 
1573 ////////////////////////////////////////////////////////////////////////////////
1574 /// read a Float16_t from the buffer
1575 
1577 {
1578 }
1579 
1580 ////////////////////////////////////////////////////////////////////////////////
1581 /// read a Double32_t from the buffer
1582 
1584 {
1585 }
1586 
1587 ////////////////////////////////////////////////////////////////////////////////
1588 /// Read a Double32_t from the buffer when the factor and minimun value have
1589 /// been specified
1590 /// see comments about Double32_t encoding at TBufferFile::WriteDouble32().
1591 /// Currently TBufferJSON does not optimize space in this case.
1592 
1594  Double_t /* minvalue */)
1595 {
1596 }
1597 
1598 ////////////////////////////////////////////////////////////////////////////////
1599 /// Read a Float16_t from the buffer when the number of bits is specified
1600 /// (explicitly or not)
1601 /// see comments about Float16_t encoding at TBufferFile::WriteFloat16().
1602 /// Currently TBufferJSON does not optimize space in this case.
1603 
1605 {
1606 }
1607 
1608 ////////////////////////////////////////////////////////////////////////////////
1609 /// Read a Double32_t from the buffer when the factor and minimun value have
1610 /// been specified
1611 /// see comments about Double32_t encoding at TBufferFile::WriteDouble32().
1612 /// Currently TBufferJSON does not optimize space in this case.
1613 
1615  Double_t /* minvalue */)
1616 {
1617 }
1618 
1619 ////////////////////////////////////////////////////////////////////////////////
1620 /// Read a Double32_t from the buffer when the number of bits is specified
1621 /// (explicitly or not)
1622 /// see comments about Double32_t encoding at TBufferFile::WriteDouble32().
1623 /// Currently TBufferJSON does not optimize space in this case.
1624 
1626 {
1627 }
1628 
1629 ////////////////////////////////////////////////////////////////////////////////
1630 /// write a Float16_t to the buffer
1631 
1633 {
1634  TJSONPushValue();
1635 
1636  JsonWriteBasic(*f);
1637 }
1638 
1639 ////////////////////////////////////////////////////////////////////////////////
1640 /// write a Double32_t to the buffer
1641 
1643 {
1644  TJSONPushValue();
1645 
1646  JsonWriteBasic(*d);
1647 }
1648 
1649 ////////////////////////////////////////////////////////////////////////////////
1650 /// Read array of Bool_t from buffer
1651 
1653 {
1655 }
1656 
1657 ////////////////////////////////////////////////////////////////////////////////
1658 /// Read array of Char_t from buffer
1659 
1661 {
1663 }
1664 
1665 ////////////////////////////////////////////////////////////////////////////////
1666 /// Read array of UChar_t from buffer
1667 
1669 {
1671 }
1672 
1673 ////////////////////////////////////////////////////////////////////////////////
1674 /// Read array of Short_t from buffer
1675 
1677 {
1679 }
1680 
1681 ////////////////////////////////////////////////////////////////////////////////
1682 /// Read array of UShort_t from buffer
1683 
1685 {
1687 }
1688 
1689 ////////////////////////////////////////////////////////////////////////////////
1690 /// Read array of Int_t from buffer
1691 
1693 {
1695 }
1696 
1697 ////////////////////////////////////////////////////////////////////////////////
1698 /// Read array of UInt_t from buffer
1699 
1701 {
1703 }
1704 
1705 ////////////////////////////////////////////////////////////////////////////////
1706 /// Read array of Long_t from buffer
1707 
1709 {
1711 }
1712 
1713 ////////////////////////////////////////////////////////////////////////////////
1714 /// Read array of ULong_t from buffer
1715 
1717 {
1719 }
1720 
1721 ////////////////////////////////////////////////////////////////////////////////
1722 /// Read array of Long64_t from buffer
1723 
1725 {
1727 }
1728 
1729 ////////////////////////////////////////////////////////////////////////////////
1730 /// Read array of ULong64_t from buffer
1731 
1733 {
1735 }
1736 
1737 ////////////////////////////////////////////////////////////////////////////////
1738 /// Read array of Float_t from buffer
1739 
1741 {
1743 }
1744 
1745 ////////////////////////////////////////////////////////////////////////////////
1746 /// Read array of Double_t from buffer
1747 
1749 {
1751 }
1752 
1753 ////////////////////////////////////////////////////////////////////////////////
1754 /// Read array of Float16_t from buffer
1755 
1757 {
1759 }
1760 
1761 ////////////////////////////////////////////////////////////////////////////////
1762 /// Read array of Double32_t from buffer
1763 
1765 {
1767 }
1768 
1769 // dummy macro to read array from json buffer
1770 #define TBufferJSON_ReadStaticArray(vname) \
1771  { \
1772  if (!vname) return 0; \
1773  return 1; \
1774  }
1775 
1776 ////////////////////////////////////////////////////////////////////////////////
1777 /// Read array of Bool_t from buffer
1778 
1780 {
1782 }
1783 
1784 ////////////////////////////////////////////////////////////////////////////////
1785 /// Read array of Char_t from buffer
1786 
1788 {
1790 }
1791 
1792 ////////////////////////////////////////////////////////////////////////////////
1793 /// Read array of UChar_t from buffer
1794 
1796 {
1798 }
1799 
1800 ////////////////////////////////////////////////////////////////////////////////
1801 /// Read array of Short_t from buffer
1802 
1804 {
1806 }
1807 
1808 ////////////////////////////////////////////////////////////////////////////////
1809 /// Read array of UShort_t from buffer
1810 
1812 {
1814 }
1815 
1816 ////////////////////////////////////////////////////////////////////////////////
1817 /// Read array of Int_t from buffer
1818 
1820 {
1822 }
1823 
1824 ////////////////////////////////////////////////////////////////////////////////
1825 /// Read array of UInt_t from buffer
1826 
1828 {
1830 }
1831 
1832 ////////////////////////////////////////////////////////////////////////////////
1833 /// Read array of Long_t from buffer
1834 
1836 {
1838 }
1839 
1840 ////////////////////////////////////////////////////////////////////////////////
1841 /// Read array of ULong_t from buffer
1842 
1844 {
1846 }
1847 
1848 ////////////////////////////////////////////////////////////////////////////////
1849 /// Read array of Long64_t from buffer
1850 
1852 {
1854 }
1855 
1856 ////////////////////////////////////////////////////////////////////////////////
1857 /// Read array of ULong64_t from buffer
1858 
1860 {
1862 }
1863 
1864 ////////////////////////////////////////////////////////////////////////////////
1865 /// Read array of Float_t from buffer
1866 
1868 {
1870 }
1871 
1872 ////////////////////////////////////////////////////////////////////////////////
1873 /// Read array of Double_t from buffer
1874 
1876 {
1878 }
1879 
1880 ////////////////////////////////////////////////////////////////////////////////
1881 /// Read array of Float16_t from buffer
1882 
1884 {
1886 }
1887 
1888 ////////////////////////////////////////////////////////////////////////////////
1889 /// Read array of Double32_t from buffer
1890 
1892 {
1894 }
1895 
1896 // macro to read content of array, which not include size of array
1897 // macro also treat situation, when instead of one single array chain
1898 // of several elements should be produced
1899 #define TBufferJSON_ReadFastArray(vname) \
1900  { \
1901  if (n <= 0) return; \
1902  if (!vname) return; \
1903  }
1904 
1905 ////////////////////////////////////////////////////////////////////////////////
1906 /// read array of Bool_t from buffer
1907 
1909 {
1911 }
1912 
1913 ////////////////////////////////////////////////////////////////////////////////
1914 /// read array of Char_t from buffer
1915 
1917 {
1919 }
1920 
1921 ////////////////////////////////////////////////////////////////////////////////
1922 /// read array of Char_t from buffer
1923 
1925 {
1927 }
1928 
1929 ////////////////////////////////////////////////////////////////////////////////
1930 /// read array of UChar_t from buffer
1931 
1933 {
1935 }
1936 
1937 ////////////////////////////////////////////////////////////////////////////////
1938 /// read array of Short_t from buffer
1939 
1941 {
1943 }
1944 
1945 ////////////////////////////////////////////////////////////////////////////////
1946 /// read array of UShort_t from buffer
1947 
1949 {
1951 }
1952 
1953 ////////////////////////////////////////////////////////////////////////////////
1954 /// read array of Int_t from buffer
1955 
1957 {
1959 }
1960 
1961 ////////////////////////////////////////////////////////////////////////////////
1962 /// read array of UInt_t from buffer
1963 
1965 {
1967 }
1968 
1969 ////////////////////////////////////////////////////////////////////////////////
1970 /// read array of Long_t from buffer
1971 
1973 {
1975 }
1976 
1977 ////////////////////////////////////////////////////////////////////////////////
1978 /// read array of ULong_t from buffer
1979 
1981 {
1983 }
1984 
1985 ////////////////////////////////////////////////////////////////////////////////
1986 /// read array of Long64_t from buffer
1987 
1989 {
1991 }
1992 
1993 ////////////////////////////////////////////////////////////////////////////////
1994 /// read array of ULong64_t from buffer
1995 
1997 {
1999 }
2000 
2001 ////////////////////////////////////////////////////////////////////////////////
2002 /// read array of Float_t from buffer
2003 
2005 {
2007 }
2008 
2009 ////////////////////////////////////////////////////////////////////////////////
2010 /// read array of Double_t from buffer
2011 
2013 {
2015 }
2016 
2017 ////////////////////////////////////////////////////////////////////////////////
2018 /// read array of Float16_t from buffer
2019 
2021  TStreamerElement * /*ele*/)
2022 {
2024 }
2025 
2026 ////////////////////////////////////////////////////////////////////////////////
2027 /// read array of Float16_t from buffer
2028 
2030  Double_t /* factor */,
2031  Double_t /* minvalue */)
2032 {
2034 }
2035 
2036 ////////////////////////////////////////////////////////////////////////////////
2037 /// read array of Float16_t from buffer
2038 
2040 {
2042 }
2043 
2044 ////////////////////////////////////////////////////////////////////////////////
2045 /// read array of Double32_t from buffer
2046 
2048  TStreamerElement * /*ele*/)
2049 {
2051 }
2052 
2053 ////////////////////////////////////////////////////////////////////////////////
2054 /// read array of Double32_t from buffer
2055 
2057  Double_t /* factor */,
2058  Double_t /* minvalue */)
2059 {
2061 }
2062 
2063 ////////////////////////////////////////////////////////////////////////////////
2064 /// read array of Double32_t from buffer
2065 
2067 {
2069 }
2070 
2071 ////////////////////////////////////////////////////////////////////////////////
2072 /// redefined here to avoid warning message from gcc
2073 
2074 void TBufferJSON::ReadFastArray(void * /*start*/, const TClass * /*cl*/,
2075  Int_t /*n*/, TMemberStreamer * /*s*/,
2076  const TClass * /*onFileClass*/)
2077 {
2078 }
2079 
2080 ////////////////////////////////////////////////////////////////////////////////
2081 /// redefined here to avoid warning message from gcc
2082 
2083 void TBufferJSON::ReadFastArray(void ** /*startp*/, const TClass * /*cl*/,
2084  Int_t /*n*/, Bool_t /*isPreAlloc*/,
2085  TMemberStreamer * /*s*/,
2086  const TClass * /*onFileClass*/)
2087 {
2088 }
2089 
2090 
2091 #define TJSONWriteArrayContent(vname, arrsize) \
2092  { \
2093  fValue.Append("["); /* fJsonrCnt++; */ \
2094  for (Int_t indx=0;indx<arrsize;indx++) { \
2095  if (indx>0) fValue.Append(fArraySepar.Data()); \
2096  JsonWriteBasic(vname[indx]); \
2097  } \
2098  fValue.Append("]"); \
2099  }
2100 
2101 // macro to write array, which include size
2102 #define TBufferJSON_WriteArray(vname) \
2103  { \
2104  TJSONPushValue(); \
2105  TJSONWriteArrayContent(vname, n); \
2106  }
2107 
2108 ////////////////////////////////////////////////////////////////////////////////
2109 /// Write array of Bool_t to buffer
2110 
2112 {
2114 }
2115 
2116 ////////////////////////////////////////////////////////////////////////////////
2117 /// Write array of Char_t to buffer
2118 
2120 {
2122 }
2123 
2124 ////////////////////////////////////////////////////////////////////////////////
2125 /// Write array of UChar_t to buffer
2126 
2128 {
2130 }
2131 
2132 ////////////////////////////////////////////////////////////////////////////////
2133 /// Write array of Short_t to buffer
2134 
2136 {
2138 }
2139 
2140 ////////////////////////////////////////////////////////////////////////////////
2141 /// Write array of UShort_t to buffer
2142 
2144 {
2146 }
2147 
2148 ////////////////////////////////////////////////////////////////////////////////
2149 /// Write array of Int_ to buffer
2150 
2152 {
2154 }
2155 
2156 ////////////////////////////////////////////////////////////////////////////////
2157 /// Write array of UInt_t to buffer
2158 
2160 {
2162 }
2163 
2164 ////////////////////////////////////////////////////////////////////////////////
2165 /// Write array of Long_t to buffer
2166 
2168 {
2170 }
2171 
2172 ////////////////////////////////////////////////////////////////////////////////
2173 /// Write array of ULong_t to buffer
2174 
2176 {
2178 }
2179 
2180 ////////////////////////////////////////////////////////////////////////////////
2181 /// Write array of Long64_t to buffer
2182 
2184 {
2186 }
2187 
2188 ////////////////////////////////////////////////////////////////////////////////
2189 /// Write array of ULong64_t to buffer
2190 
2192 {
2194 }
2195 
2196 ////////////////////////////////////////////////////////////////////////////////
2197 /// Write array of Float_t to buffer
2198 
2200 {
2202 }
2203 
2204 ////////////////////////////////////////////////////////////////////////////////
2205 /// Write array of Double_t to buffer
2206 
2208 {
2210 }
2211 
2212 ////////////////////////////////////////////////////////////////////////////////
2213 /// Write array of Float16_t to buffer
2214 
2216  TStreamerElement * /*ele*/)
2217 {
2219 }
2220 
2221 ////////////////////////////////////////////////////////////////////////////////
2222 /// Write array of Double32_t to buffer
2223 
2225  TStreamerElement * /*ele*/)
2226 {
2228 }
2229 
2230 // write array without size attribute
2231 // macro also treat situation, when instead of one single array
2232 // chain of several elements should be produced
2233 #define TBufferJSON_WriteFastArray(vname) \
2234  { \
2235  TJSONPushValue(); \
2236  if (n <= 0) { /*fJsonrCnt++;*/ fValue.Append("[]"); return; } \
2237  TStreamerElement* elem = Stack(0)->fElem; \
2238  if ((elem != 0) && (elem->GetType()>TStreamerInfo::kOffsetL) && \
2239  (elem->GetType() < TStreamerInfo::kOffsetP) && \
2240  (elem->GetArrayLength() != n)) fExpectedChain = kTRUE; \
2241  if (fExpectedChain) { \
2242  TStreamerInfo* info = Stack(1)->fInfo; \
2243  Int_t startnumber = Stack(0)->fElemNumber; \
2244  fExpectedChain = kFALSE; \
2245  Int_t index(0); \
2246  while (index<n) { \
2247  elem = (TStreamerElement*)info->GetElements()->At(startnumber++);\
2248  if (index>0) JsonStartElement(elem); \
2249  if (elem->GetType()<TStreamerInfo::kOffsetL) { \
2250  JsonWriteBasic(vname[index]); \
2251  index++; \
2252  } else { \
2253  TJSONWriteArrayContent((vname+index), elem->GetArrayLength());\
2254  index+=elem->GetArrayLength(); \
2255  } \
2256  PerformPostProcessing(Stack(0), elem); \
2257  } \
2258  } else \
2259  if ((elem!=0) && (elem->GetArrayDim()>1) && (elem->GetArrayLength()==n)) { \
2260  TArrayI indexes(elem->GetArrayDim() - 1); \
2261  indexes.Reset(0); \
2262  Int_t cnt = 0; \
2263  while (cnt >= 0) { \
2264  if (indexes[cnt] >= elem->GetMaxIndex(cnt)) { \
2265  fValue.Append("]"); \
2266  indexes[cnt--] = 0; \
2267  if (cnt >= 0) indexes[cnt]++; \
2268  continue; \
2269  } \
2270  fValue.Append(indexes[cnt] == 0 ? "[" : fArraySepar.Data()); \
2271  if (++cnt == indexes.GetSize()) { \
2272  Int_t shift = 0; \
2273  for (Int_t k = 0; k < indexes.GetSize(); k++) \
2274  shift = shift * elem->GetMaxIndex(k) + indexes[k]; \
2275  Int_t len = elem->GetMaxIndex(indexes.GetSize()); \
2276  shift *= len; \
2277  TJSONWriteArrayContent((vname+shift), len); \
2278  indexes[--cnt]++; \
2279  } \
2280  } \
2281  } else { \
2282  TJSONWriteArrayContent(vname, n); \
2283  } \
2284  }
2285 
2286 ////////////////////////////////////////////////////////////////////////////////
2287 /// Write array of Bool_t to buffer
2288 
2290 {
2292 }
2293 
2294 ////////////////////////////////////////////////////////////////////////////////
2295 /// Write array of Char_t to buffer
2296 /// If array does not include any special characters,
2297 /// it will be reproduced as CharStar node with string as attribute
2298 
2300 {
2301  Bool_t asarray = fExpectedChain;
2302  if (Stack(0)->fElem != 0)
2303  if (Stack(0)->fElem->GetType() == TStreamerInfo::kOffsetP + TStreamerInfo::kChar) asarray = kTRUE;
2304 
2305  if (asarray) {
2307  } else {
2308  TJSONPushValue();
2309  JsonWriteConstChar(c, n);
2310  }
2311 }
2312 
2313 ////////////////////////////////////////////////////////////////////////////////
2314 /// Write array of Char_t to buffer
2315 
2317 {
2318  WriteFastArray(c, n);
2319 }
2320 
2321 
2322 ////////////////////////////////////////////////////////////////////////////////
2323 /// Write array of UChar_t to buffer
2324 
2326 {
2328 }
2329 
2330 ////////////////////////////////////////////////////////////////////////////////
2331 /// Write array of Short_t to buffer
2332 
2334 {
2336 }
2337 
2338 ////////////////////////////////////////////////////////////////////////////////
2339 /// Write array of UShort_t to buffer
2340 
2342 {
2344 }
2345 
2346 ////////////////////////////////////////////////////////////////////////////////
2347 /// Write array of Int_t to buffer
2348 
2350 {
2352 }
2353 
2354 ////////////////////////////////////////////////////////////////////////////////
2355 /// Write array of UInt_t to buffer
2356 
2358 {
2360 }
2361 
2362 ////////////////////////////////////////////////////////////////////////////////
2363 /// Write array of Long_t to buffer
2364 
2366 {
2368 }
2369 
2370 ////////////////////////////////////////////////////////////////////////////////
2371 /// Write array of ULong_t to buffer
2372 
2374 {
2376 }
2377 
2378 ////////////////////////////////////////////////////////////////////////////////
2379 /// Write array of Long64_t to buffer
2380 
2382 {
2384 }
2385 
2386 ////////////////////////////////////////////////////////////////////////////////
2387 /// Write array of ULong64_t to buffer
2388 
2390 {
2392 }
2393 
2394 ////////////////////////////////////////////////////////////////////////////////
2395 /// Write array of Float_t to buffer
2396 
2398 {
2400 }
2401 
2402 ////////////////////////////////////////////////////////////////////////////////
2403 /// Write array of Double_t to buffer
2404 
2406 {
2408 }
2409 
2410 ////////////////////////////////////////////////////////////////////////////////
2411 /// Write array of Float16_t to buffer
2412 
2414  TStreamerElement * /*ele*/)
2415 {
2417 }
2418 
2419 ////////////////////////////////////////////////////////////////////////////////
2420 /// Write array of Double32_t to buffer
2421 
2423  TStreamerElement * /*ele*/)
2424 {
2426 }
2427 
2428 ////////////////////////////////////////////////////////////////////////////////
2429 /// Recall TBuffer function to avoid gcc warning message
2430 
2431 void TBufferJSON::WriteFastArray(void *start, const TClass *cl, Int_t n,
2432  TMemberStreamer *streamer)
2433 {
2434  if (gDebug > 2)
2435  Info("WriteFastArray", "void *start cl %s n %d streamer %p",
2436  cl ? cl->GetName() : "---", n, streamer);
2437 
2438  if (streamer) {
2440  (*streamer)(*this, start, 0);
2441  return;
2442  }
2443 
2444  char *obj = (char *)start;
2445  if (!n) n = 1;
2446  int size = cl->Size();
2447 
2448  if (n > 1) {
2450  AppendOutput("[");
2451  /* fJsonrCnt++; */ // count array, but do not add to references
2452  }
2453 
2454  for (Int_t j = 0; j < n; j++, obj += size) {
2455  if (j > 0) AppendOutput(fArraySepar.Data());
2456 
2457  JsonWriteObject(obj, cl, kFALSE);
2458  }
2459 
2460  if (n > 1) {
2461  AppendOutput("]");
2462  }
2463 
2464 }
2465 
2466 ////////////////////////////////////////////////////////////////////////////////
2467 /// Recall TBuffer function to avoid gcc warning message
2468 
2470  Bool_t isPreAlloc, TMemberStreamer *streamer)
2471 {
2472  if (gDebug > 2)
2473  Info("WriteFastArray", "void **startp cl %s n %d streamer %p",
2474  cl->GetName(), n, streamer);
2475 
2476  if (streamer) {
2478  (*streamer)(*this, (void *)start, 0);
2479  return 0;
2480  }
2481 
2482  Int_t res = 0;
2483 
2484  if (n > 1) {
2486  AppendOutput("[");
2487  /* fJsonrCnt++; */ // count array, but do not add to references
2488  }
2489 
2490  if (!isPreAlloc) {
2491 
2492  for (Int_t j = 0; j < n; j++) {
2493  if (j > 0) AppendOutput(fArraySepar.Data());
2494  res |= WriteObjectAny(start[j], cl);
2495  }
2496 
2497  } else {
2498  //case //-> in comment
2499 
2500  for (Int_t j = 0; j < n; j++) {
2501  if (j > 0) AppendOutput(fArraySepar.Data());
2502 
2503  if (!start[j]) start[j] = ((TClass *)cl)->New();
2504  // ((TClass*)cl)->Streamer(start[j],*this);
2505  JsonWriteObject(start[j], cl, kFALSE);
2506  }
2507  }
2508 
2509  if (n > 1) {
2510  AppendOutput("]");
2511  }
2512 
2513  return res;
2514 }
2515 
2516 ////////////////////////////////////////////////////////////////////////////////
2517 /// stream object to/from buffer
2518 
2519 void TBufferJSON::StreamObject(void *obj, const std::type_info &typeinfo,
2520  const TClass * /* onFileClass */)
2521 {
2522  StreamObject(obj, TClass::GetClass(typeinfo));
2523 }
2524 
2525 ////////////////////////////////////////////////////////////////////////////////
2526 /// stream object to/from buffer
2527 
2528 void TBufferJSON::StreamObject(void *obj, const char *className,
2529  const TClass * /* onFileClass */)
2530 {
2531  StreamObject(obj, TClass::GetClass(className));
2532 }
2533 
2535 {
2536  // stream object to/from buffer
2537 
2538  StreamObject(obj, obj ? obj->IsA() : TObject::Class());
2539 }
2540 
2541 ////////////////////////////////////////////////////////////////////////////////
2542 /// stream object to/from buffer
2543 
2544 void TBufferJSON::StreamObject(void *obj, const TClass *cl,
2545  const TClass * /* onfileClass */)
2546 {
2547  if (gDebug > 3)
2548  Info("StreamObject", "Class: %s", (cl ? cl->GetName() : "none"));
2549 
2550  JsonWriteObject(obj, cl);
2551 }
2552 
2553 ////////////////////////////////////////////////////////////////////////////////
2554 /// Reads Bool_t value from buffer
2555 
2557 {
2558 }
2559 
2560 ////////////////////////////////////////////////////////////////////////////////
2561 /// Reads Char_t value from buffer
2562 
2564 {
2565 }
2566 
2567 ////////////////////////////////////////////////////////////////////////////////
2568 /// Reads UChar_t value from buffer
2569 
2571 {
2572 }
2573 
2574 ////////////////////////////////////////////////////////////////////////////////
2575 /// Reads Short_t value from buffer
2576 
2578 {
2579 }
2580 
2581 ////////////////////////////////////////////////////////////////////////////////
2582 /// Reads UShort_t value from buffer
2583 
2585 {
2586 }
2587 
2588 ////////////////////////////////////////////////////////////////////////////////
2589 /// Reads Int_t value from buffer
2590 
2592 {
2593 }
2594 
2595 ////////////////////////////////////////////////////////////////////////////////
2596 /// Reads UInt_t value from buffer
2597 
2599 {
2600 }
2601 
2602 ////////////////////////////////////////////////////////////////////////////////
2603 /// Reads Long_t value from buffer
2604 
2606 {
2607 }
2608 
2609 ////////////////////////////////////////////////////////////////////////////////
2610 /// Reads ULong_t value from buffer
2611 
2613 {
2614 }
2615 
2616 ////////////////////////////////////////////////////////////////////////////////
2617 /// Reads Long64_t value from buffer
2618 
2620 {
2621 }
2622 
2623 ////////////////////////////////////////////////////////////////////////////////
2624 /// Reads ULong64_t value from buffer
2625 
2627 {
2628 }
2629 
2630 ////////////////////////////////////////////////////////////////////////////////
2631 /// Reads Float_t value from buffer
2632 
2634 {
2635 }
2636 
2637 ////////////////////////////////////////////////////////////////////////////////
2638 /// Reads Double_t value from buffer
2639 
2641 {
2642 }
2643 
2644 ////////////////////////////////////////////////////////////////////////////////
2645 /// Reads array of characters from buffer
2646 
2648 {
2649 }
2650 
2651 ////////////////////////////////////////////////////////////////////////////////
2652 /// Reads a TString
2653 
2655 {
2656 }
2657 
2658 ////////////////////////////////////////////////////////////////////////////////
2659 /// Reads a std::string
2660 
2661 void TBufferJSON::ReadStdString(std::string */*s*/)
2662 {
2663 }
2664 
2665 ////////////////////////////////////////////////////////////////////////////////
2666 /// Writes Bool_t value to buffer
2667 
2669 {
2670  TJSONPushValue();
2671 
2672  JsonWriteBasic(b);
2673 }
2674 
2675 ////////////////////////////////////////////////////////////////////////////////
2676 /// Writes Char_t value to buffer
2677 
2679 {
2680  TJSONPushValue();
2681 
2682  JsonWriteBasic(c);
2683 }
2684 
2685 ////////////////////////////////////////////////////////////////////////////////
2686 /// Writes UChar_t value to buffer
2687 
2689 {
2690  TJSONPushValue();
2691 
2692  JsonWriteBasic(c);
2693 }
2694 
2695 ////////////////////////////////////////////////////////////////////////////////
2696 /// Writes Short_t value to buffer
2697 
2699 {
2700  TJSONPushValue();
2701 
2702  JsonWriteBasic(h);
2703 }
2704 
2705 ////////////////////////////////////////////////////////////////////////////////
2706 /// Writes UShort_t value to buffer
2707 
2709 {
2710  TJSONPushValue();
2711 
2712  JsonWriteBasic(h);
2713 }
2714 
2715 ////////////////////////////////////////////////////////////////////////////////
2716 /// Writes Int_t value to buffer
2717 
2719 {
2720  TJSONPushValue();
2721 
2722  JsonWriteBasic(i);
2723 }
2724 
2725 ////////////////////////////////////////////////////////////////////////////////
2726 /// Writes UInt_t value to buffer
2727 
2729 {
2730  TJSONPushValue();
2731 
2732  JsonWriteBasic(i);
2733 }
2734 
2735 ////////////////////////////////////////////////////////////////////////////////
2736 /// Writes Long_t value to buffer
2737 
2739 {
2740  TJSONPushValue();
2741 
2742  JsonWriteBasic(l);
2743 }
2744 
2745 ////////////////////////////////////////////////////////////////////////////////
2746 /// Writes ULong_t value to buffer
2747 
2749 {
2750  TJSONPushValue();
2751 
2752  JsonWriteBasic(l);
2753 }
2754 
2755 ////////////////////////////////////////////////////////////////////////////////
2756 /// Writes Long64_t value to buffer
2757 
2759 {
2760  TJSONPushValue();
2761 
2762  JsonWriteBasic(l);
2763 }
2764 
2765 ////////////////////////////////////////////////////////////////////////////////
2766 /// Writes ULong64_t value to buffer
2767 
2769 {
2770  TJSONPushValue();
2771 
2772  JsonWriteBasic(l);
2773 }
2774 
2775 ////////////////////////////////////////////////////////////////////////////////
2776 /// Writes Float_t value to buffer
2777 
2779 {
2780  TJSONPushValue();
2781 
2782  JsonWriteBasic(f);
2783 }
2784 
2785 ////////////////////////////////////////////////////////////////////////////////
2786 /// Writes Double_t value to buffer
2787 
2789 {
2790  TJSONPushValue();
2791 
2792  JsonWriteBasic(d);
2793 }
2794 
2795 ////////////////////////////////////////////////////////////////////////////////
2796 /// Writes array of characters to buffer
2797 
2799 {
2800  TJSONPushValue();
2801 
2802  JsonWriteConstChar(c);
2803 }
2804 
2805 ////////////////////////////////////////////////////////////////////////////////
2806 /// Writes a TString
2807 
2809 {
2810  TJSONPushValue();
2811 
2812  JsonWriteConstChar(s.Data(), s.Length());
2813 }
2814 
2815 ////////////////////////////////////////////////////////////////////////////////
2816 /// Writes a std::string
2817 
2818 void TBufferJSON::WriteStdString(const std::string *s)
2819 {
2820  TJSONPushValue();
2821 
2822  if (s) JsonWriteConstChar(s->c_str(), s->length());
2823  else JsonWriteConstChar("",0);
2824 
2825 }
2826 
2827 ////////////////////////////////////////////////////////////////////////////////
2828 /// converts Char_t to string and add to json value buffer
2829 
2831 {
2832  char buf[50];
2833  snprintf(buf, sizeof(buf), "%d", value);
2834  fValue.Append(buf);
2835 }
2836 
2837 ////////////////////////////////////////////////////////////////////////////////
2838 /// converts Short_t to string and add to json value buffer
2839 
2841 {
2842  char buf[50];
2843  snprintf(buf, sizeof(buf), "%hd", value);
2844  fValue.Append(buf);
2845 }
2846 
2847 ////////////////////////////////////////////////////////////////////////////////
2848 /// converts Int_t to string and add to json value buffer
2849 
2851 {
2852  char buf[50];
2853  snprintf(buf, sizeof(buf), "%d", value);
2854  fValue.Append(buf);
2855 }
2856 
2857 ////////////////////////////////////////////////////////////////////////////////
2858 /// converts Long_t to string and add to json value buffer
2859 
2861 {
2862  char buf[50];
2863  snprintf(buf, sizeof(buf), "%ld", value);
2864  fValue.Append(buf);
2865 }
2866 
2867 ////////////////////////////////////////////////////////////////////////////////
2868 /// converts Long64_t to string and add to json value buffer
2869 
2871 {
2872  char buf[50];
2873  snprintf(buf, sizeof(buf), FLong64, value);
2874  fValue.Append(buf);
2875 }
2876 
2877 ////////////////////////////////////////////////////////////////////////////////
2878 /// method compress float string, excluding exp and/or move float point
2879 /// 1.000000e-01 -> 0.1
2880 /// 3.750000e+00 -> 3.75
2881 /// 3.750000e-03 -> 0.00375
2882 /// 3.750000e-04 -> 3.75e-4
2883 /// 1.100000e-10 -> 1.1e-10
2884 
2885 void TBufferJSON::CompactFloatString(char* sbuf, unsigned len)
2886 {
2887  char* pnt = 0, *exp = 0, *lastdecimal = 0, *s = sbuf;
2888  bool negative_exp = false;
2889  int power = 0;
2890  while(*s && --len) {
2891  switch (*s) {
2892  case '.': pnt = s; break;
2893  case 'E':
2894  case 'e': exp = s; break;
2895  case '-': if (exp) negative_exp = true; break;
2896  case '+': break;
2897  default: // should be digits from '0' to '9'
2898  if ((*s <'0') || (*s >'9')) return;
2899  if (exp) power = power*10 + (*s - '0'); else
2900  if (pnt && *s!='0') lastdecimal = s;
2901  break;
2902  }
2903  ++s;
2904  }
2905  if (*s) return; // if end-of-string was not found
2906 
2907  if (!exp) {
2908  // value without exponent like 123.4569000
2909  if (pnt) {
2910  if (lastdecimal) *(lastdecimal+1) = 0;
2911  else *pnt = 0;
2912  }
2913  } else
2914  if (power==0) {
2915  if (lastdecimal) *(lastdecimal+1) = 0; else
2916  if (pnt) *pnt = 0;
2917  } else
2918  if (!negative_exp && pnt && exp && (exp-pnt > power)) {
2919  // this is case of value 1.23000e+02
2920  // we can move point and exclude exponent easily
2921  for (int cnt=0;cnt<power;++cnt) {
2922  char tmp = *pnt;
2923  *pnt = *(pnt+1);
2924  *(++pnt) = tmp;
2925  }
2926  if (lastdecimal && (pnt<lastdecimal)) *(lastdecimal+1) = 0;
2927  else *pnt = 0;
2928  } else
2929  if (negative_exp && pnt && exp && (power < (s-exp))) {
2930  // this is small negative exponent like 1.2300e-02
2931  if (!lastdecimal) lastdecimal = pnt;
2932  *(lastdecimal+1) = 0;
2933  // copy most significant digit on the point place
2934  *pnt = *(pnt-1);
2935 
2936  for (char* pos = lastdecimal+1; pos>=pnt; --pos)
2937  *(pos+power) = *pos;
2938  *(pnt-1) = '0';
2939  *pnt = '.';
2940  for (int cnt=1;cnt<power;++cnt)
2941  *(pnt+cnt) = '0';
2942  } else
2943  if (pnt && exp) {
2944  // keep exponent, but non-significant zeros
2945  if (lastdecimal) pnt = lastdecimal+1;
2946  // copy exponent sign
2947  *pnt++ = *exp++;
2948  if (*exp=='+') ++exp; else
2949  if (*exp=='-') *pnt++ = *exp++;
2950  // exclude zeros in the begin of exponent
2951  while (*exp=='0') ++exp;
2952  while (*exp) *pnt++ = *exp++;
2953  *pnt = 0;
2954  }
2955 }
2956 
2957 ////////////////////////////////////////////////////////////////////////////////
2958 /// converts Float_t to string and add to json value buffer
2959 
2961 {
2962  char buf[200];
2963  if (value == floor(value)) {
2964  snprintf(buf, sizeof(buf), "%1.0f", value);
2965  } else {
2966  snprintf(buf, sizeof(buf), fgFloatFmt, value);
2967  CompactFloatString(buf, sizeof(buf));
2968  }
2969  fValue.Append(buf);
2970 }
2971 
2972 ////////////////////////////////////////////////////////////////////////////////
2973 /// converts Double_t to string and add to json value buffer
2974 
2976 {
2977  char buf[200];
2978  if (value == floor(value)) {
2979  snprintf(buf, sizeof(buf), "%1.0f", value);
2980  } else {
2981  snprintf(buf, sizeof(buf), fgDoubleFmt, value);
2982  CompactFloatString(buf, sizeof(buf));
2983  }
2984  fValue.Append(buf);
2985 }
2986 
2987 ////////////////////////////////////////////////////////////////////////////////
2988 /// converts Bool_t to string and add to json value buffer
2989 
2991 {
2992  fValue.Append(value ? "true" : "false");
2993 }
2994 
2995 ////////////////////////////////////////////////////////////////////////////////
2996 /// converts UChar_t to string and add to json value buffer
2997 
2999 {
3000  char buf[50];
3001  snprintf(buf, sizeof(buf), "%u", value);
3002  fValue.Append(buf);
3003 }
3004 
3005 ////////////////////////////////////////////////////////////////////////////////
3006 /// converts UShort_t to string and add to json value buffer
3007 
3009 {
3010  char buf[50];
3011  snprintf(buf, sizeof(buf), "%hu", value);
3012  fValue.Append(buf);
3013 }
3014 
3015 ////////////////////////////////////////////////////////////////////////////////
3016 /// converts UInt_t to string and add to json value buffer
3017 
3019 {
3020  char buf[50];
3021  snprintf(buf, sizeof(buf), "%u", value);
3022  fValue.Append(buf);
3023 }
3024 
3025 ////////////////////////////////////////////////////////////////////////////////
3026 /// converts ULong_t to string and add to json value buffer
3027 
3029 {
3030  char buf[50];
3031  snprintf(buf, sizeof(buf), "%lu", value);
3032  fValue.Append(buf);
3033 }
3034 
3035 ////////////////////////////////////////////////////////////////////////////////
3036 /// converts ULong64_t to string and add to json value buffer
3037 
3039 {
3040  char buf[50];
3041  snprintf(buf, sizeof(buf), FULong64, value);
3042  fValue.Append(buf);
3043 }
3044 
3045 ////////////////////////////////////////////////////////////////////////////////
3046 /// writes string value, processing all kind of special characters
3047 
3048 void TBufferJSON::JsonWriteConstChar(const char* value, Int_t len)
3049 {
3050  fValue.Append("\"");
3051 
3052  if (value!=0) {
3053  if (len<0) len = strlen(value);
3054 
3055  for (Int_t n=0;n<len;n++) {
3056  char c = value[n];
3057  switch(c) {
3058  case '\n':
3059  fValue.Append("\\n");
3060  break;
3061  case '\t':
3062  fValue.Append("\\t");
3063  break;
3064  case '\"':
3065  fValue.Append("\\\"");
3066  break;
3067  case '\\':
3068  fValue.Append("\\\\");
3069  break;
3070  case '\b':
3071  fValue.Append("\\b");
3072  break;
3073  case '\f':
3074  fValue.Append("\\f");
3075  break;
3076  case '\r':
3077  fValue.Append("\\r");
3078  break;
3079  case '/':
3080  fValue.Append("\\/");
3081  break;
3082  default:
3083  if ((c > 31) && (c < 127))
3084  fValue.Append(c);
3085  else
3086  fValue.Append(TString::Format("\\u%04x", (unsigned) c));
3087  }
3088  }
3089  }
3090 
3091  fValue.Append("\"");
3092 }
3093 
3094 
3095 ////////////////////////////////////////////////////////////////////////////////
3096 /// set printf format for float/double members, default "%e"
3097 /// to change format only for doubles, use SetDoubleFormat
3098 
3099 void TBufferJSON::SetFloatFormat(const char *fmt)
3100 {
3101  if (fmt == 0) fmt = "%e";
3102  fgFloatFmt = fmt;
3103  fgDoubleFmt = fmt;
3104 }
3105 
3106 ////////////////////////////////////////////////////////////////////////////////
3107 /// return current printf format for float members, default "%e"
3108 
3110 {
3111  return fgFloatFmt;
3112 }
3113 
3114 ////////////////////////////////////////////////////////////////////////////////
3115 /// set printf format for double members, default "%.14e"
3116 /// use it after SetFloatFormat, which also overwrites format for doubles
3117 
3118 void TBufferJSON::SetDoubleFormat(const char *fmt)
3119 {
3120  if (fmt == 0) fmt = "%.14e";
3121  fgDoubleFmt = fmt;
3122 }
3123 
3124 ////////////////////////////////////////////////////////////////////////////////
3125 /// return current printf format for double members, default "%.14e"
3126 
3128 {
3129  return fgDoubleFmt;
3130 }
3131 
3132 ////////////////////////////////////////////////////////////////////////////////
3133 /// Read one collection of objects from the buffer using the StreamerInfoLoopAction.
3134 /// The collection needs to be a split TClonesArray or a split vector of pointers.
3135 
3137  void *obj)
3138 {
3139  TVirtualStreamerInfo *info = sequence.fStreamerInfo;
3140  IncrementLevel(info);
3141 
3142  if (gDebug) {
3143  //loop on all active members
3144  TStreamerInfoActions::ActionContainer_t::const_iterator end = sequence.fActions.end();
3145  for (TStreamerInfoActions::ActionContainer_t::const_iterator iter = sequence.fActions.begin();
3146  iter != end; ++iter) {
3147  // Idea: Try to remove this function call as it is really needed only for JSON streaming.
3148  SetStreamerElementNumber((*iter).fConfiguration->fCompInfo->fElem, (*iter).fConfiguration->fCompInfo->fType);
3149  (*iter).PrintDebug(*this, obj);
3150  (*iter)(*this, obj);
3151  }
3152  } else {
3153  //loop on all active members
3154  TStreamerInfoActions::ActionContainer_t::const_iterator end = sequence.fActions.end();
3155  for (TStreamerInfoActions::ActionContainer_t::const_iterator iter = sequence.fActions.begin();
3156  iter != end; ++iter) {
3157  // Idea: Try to remove this function call as it is really needed only for JSON streaming.
3158  SetStreamerElementNumber((*iter).fConfiguration->fCompInfo->fElem, (*iter).fConfiguration->fCompInfo->fType);
3159  (*iter)(*this, obj);
3160  }
3161  }
3162  DecrementLevel(info);
3163  return 0;
3164 }
3165 
3166 ////////////////////////////////////////////////////////////////////////////////
3167 /// Read one collection of objects from the buffer using the StreamerInfoLoopAction.
3168 /// The collection needs to be a split TClonesArray or a split vector of pointers.
3169 
3171  void *start_collection, void *end_collection)
3172 {
3173  TVirtualStreamerInfo *info = sequence.fStreamerInfo;
3174  IncrementLevel(info);
3175 
3176  if (gDebug) {
3177  //loop on all active members
3178  TStreamerInfoActions::ActionContainer_t::const_iterator end = sequence.fActions.end();
3179  for (TStreamerInfoActions::ActionContainer_t::const_iterator iter = sequence.fActions.begin();
3180  iter != end; ++iter) {
3181  // Idea: Try to remove this function call as it is really needed only for JSON streaming.
3182  SetStreamerElementNumber((*iter).fConfiguration->fCompInfo->fElem, (*iter).fConfiguration->fCompInfo->fType);
3183  (*iter).PrintDebug(*this, *(char **)start_collection); // Warning: This limits us to TClonesArray and vector of pointers.
3184  (*iter)(*this, start_collection, end_collection);
3185  }
3186  } else {
3187  //loop on all active members
3188  TStreamerInfoActions::ActionContainer_t::const_iterator end = sequence.fActions.end();
3189  for (TStreamerInfoActions::ActionContainer_t::const_iterator iter = sequence.fActions.begin();
3190  iter != end; ++iter) {
3191  // Idea: Try to remove this function call as it is really needed only for JSON streaming.
3192  SetStreamerElementNumber((*iter).fConfiguration->fCompInfo->fElem, (*iter).fConfiguration->fCompInfo->fType);
3193  (*iter)(*this, start_collection, end_collection);
3194  }
3195  }
3196  DecrementLevel(info);
3197  return 0;
3198 }
3199 
3200 ////////////////////////////////////////////////////////////////////////////////
3201 /// Read one collection of objects from the buffer using the StreamerInfoLoopAction.
3202 
3204  void *start_collection, void *end_collection)
3205 {
3206  TVirtualStreamerInfo *info = sequence.fStreamerInfo;
3207  IncrementLevel(info);
3208 
3210  if (gDebug) {
3211 
3212  // Get the address of the first item for the PrintDebug.
3213  // (Performance is not essential here since we are going to print to
3214  // the screen anyway).
3215  void *arr0 = loopconfig->GetFirstAddress(start_collection, end_collection);
3216  // loop on all active members
3217  TStreamerInfoActions::ActionContainer_t::const_iterator end = sequence.fActions.end();
3218  for (TStreamerInfoActions::ActionContainer_t::const_iterator iter = sequence.fActions.begin();
3219  iter != end; ++iter) {
3220  // Idea: Try to remove this function call as it is really needed only for JSON streaming.
3221  SetStreamerElementNumber((*iter).fConfiguration->fCompInfo->fElem, (*iter).fConfiguration->fCompInfo->fType);
3222  (*iter).PrintDebug(*this, arr0);
3223  (*iter)(*this, start_collection, end_collection, loopconfig);
3224  }
3225  } else {
3226  //loop on all active members
3227  TStreamerInfoActions::ActionContainer_t::const_iterator end = sequence.fActions.end();
3228  for (TStreamerInfoActions::ActionContainer_t::const_iterator iter = sequence.fActions.begin();
3229  iter != end; ++iter) {
3230  // Idea: Try to remove this function call as it is really needed only for JSON streaming.
3231  SetStreamerElementNumber((*iter).fConfiguration->fCompInfo->fElem, (*iter).fConfiguration->fCompInfo->fType);
3232  (*iter)(*this, start_collection, end_collection, loopconfig);
3233  }
3234  }
3235  DecrementLevel(info);
3236  return 0;
3237 }
3238 
3239 
3240 ////////////////////////////////////////////////////////////////////////////////
3241 /// Interface to TStreamerInfo::WriteBufferClones.
3242 
3244 {
3245  Info("WriteClones", "Not yet tested");
3246 
3247  if (a != 0)
3248  JsonStreamCollection(a, a->IsA());
3249 
3250  return 0;
3251 }
3252 
3253 namespace {
3254  struct DynamicType {
3255  // Helper class to enable typeid on any address
3256  // Used in code similar to:
3257  // typeid( * (DynamicType*) void_ptr );
3258  virtual ~DynamicType() {}
3259  };
3260 }
3261 
3262 ////////////////////////////////////////////////////////////////////////////////
3263 /// Write object to I/O buffer.
3264 /// This function assumes that the value in 'obj' is the value stored in
3265 /// a pointer to a "ptrClass". The actual type of the object pointed to
3266 /// can be any class derived from "ptrClass".
3267 /// Return:
3268 /// 0: failure
3269 /// 1: success
3270 /// 2: truncated success (i.e actual class is missing. Only ptrClass saved.)
3271 
3272 Int_t TBufferJSON::WriteObjectAny(const void *obj, const TClass *ptrClass)
3273 {
3274  if (!obj) {
3275  WriteObjectClass(0, 0);
3276  return 1;
3277  }
3278 
3279  if (!ptrClass) {
3280  Error("WriteObjectAny", "ptrClass argument may not be 0");
3281  return 0;
3282  }
3283 
3284  TClass *clActual = ptrClass->GetActualClass(obj);
3285 
3286  if (clActual == 0) {
3287  // The ptrClass is a class with a virtual table and we have no
3288  // TClass with the actual type_info in memory.
3289 
3290  DynamicType *d_ptr = (DynamicType *)obj;
3291  Warning("WriteObjectAny",
3292  "An object of type %s (from type_info) passed through a %s pointer was truncated (due a missing dictionary)!!!",
3293  typeid(*d_ptr).name(), ptrClass->GetName());
3294  WriteObjectClass(obj, ptrClass);
3295  return 2;
3296  } else if (clActual && (clActual != ptrClass)) {
3297  const char *temp = (const char *) obj;
3298  temp -= clActual->GetBaseClassOffset(ptrClass);
3299  WriteObjectClass(temp, clActual);
3300  return 1;
3301  } else {
3302  WriteObjectClass(obj, ptrClass);
3303  return 1;
3304  }
3305 }
3306 
3307 ////////////////////////////////////////////////////////////////////////////////
3308 /// Function called by the Streamer functions to serialize object at p
3309 /// to buffer b. The optional argument info may be specified to give an
3310 /// alternative StreamerInfo instead of using the default StreamerInfo
3311 /// automatically built from the class definition.
3312 /// For more information, see class TStreamerInfo.
3313 
3314 Int_t TBufferJSON::WriteClassBuffer(const TClass *cl, void *pointer)
3315 {
3316 
3317  //build the StreamerInfo if first time for the class
3318  TStreamerInfo *sinfo = (TStreamerInfo *)const_cast<TClass *>(cl)->GetCurrentStreamerInfo();
3319  if (sinfo == 0) {
3320  //Have to be sure between the check and the taking of the lock if the current streamer has changed
3322  sinfo = (TStreamerInfo *)const_cast<TClass *>(cl)->GetCurrentStreamerInfo();
3323  if (sinfo == 0) {
3324  const_cast<TClass *>(cl)->BuildRealData(pointer);
3325  sinfo = new TStreamerInfo(const_cast<TClass *>(cl));
3326  const_cast<TClass *>(cl)->SetCurrentStreamerInfo(sinfo);
3327  const_cast<TClass *>(cl)->RegisterStreamerInfo(sinfo);
3328  if (gDebug > 0)
3329  printf("Creating StreamerInfo for class: %s, version: %d\n",
3330  cl->GetName(), cl->GetClassVersion());
3331  sinfo->Build();
3332  }
3333  } else if (!sinfo->IsCompiled()) {
3335  // Redo the test in case we have been victim of a data race on fIsCompiled.
3336  if (!sinfo->IsCompiled()) {
3337  const_cast<TClass *>(cl)->BuildRealData(pointer);
3338  sinfo->BuildOld();
3339  }
3340  }
3341 
3342  //write the class version number and reserve space for the byte count
3343  // UInt_t R__c = WriteVersion(cl, kTRUE);
3344 
3345  //NOTE: In the future Philippe wants this to happen via a custom action
3346  TagStreamerInfo(sinfo);
3347  ApplySequence(*(sinfo->GetWriteObjectWiseActions()), (char *)pointer);
3348 
3349  //write the byte count at the start of the buffer
3350  // SetByteCount(R__c, kTRUE);
3351 
3352  if (gDebug > 2)
3353  Info("WriteClassBuffer", "class: %s version %d done", cl->GetName(), cl->GetClassVersion());
3354  return 0;
3355 }
Abstract array base class.
Definition: TArray.h:33
Describe Streamer information for one class version.
Definition: TStreamerInfo.h:47
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:51
virtual UInt_t WriteVersion(const TClass *cl, Bool_t useBcnt=kFALSE)
Ignored in TBufferJSON.
TStreamerInfoActions::TActionSequence * GetWriteObjectWiseActions()
Ssiz_t Capacity() const
Definition: TString.h:337
#define TJSONPushValue()
An array of TObjects.
Definition: TObjArray.h:39
TString JsonWriteMember(const void *ptr, TDataMember *member, TClass *memberClass, Int_t arraylen)
Convert single data member to JSON structures Returns string with converted member.
virtual void WriteUChar(UChar_t c)
Writes UChar_t value to buffer.
virtual void WriteArrayFloat16(const Float_t *f, Int_t n, TStreamerElement *ele=0)
Write array of Float16_t to buffer.
virtual void Info(const char *method, const char *msgfmt,...) const
Issue info message.
Definition: TObject.cxx:899
virtual Int_t WriteClones(TClonesArray *a, Int_t nobjects)
Interface to TStreamerInfo::WriteBufferClones.
void WorkWithElement(TStreamerElement *elem, Int_t comp_type)
This is call-back from streamer which indicates that class member will be streamed Name of element us...
virtual TClass * ReadClass(const TClass *cl=0, UInt_t *objTag=0)
suppressed function of TBuffer
virtual Int_t ReadStaticArray(Bool_t *b)
Read array of Bool_t from buffer.
long long Long64_t
Definition: RtypesCore.h:69
virtual Int_t ReadArray(Bool_t *&b)
Read array of Bool_t from buffer.
void JsonDisablePostprocessing()
virtual void ReadShort(Short_t &s)
Reads Short_t value from buffer.
virtual Int_t WriteObjectAny(const void *obj, const TClass *ptrClass)
Write object to I/O buffer.
virtual Int_t ReadStaticArrayFloat16(Float_t *f, TStreamerElement *ele=0)
Read array of Float16_t from buffer.
short Version_t
Definition: RtypesCore.h:61
virtual void WriteLong64(Long64_t l)
Writes Long64_t value to buffer.
#define TBufferJSON_ReadArray(tname, vname)
virtual TClass * GetClass() const =0
TLoopConfiguration * fLoopConfig
If this is a bundle of memberwise streaming action, this configures the looping.
#define TBufferJSON_WriteFastArray(vname)
Collectable string class.
Definition: TObjString.h:32
float Float_t
Definition: RtypesCore.h:53
virtual void ReadFloat(Float_t &f)
Reads Float_t value from buffer.
return c
virtual void ReadWithFactor(Float_t *ptr, Double_t factor, Double_t minvalue)
Read a Double32_t from the buffer when the factor and minimun value have been specified see comments ...
virtual void Delete(Option_t *option="")
Remove all objects from the array AND delete all heap based objects.
Definition: TObjArray.cxx:329
All ROOT classes may have RTTI (run time type identification) support added.
Definition: TDataMember.h:33
R__EXTERN TVirtualMutex * gInterpreterMutex
Definition: TInterpreter.h:46
virtual void ReadWithNbits(Float_t *ptr, Int_t nbits)
Read a Float16_t from the buffer when the number of bits is specified (explicitly or not) see comment...
TString fSemicolon
0 - no any compression, 1 - no spaces in the begin, 2 - no new lines, 3 - no spaces at all ...
Definition: TBufferJSON.h:468
virtual void SkipObjectAny()
Skip any kind of object from buffer.
unsigned short UShort_t
Definition: RtypesCore.h:36
virtual void ReadCharP(Char_t *c)
Reads array of characters from buffer.
virtual TClass * GetClassPointer() const
Returns a pointer to the TClass of this element.
virtual void SetOwner(Bool_t enable=kTRUE)
Set whether this collection is the owner (enable==true) of its content.
TH1 * h
Definition: legend2.C:5
virtual void DecrementLevel(TVirtualStreamerInfo *)
Function is called from TStreamerInfo WriteBuffer and ReadBuffer functions and decrease level in json...
TString fArraySepar
depending from compression level, " : " or ":"
Definition: TBufferJSON.h:469
virtual void ReadFastArrayWithFactor(Float_t *ptr, Int_t n, Double_t factor, Double_t minvalue)
read array of Float16_t from buffer
const char * GetTypeName() const
Get type of data member, e,g.: "class TDirectory*" -> "TDirectory".
virtual void ReadBool(Bool_t &b)
Reads Bool_t value from buffer.
Int_t fCompact
flag to resolve situation when several elements of same basic type stored as FastArray ...
Definition: TBufferJSON.h:467
virtual void WriteDouble(Double_t d)
Writes Double_t value to buffer.
virtual void ReadLong64(Long64_t &l)
Reads Long64_t value from buffer.
virtual void ReadStdString(std::string *s)
Reads a std::string.
Buffer base class used for serializing objects.
Definition: TBuffer.h:42
void JsonWriteBasic(Char_t value)
converts Char_t to string and add to json value buffer
#define gROOT
Definition: TROOT.h:364
virtual TObject * Remove(TObject *obj)
Remove object from array.
Definition: TObjArray.cxx:653
static void SetDoubleFormat(const char *fmt="%.14e")
set printf format for double members, default "%.14e" use it after SetFloatFormat, which also overwrites format for doubles
virtual void ReadFastArrayFloat16(Float_t *f, Int_t n, TStreamerElement *ele=0)
read array of Float16_t from buffer
virtual void WriteULong64(ULong64_t l)
Writes ULong64_t value to buffer.
Basic string class.
Definition: TString.h:137
Int_t JsonSpecialClass(const TClass *cl) const
return non-zero value when class has special handling in JSON it is TCollection (-130), TArray (100), TString (110), std::string (120) and STL containers (1..6)
virtual void ReadFastArray(Bool_t *b, Int_t n)
read array of Bool_t from buffer
int Int_t
Definition: RtypesCore.h:41
bool Bool_t
Definition: RtypesCore.h:59
TArc * a
Definition: textangle.C:12
const Bool_t kFALSE
Definition: Rtypes.h:92
static const char * fgDoubleFmt
printf argument for floats, either "%f" or "%e" or "%10f" and so on
Definition: TBufferJSON.h:473
virtual void ReadLong(Long_t &l)
Reads Long_t value from buffer.
virtual void WriteLong(Long_t l)
Writes Long_t value to buffer.
virtual Int_t ApplySequence(const TStreamerInfoActions::TActionSequence &sequence, void *object)
Read one collection of objects from the buffer using the StreamerInfoLoopAction.
void SetParent(TObject *parent)
Set parent owning this buffer.
Definition: TBuffer.cxx:239
Option_t * GetOption() const
Definition: TCollection.h:160
virtual void SetArrayDim(Int_t dim)
Set number of array dimensions.
TObject * At(Int_t idx) const
Definition: TObjArray.h:167
const char * Class
Definition: TXMLSetup.cxx:64
virtual void WriteFastArrayString(const Char_t *c, Int_t n)
Write array of Char_t to buffer.
virtual void SetMaxIndex(Int_t dim, Int_t max)
set maximum index for array with dimension dim
Array of integers (32 bits per element).
Definition: TArrayI.h:29
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
Definition: TObject.cxx:739
virtual void WriteInt(Int_t i)
Writes Int_t value to buffer.
virtual Int_t CheckByteCount(UInt_t startpos, UInt_t bcnt, const TClass *clss)
suppressed function of TBuffer
#define TBufferJSON_WriteArray(vname)
Int_t GetBaseClassOffset(const TClass *toBase, void *address=0, bool isDerivedObject=true)
Definition: TClass.cxx:2717
TObject * Last() const
Return the object in the last filled slot. Returns 0 if no entries.
Definition: TObjArray.cxx:479
virtual void ReadChar(Char_t &c)
Reads Char_t value from buffer.
#define FULong64
Definition: TBufferJSON.cxx:72
Bool_t IsBasic() const
Return true if data member is a basic type, e.g. char, int, long...
virtual void ReadFastArrayDouble32(Double_t *d, Int_t n, TStreamerElement *ele=0)
read array of Double32_t from buffer
virtual void * GetFirstAddress(void *start, const void *end) const =0
virtual void WriteFastArray(const Bool_t *b, Int_t n)
Write array of Bool_t to buffer.
static TString Format(const char *fmt,...)
Static method which formats a string using a printf style format descriptor and return a TString...
Definition: TString.cxx:2335
TString fOutBuffer
Definition: TBufferJSON.h:460
virtual void ReadUShort(UShort_t &s)
Reads UShort_t value from buffer.
void Clear()
Clear string without changing its capacity.
Definition: TString.cxx:1140
virtual void ReadDouble(Double_t &d)
Reads Double_t value from buffer.
virtual void WriteObject(const TObject *obj)
Convert object into json structures.
TJSONStackObj * Stack(Int_t depth=0)
return stack object of specified depth
TString & Append(const char *cs)
Definition: TString.h:492
std::map< const void *, unsigned > fJsonrMap
buffer for current value
Definition: TBufferJSON.h:463
Long_t GetThisOffset() const
Definition: TRealData.h:59
unsigned fJsonrCnt
map of recorded objects, used in JsonR to restore references
Definition: TBufferJSON.h:464
TDataType * GetDataType() const
Definition: TDataMember.h:74
TObjArray fStack
counter for all objects and arrays
Definition: TBufferJSON.h:465
virtual void ReadUChar(UChar_t &c)
Reads UChar_t value from buffer.
#define TBufferJSON_ReadStaticArray(vname)
Base class of the Configurations for the member wise looping routines.
TObject()
TObject constructor.
Definition: TObject.cxx:65
void SetCompact(int level)
Set level of space/newline compression 0 - no any compression 1 - exclude spaces in the begin 2 - rem...
virtual void WriteFastArrayDouble32(const Double_t *d, Int_t n, TStreamerElement *ele=0)
Write array of Double32_t to buffer.
void JsonWriteConstChar(const char *value, Int_t len=-1)
writes string value, processing all kind of special characters
Int_t GetMaxIndex(Int_t dim) const
Return maximum index for array dimension "dim".
virtual Int_t ReadStaticArrayDouble32(Double_t *d, TStreamerElement *ele=0)
Read array of Double32_t from buffer.
TString fNumericLocale
depending from compression level, ", " or ","
Definition: TBufferJSON.h:470
virtual void ReadInt(Int_t &i)
Reads Int_t value from buffer.
Int_t GetType() const
Definition: TDataType.h:70
TString fValue
current output buffer for json code
Definition: TBufferJSON.h:462
virtual void SetStreamerElementNumber(TStreamerElement *elem, Int_t comp_type)
Function is called from TStreamerInfo WriteBuffer and Readbuffer functions and add/verify next elemen...
virtual void WriteStdString(const std::string *s)
Writes a std::string.
Int_t GetLast() const
Return index of last object in array.
Definition: TObjArray.cxx:528
virtual void IncrementLevel(TVirtualStreamerInfo *)
Function is called from TStreamerInfo WriteBuffer and ReadBuffer functions and indent new level in js...
virtual void SetByteCount(UInt_t cntpos, Bool_t packInVersion=kFALSE)
suppressed function of TBuffer
static Int_t ExportToFile(const char *filename, const TObject *obj, const char *option=0)
Convert object into JSON and store in text file Returns size of the produce file Used in TObject::Sav...
TClass * GetClass() const
void BuildOld()
rebuild the TStreamerInfo structure
virtual void TagStreamerInfo(TVirtualStreamerInfo *)
Definition: TBufferJSON.h:234
Int_t GetSize() const
Definition: TArray.h:49
virtual void ReadULong(ULong_t &l)
Reads ULong_t value from buffer.
SVector< double, 2 > v
Definition: Dict.h:5
virtual void WriteObjectClass(const void *actualObjStart, const TClass *actualClass)
Write object to buffer. Only used from TBuffer.
Basic data type descriptor (datatype information is obtained from CINT).
Definition: TDataType.h:46
TClass * GetActualClass(const void *object) const
Return a pointer the the real class of the object.
Definition: TClass.cxx:2536
static const char * GetDoubleFormat()
return current printf format for double members, default "%.14e"
PyObject * fValue
virtual void ClassBegin(const TClass *, Version_t=-1)
Should be called in the beginning of custom class streamer.
virtual Int_t ApplySequenceVecPtr(const TStreamerInfoActions::TActionSequence &sequence, void *start_collection, void *end_collection)
Read one collection of objects from the buffer using the StreamerInfoLoopAction.
TString * fOutput
main output buffer for json code
Definition: TBufferJSON.h:461
virtual Bool_t InheritsFrom(const char *classname) const
Returns kTRUE if object inherits from class "classname".
Definition: TObject.cxx:488
TDataMember * GetDataMember() const
Definition: TRealData.h:57
Collection abstract base class.
Definition: TCollection.h:48
void AppendOutput(const char *line0, const char *line1=0)
Info("AppendOutput"," &#39;%s&#39; &#39;%s&#39;", line0, line1?line1 : "---");.
virtual void ReadDouble32(Double_t *d, TStreamerElement *ele=0)
read a Double32_t from the buffer
unsigned int UInt_t
Definition: RtypesCore.h:42
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition: TObject.cxx:925
char * Form(const char *fmt,...)
virtual void SkipVersion(const TClass *cl=0)
Skip class version from I/O buffer.
Ssiz_t Length() const
Definition: TString.h:390
Int_t Size() const
Return size of object of this class.
Definition: TClass.cxx:5356
double floor(double)
short Short_t
Definition: RtypesCore.h:35
TLine * l
Definition: textangle.C:4
The TRealData class manages the effective list of all data members for a given class.
Definition: TRealData.h:34
Int_t GetArrayDim() const
Return number of array dimensions.
The ROOT global object gROOT contains a list of all defined classes.
Definition: TClass.h:81
ROOT::ESTLType GetCollectionType() const
Return the &#39;type&#39; of the STL the TClass is representing.
Definition: TClass.cxx:2811
static const char * fgFloatFmt
stored value of setlocale(LC_NUMERIC), which should be recovered at the end
Definition: TBufferJSON.h:472
virtual void WriteUShort(UShort_t s)
Writes UShort_t value to buffer.
virtual void WriteBool(Bool_t b)
Writes Bool_t value to buffer.
virtual void WriteDouble32(Double_t *d, TStreamerElement *ele=0)
write a Double32_t to the buffer
void WorkWithClass(TStreamerInfo *info, const TClass *cl=0)
Prepares buffer to stream data of specified class.
bool IsStdClass(const char *type)
return true if the class belongs to the std namespace
void JsonStartElement(const TStreamerElement *elem, const TClass *base_class=0)
virtual void ReadTString(TString &s)
Reads a TString.
virtual void WriteFloat(Float_t f)
Writes Float_t value to buffer.
#define FLong64
Definition: TBufferJSON.cxx:71
void PerformPostProcessing(TJSONStackObj *stack, const TStreamerElement *elem=0)
Function is converts TObject and TString structures to more compact representation.
const char * GetTrueTypeName() const
Get full type description of data member, e,g.: "class TDirectory*".
long Long_t
Definition: RtypesCore.h:50
virtual void WriteFastArrayFloat16(const Float_t *d, Int_t n, TStreamerElement *ele=0)
Write array of Float16_t to buffer.
Version_t GetClassVersion() const
Definition: TClass.h:382
virtual void WriteTString(const TString &s)
Writes a TString.
void Build()
Build the I/O data structure for the current class version.
static const char * GetFloatFormat()
return current printf format for float members, default "%e"
virtual void WriteShort(Short_t s)
Writes Short_t value to buffer.
#define ClassImp(name)
Definition: Rtypes.h:279
double f(double x)
virtual void ReadFloat16(Float_t *f, TStreamerElement *ele=0)
read a Float16_t from the buffer
double Double_t
Definition: RtypesCore.h:55
virtual Bool_t CheckObject(const TObject *)
Check that object already stored in the buffer.
virtual void WriteUInt(UInt_t i)
Writes UInt_t value to buffer.
virtual void WriteFloat16(Float_t *f, TStreamerElement *ele=0)
write a Float16_t to the buffer
virtual void WriteULong(ULong_t l)
Writes ULong_t value to buffer.
virtual void WriteArrayDouble32(const Double_t *d, Int_t n, TStreamerElement *ele=0)
Write array of Double32_t to buffer.
Int_t IndexOf(const TObject *obj) const
Definition: TObjArray.cxx:552
unsigned long long ULong64_t
Definition: RtypesCore.h:70
Bool_t fExpectedChain
stack of streamer infos
Definition: TBufferJSON.h:466
unsigned long ULong_t
Definition: RtypesCore.h:51
virtual Bool_t IsBase() const
Return kTRUE if the element represent a base class.
static TString ConvertToJSON(const TObject *obj, Int_t compact=0, const char *member_name=0)
converts object, inherited from TObject class, to JSON string
virtual void * ReadObjectAny(const TClass *clCast)
Read object from buffer. Only used from TBuffer.
#define R__LOCKGUARD(mutex)
TBufferJSON()
Creates buffer object to serialize data into json.
void JsonWriteObject(const void *obj, const TClass *objClass, Bool_t check_map=kTRUE)
Write object to buffer If object was written before, only pointer will be stored If check_map==kFALSE...
virtual void ReadULong64(ULong64_t &l)
Reads ULong64_t value from buffer.
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
virtual void ClassEnd(const TClass *)
Should be called at the end of custom streamer See TBufferJSON::ClassBegin for more details...
virtual Int_t ReadArrayDouble32(Double_t *&d, TStreamerElement *ele=0)
Read array of Double32_t from buffer.
Mother of all ROOT objects.
Definition: TObject.h:37
TObjArray * GetElements() const
static void SetFloatFormat(const char *fmt="%e")
set printf format for float/double members, default "%e" to change format only for doubles...
Int_t IsSTLContainer()
The return type is defined in TDictionary (kVector, kList, etc.)
TJSONStackObj * PopStack()
remove one level from stack
char Char_t
Definition: RtypesCore.h:29
virtual void StreamObject(void *obj, const std::type_info &typeinfo, const TClass *onFileClass=0)
stream object to/from buffer
Bool_t IsTObject() const
Return kTRUE is the class inherits from TObject.
Definition: TClass.cxx:5583
virtual void WriteChar(Char_t c)
Writes Char_t value to buffer.
An array of clone (identical) objects.
Definition: TClonesArray.h:32
const char * GetTypeName() const
virtual Int_t ReadArrayFloat16(Float_t *&f, TStreamerElement *ele=0)
Read array of Float16_t from buffer.
virtual void WriteCharP(const Char_t *c)
Writes array of characters to buffer.
const char * GetArrayIndex() const
If the data member is pointer and has a valid array size in its comments GetArrayIndex returns a stri...
static void CompactFloatString(char *buf, unsigned len)
method compress float string, excluding exp and/or move float point 1.000000e-01 -> 0...
you should not use this method at all Int_t Int_t Double_t Double_t Double_t Int_t Double_t Double_t Double_t Double_t b
Definition: TRolke.cxx:630
TJSONStackObj * PushStack(Int_t inclevel=0)
add new level to the structures stack
#define TBufferJSON_ReadFastArray(vname)
#define snprintf
Definition: civetweb.c:822
Int_t fBufSize
Definition: TBuffer.h:49
void Reset()
Definition: TArrayI.h:49
R__EXTERN Int_t gDebug
Definition: Rtypes.h:128
Int_t Atoi() const
Return integer value of string.
Definition: TString.cxx:1965
void Add(TObject *obj)
Definition: TObjArray.h:75
void SetBaseVersion(Int_t v)
virtual Int_t WriteClassBuffer(const TClass *cl, void *pointer)
Function called by the Streamer functions to serialize object at p to buffer b.
void JsonStreamCollection(TCollection *obj, const TClass *objClass)
store content of collection
unsigned char UChar_t
Definition: RtypesCore.h:34
Definition: first.py:1
virtual Version_t ReadVersion(UInt_t *start=0, UInt_t *bcnt=0, const TClass *cl=0)
read version value from buffer
virtual ~TBufferJSON()
destroy buffer
virtual void WriteClass(const TClass *cl)
suppressed function of TBuffer
virtual void ReadFastArrayString(Char_t *c, Int_t n)
read array of Char_t from buffer
virtual void Compress()
Remove empty slots from array.
Definition: TObjArray.cxx:309
double exp(double)
Abstract Interface class describing Streamer information for one class.
const Bool_t kTRUE
Definition: Rtypes.h:91
Bool_t IsaPointer() const
Return true if data member is a pointer.
Int_t GetType() const
const Int_t n
Definition: legend1.C:16
virtual void WriteArray(const Bool_t *b, Int_t n)
Write array of Bool_t to buffer.
TRealData * GetRealData(const char *name) const
Return pointer to TRealData element with name "name".
Definition: TClass.cxx:3287
virtual void ReadFastArrayWithNbits(Float_t *ptr, Int_t n, Int_t nbits)
read array of Float16_t from buffer
char name[80]
Definition: TGX11.cxx:109
const char * cnt
Definition: TXMLSetup.cxx:75
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition: TObject.cxx:911
virtual const char * GetName() const
Return name of this collection.
void Resize(Ssiz_t n)
Resize the string. Truncate or add blanks as necessary.
Definition: TString.cxx:1059
virtual void ReadUInt(UInt_t &i)
Reads UInt_t value from buffer.
virtual void ClassMember(const char *name, const char *typeName=0, Int_t arrsize1=-1, Int_t arrsize2=-1)
Method indicates name and typename of class member, which should be now streamed in custom streamer F...
const char * Data() const
Definition: TString.h:349
TVirtualStreamerInfo * fStreamerInfo
StreamerInfo used to derive these actions.