Logo ROOT   6.07/09
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 
80 
81 // TJSONStackObj is used to keep stack of object hierarchy,
82 // stored in TBuffer. For instance, data for parent class(es)
83 // stored in subnodes, but initial object node will be kept.
84 
85 class TJSONStackObj : public TObject {
86 public:
87  TStreamerInfo *fInfo; //!
88  TStreamerElement *fElem; //! element in streamer info
89  Int_t fElemNumber; //! number of streamer element in streamer info
90  Bool_t fIsStreamerInfo; //!
91  Bool_t fIsElemOwner; //!
92  Bool_t fIsPostProcessed;//! indicate that value is written
93  Bool_t fIsObjStarted; //! indicate that object writing started, should be closed in postprocess
94  Bool_t fAccObjects; //! if true, accumulate whole objects in values
95  TObjArray fValues; //! raw values
96  Int_t fLevel; //! indent level
97 
98  TJSONStackObj() :
99  TObject(),
100  fInfo(0),
101  fElem(0),
102  fElemNumber(0),
103  fIsStreamerInfo(kFALSE),
104  fIsElemOwner(kFALSE),
105  fIsPostProcessed(kFALSE),
106  fIsObjStarted(kFALSE),
107  fAccObjects(kFALSE),
108  fValues(),
109  fLevel(0)
110  {
111  fValues.SetOwner(kTRUE);
112  }
113 
114  virtual ~TJSONStackObj()
115  {
116  if (fIsElemOwner) delete fElem;
117  }
118 
119  Bool_t IsStreamerInfo() const
120  {
121  return fIsStreamerInfo;
122  }
123  Bool_t IsStreamerElement() const
124  {
125  return !fIsStreamerInfo && (fElem != 0);
126  }
127 
128  void PushValue(TString &v)
129  {
130  fValues.Add(new TObjString(v));
131  v.Clear();
132  }
133 };
134 
135 
136 ////////////////////////////////////////////////////////////////////////////////
137 /// Creates buffer object to serialize data into json.
138 
140  TBuffer(TBuffer::kWrite),
141  fOutBuffer(),
142  fOutput(0),
143  fValue(),
144  fJsonrMap(),
145  fJsonrCnt(0),
146  fStack(),
147  fExpectedChain(kFALSE),
148  fCompact(0),
149  fSemicolon(" : "),
150  fArraySepar(", "),
151  fNumericLocale()
152 {
153  fBufSize = 1000000000;
154 
155  SetParent(0);
157  //SetBit(kTextBasedStreaming);
158 
159  fOutBuffer.Capacity(10000);
160  fValue.Capacity(1000);
161  fOutput = &fOutBuffer;
162 
163  // checks if setlocale(LC_NUMERIC) returns others than "C"
164  // in this case locale will be changed and restored at the end of object conversion
165 
166  char* loc = setlocale(LC_NUMERIC, 0);
167  if ((loc!=0) && (strcmp(loc,"C")!=0)) {
168  fNumericLocale = loc;
169  setlocale(LC_NUMERIC, "C");
170  }
171 }
172 
173 ////////////////////////////////////////////////////////////////////////////////
174 /// destroy buffer
175 
177 {
178  fStack.Delete();
179 
180  if (fNumericLocale.Length()>0)
181  setlocale(LC_NUMERIC, fNumericLocale.Data());
182 }
183 
184 ////////////////////////////////////////////////////////////////////////////////
185 /// converts object, inherited from TObject class, to JSON string
186 
187 TString TBufferJSON::ConvertToJSON(const TObject *obj, Int_t compact, const char *member_name)
188 {
189  TClass *clActual = 0;
190  void *ptr = (void *) obj;
191 
192  if (obj!=0) {
193  clActual = TObject::Class()->GetActualClass(obj);
194  if (!clActual) clActual = TObject::Class(); else
195  if (clActual != TObject::Class())
196  ptr = (void *) ((Long_t) obj - clActual->GetBaseClassOffset(TObject::Class()));
197  }
198 
199  return ConvertToJSON(ptr, clActual, compact, member_name);
200 }
201 
202 ////////////////////////////////////////////////////////////////////////////////
203 /// Set level of space/newline compression
204 /// 0 - no any compression
205 /// 1 - exclude spaces in the begin
206 /// 2 - remove newlines
207 /// 3 - exclude spaces as much as possible
208 
209 void TBufferJSON::SetCompact(int level)
210 {
211  fCompact = level;
212  fSemicolon = fCompact > 2 ? ":" : " : ";
213  fArraySepar = fCompact > 2 ? "," : ", ";
214 }
215 
216 
217 ////////////////////////////////////////////////////////////////////////////////
218 /// Converts any type of object to JSON string
219 /// One should provide pointer on object and its class name
220 /// Following values of compact parameter can be used
221 /// 0 - no any compression
222 /// 1 - exclude spaces in the begin
223 /// 2 - remove newlines
224 /// 3 - exclude spaces as much as possible
225 /// When member_name specified, converts only this data member
226 
227 TString TBufferJSON::ConvertToJSON(const void *obj, const TClass *cl,
228  Int_t compact, const char *member_name)
229 {
230  if ((member_name!=0) && (obj!=0)) {
231  TRealData *rdata = cl->GetRealData(member_name);
232  if (rdata==0) return TString();
233  TDataMember *member = rdata->GetDataMember();
234  if (member==0) return TString();
235 
236  Int_t arraylen = -1;
237  if (member->GetArrayIndex()!=0) {
238  TRealData *idata = cl->GetRealData(member->GetArrayIndex());
239  TDataMember *imember = (idata!=0) ? idata->GetDataMember() : 0;
240  if ((imember!=0) && (strcmp(imember->GetTrueTypeName(),"int")==0)) {
241  arraylen = *((int *) ((char *) obj + idata->GetThisOffset()));
242  }
243  }
244 
245  void *ptr = (char *) obj + rdata->GetThisOffset();
246  if (member->IsaPointer()) ptr = *((char **) ptr);
247 
248  return TBufferJSON::ConvertToJSON(ptr, member, compact, arraylen);
249  }
250 
251  TBufferJSON buf;
252 
253  buf.SetCompact(compact);
254 
255  buf.JsonWriteObject(obj, cl);
256 
257  return buf.fOutBuffer.Length() ? buf.fOutBuffer : buf.fValue;
258 }
259 
260 ////////////////////////////////////////////////////////////////////////////////
261 /// Converts selected data member into json
262 /// Parameter ptr specifies address in memory, where data member is located
263 /// compact parameter defines compactness of produced JSON (from 0 to 3)
264 /// arraylen (when specified) is array length for this data member, //[fN] case
265 
267  Int_t compact, Int_t arraylen)
268 {
269  if ((ptr == 0) || (member == 0)) return TString("null");
270 
271  Bool_t stlstring = !strcmp(member->GetTrueTypeName(), "string");
272 
273  Int_t isstl = member->IsSTLContainer();
274 
275  TClass *mcl = member->IsBasic() ? 0 : gROOT->GetClass(member->GetTypeName());
276 
277  if ((mcl != 0) && (mcl != TString::Class()) && !stlstring && !isstl &&
278  (mcl->GetBaseClassOffset(TArray::Class()) != 0))
279  return TBufferJSON::ConvertToJSON(ptr, mcl, compact);
280 
281  TBufferJSON buf;
282 
283  buf.SetCompact(compact);
284 
285  return buf.JsonWriteMember(ptr, member, mcl, arraylen);
286 }
287 
288 ////////////////////////////////////////////////////////////////////////////////
289 /// Convert object into JSON and store in text file
290 /// Returns size of the produce file
291 /// Used in TObject::SaveAs()
292 
293 Int_t TBufferJSON::ExportToFile(const char* filename, const TObject *obj, const char* option)
294 {
295  if (!obj || !filename || (*filename==0)) return 0;
296 
297  Int_t compact = 0;
298  if (option && (*option >= '0') && (*option <='3')) compact = TString(option,1).Atoi();
299 
300  TString json = TBufferJSON::ConvertToJSON(obj, compact);
301 
302  std::ofstream ofs (filename);
303  ofs << json.Data();
304  ofs.close();
305 
306  return json.Length();
307 }
308 
309 ////////////////////////////////////////////////////////////////////////////////
310 /// Convert object into JSON and store in text file
311 /// Returns size of the produce file
312 
313 Int_t TBufferJSON::ExportToFile(const char* filename, const void *obj, const TClass *cl, const char* option)
314 {
315  if (!obj || !cl || !filename || (*filename==0)) return 0;
316 
317  Int_t compact = 0;
318  if (option && (*option >= '0') && (*option <='3')) compact = TString(option,1).Atoi();
319 
320  TString json = TBufferJSON::ConvertToJSON(obj, cl, compact);
321 
322  std::ofstream ofs (filename);
323  ofs << json.Data();
324  ofs.close();
325 
326  return json.Length();
327 }
328 
329 ////////////////////////////////////////////////////////////////////////////////
330 /// Convert single data member to JSON structures
331 /// Returns string with converted member
332 
334  TClass *memberClass, Int_t arraylen)
335 {
336  if (member == 0) return "null";
337 
338  if (gDebug > 2)
339  Info("JsonWriteMember", "Write member %s type %s ndim %d",
340  member->GetName(), member->GetTrueTypeName(), member->GetArrayDim());
341 
342  PushStack(0);
343  fValue.Clear();
344 
345  if (member->IsBasic()) {
346 
347  Int_t tid = member->GetDataType() ? member->GetDataType()->GetType() : kNoType_t;
348 
349  if (ptr == 0) {
350  fValue = "null";
351  } else if ((member->GetArrayDim() == 0) && (arraylen<0)) {
352  switch (tid) {
353  case kChar_t:
354  JsonWriteBasic(*((Char_t *)ptr));
355  break;
356  case kShort_t:
357  JsonWriteBasic(*((Short_t *)ptr));
358  break;
359  case kInt_t:
360  JsonWriteBasic(*((Int_t *)ptr));
361  break;
362  case kLong_t:
363  JsonWriteBasic(*((Long_t *)ptr));
364  break;
365  case kFloat_t:
366  JsonWriteBasic(*((Float_t *)ptr));
367  break;
368  case kCounter:
369  JsonWriteBasic(*((Int_t *)ptr));
370  break;
371  case kCharStar:
372  WriteCharP((Char_t *)ptr);
373  break;
374  case kDouble_t:
375  JsonWriteBasic(*((Double_t *)ptr));
376  break;
377  case kDouble32_t:
378  JsonWriteBasic(*((Double_t *)ptr));
379  break;
380  case kchar:
381  JsonWriteBasic(*((char *)ptr));
382  break;
383  case kUChar_t:
384  JsonWriteBasic(*((UChar_t *)ptr));
385  break;
386  case kUShort_t:
387  JsonWriteBasic(*((UShort_t *)ptr));
388  break;
389  case kUInt_t:
390  JsonWriteBasic(*((UInt_t *)ptr));
391  break;
392  case kULong_t:
393  JsonWriteBasic(*((ULong_t *)ptr));
394  break;
395  case kBits:
396  JsonWriteBasic(*((UInt_t *)ptr));
397  break;
398  case kLong64_t:
399  JsonWriteBasic(*((Long64_t *)ptr));
400  break;
401  case kULong64_t:
402  JsonWriteBasic(*((ULong64_t *)ptr));
403  break;
404  case kBool_t:
405  JsonWriteBasic(*((Bool_t *)ptr));
406  break;
407  case kFloat16_t:
408  JsonWriteBasic(*((Float_t *)ptr));
409  break;
410  case kOther_t:
411  case kNoType_t:
412  case kVoid_t:
413  break;
414  }
415  } else if ((member->GetArrayDim() == 1) || (arraylen>=0)) {
416  Int_t n = (arraylen>=0) ? arraylen : member->GetMaxIndex(0);
417  switch (tid) {
418  case kChar_t:
419  WriteFastArray((Char_t *)ptr, n);
420  break;
421  case kShort_t:
422  WriteFastArray((Short_t *)ptr, n);
423  break;
424  case kInt_t:
425  WriteFastArray((Int_t *)ptr, n);
426  break;
427  case kLong_t:
428  WriteFastArray((Long_t *)ptr, n);
429  break;
430  case kFloat_t:
431  WriteFastArray((Float_t *)ptr, n);
432  break;
433  case kCounter:
434  WriteFastArray((Int_t *)ptr, n);
435  break;
436  case kCharStar:
437  WriteFastArray((Char_t *)ptr, n);
438  break;
439  case kDouble_t:
440  WriteFastArray((Double_t *)ptr, n);
441  break;
442  case kDouble32_t:
443  WriteFastArray((Double_t *)ptr, n);
444  break;
445  case kchar:
446  WriteFastArray((char *)ptr, n);
447  break;
448  case kUChar_t:
449  WriteFastArray((UChar_t *)ptr, n);
450  break;
451  case kUShort_t:
452  WriteFastArray((UShort_t *)ptr, n);
453  break;
454  case kUInt_t:
455  WriteFastArray((UInt_t *)ptr, n);
456  break;
457  case kULong_t:
458  WriteFastArray((ULong_t *)ptr, n);
459  break;
460  case kBits:
461  WriteFastArray((UInt_t *)ptr, n);
462  break;
463  case kLong64_t:
464  WriteFastArray((Long64_t *)ptr, n);
465  break;
466  case kULong64_t:
467  WriteFastArray((ULong64_t *)ptr, n);
468  break;
469  case kBool_t:
470  WriteFastArray((Bool_t *)ptr, n);
471  break;
472  case kFloat16_t:
473  WriteFastArray((Float_t *)ptr, n);
474  break;
475  case kOther_t:
476  case kNoType_t:
477  case kVoid_t:
478  break;
479  }
480  } else {
481  // here generic code to write n-dimensional array
482 
483  TArrayI indexes(member->GetArrayDim() - 1);
484  indexes.Reset(0);
485 
486  Int_t cnt = 0;
487  while (cnt >= 0) {
488  if (indexes[cnt] >= member->GetMaxIndex(cnt)) {
489  fOutBuffer.Append(" ]");
490  indexes[cnt--] = 0;
491  if (cnt >= 0) indexes[cnt]++;
492  continue;
493  }
494 
495  if (indexes[cnt] > 0)
497  else
498  fOutBuffer.Append("[ ");
499 
500  if (++cnt == indexes.GetSize()) {
501  Int_t shift = 0;
502  for (Int_t k = 0; k < indexes.GetSize(); k++) {
503  shift = shift * member->GetMaxIndex(k) + indexes[k];
504  }
505 
506  Int_t len = member->GetMaxIndex(indexes.GetSize());
507  shift *= len;
508 
509  fValue.Clear();
510 
511  switch (tid) {
512  case kChar_t:
513  WriteFastArray((Char_t *)ptr + shift, len);
514  break;
515  case kShort_t:
516  WriteFastArray((Short_t *)ptr + shift, len);
517  break;
518  case kInt_t:
519  WriteFastArray((Int_t *)ptr + shift, len);
520  break;
521  case kLong_t:
522  WriteFastArray((Long_t *)ptr + shift, len);
523  break;
524  case kFloat_t:
525  WriteFastArray((Float_t *)ptr + shift, len);
526  break;
527  case kCounter:
528  WriteFastArray((Int_t *)ptr + shift, len);
529  break;
530  case kCharStar:
531  WriteFastArray((Char_t *)ptr + shift, len);
532  break;
533  case kDouble_t:
534  WriteFastArray((Double_t *)ptr + shift, len);
535  break;
536  case kDouble32_t:
537  WriteFastArray((Double_t *)ptr + shift, len);
538  break;
539  case kchar:
540  WriteFastArray((char *)ptr + shift, len);
541  break;
542  case kUChar_t:
543  WriteFastArray((UChar_t *)ptr + shift, len);
544  break;
545  case kUShort_t:
546  WriteFastArray((UShort_t *)ptr + shift, len);
547  break;
548  case kUInt_t:
549  WriteFastArray((UInt_t *)ptr + shift, len);
550  break;
551  case kULong_t:
552  WriteFastArray((ULong_t *)ptr + shift, len);
553  break;
554  case kBits:
555  WriteFastArray((UInt_t *)ptr + shift, len);
556  break;
557  case kLong64_t:
558  WriteFastArray((Long64_t *)ptr + shift, len);
559  break;
560  case kULong64_t:
561  WriteFastArray((ULong64_t *)ptr + shift, len);
562  break;
563  case kBool_t:
564  WriteFastArray((Bool_t *)ptr + shift, len);
565  break;
566  case kFloat16_t:
567  WriteFastArray((Float_t *)ptr + shift, len);
568  break;
569  case kOther_t:
570  case kNoType_t:
571  case kVoid_t:
572  fValue = "null";
573  break;
574  }
575 
577  indexes[--cnt]++;
578  }
579  }
580 
581  fValue = fOutBuffer;
582  }
583  } else if (memberClass == TString::Class()) {
584  TString *str = (TString *) ptr;
585  fValue.Append("\"");
586  if (str != 0) fValue.Append(*str);
587  fValue.Append("\"");
588  } else if ((member->IsSTLContainer() == ROOT::kSTLvector) ||
589  (member->IsSTLContainer() == ROOT::kSTLlist) ||
590  (member->IsSTLContainer() == ROOT::kSTLforwardlist)) {
591 
592  if (memberClass)
593  ((TClass *)memberClass)->Streamer((void *)ptr, *this);
594  else
595  fValue = "[]";
596 
597  if (fValue == "0") fValue = "[]";
598 
599  } else if (memberClass && memberClass->GetBaseClassOffset(TArray::Class()) == 0) {
600  TArray *arr = (TArray *) ptr;
601  if ((arr != 0) && (arr->GetSize() > 0)) {
602  arr->Streamer(*this);
603  // WriteFastArray(arr->GetArray(), arr->GetSize());
604  if (Stack()->fValues.GetLast() > 0) {
605  Warning("TBufferJSON", "When streaming TArray, more than 1 object in the stack, use second item");
606  fValue = Stack()->fValues.At(1)->GetName();
607  }
608  } else
609  fValue = "[]";
610  } else if (memberClass && !strcmp(memberClass->GetName(), "string")) {
611  // here value contains quotes, stack can be ignored
612  ((TClass *)memberClass)->Streamer((void *)ptr, *this);
613  }
614  PopStack();
615 
616  if (fValue.Length()) return fValue;
617 
618  if ((memberClass == 0) || (member->GetArrayDim() > 0)) return "\"not supported\"";
619 
620  return TBufferJSON::ConvertToJSON(ptr, memberClass);
621 }
622 
623 
624 ////////////////////////////////////////////////////////////////////////////////
625 /// Check that object already stored in the buffer
626 
628 {
629  if (obj == 0) return kTRUE;
630 
631  return fJsonrMap.find(obj) != fJsonrMap.end();
632 }
633 
634 ////////////////////////////////////////////////////////////////////////////////
635 /// Check that object already stored in the buffer
636 
637 Bool_t TBufferJSON::CheckObject(const void *ptr, const TClass * /*cl*/)
638 {
639  if (ptr == 0) return kTRUE;
640 
641  return fJsonrMap.find(ptr) != fJsonrMap.end();
642 }
643 
644 ////////////////////////////////////////////////////////////////////////////////
645 /// Convert object into json structures.
646 /// !!! Should be used only by TBufferJSON itself.
647 /// Use ConvertToJSON() methods to convert object to json
648 /// Redefined here to avoid gcc 3.x warning
649 
651 {
652  if (gDebug > 1)
653  Info("WriteObject", "Object %p", obj);
654 
656 }
657 
658 ////////////////////////////////////////////////////////////////////////////////
659 /// add new level to the structures stack
660 
661 TJSONStackObj *TBufferJSON::PushStack(Int_t inclevel)
662 {
663  TJSONStackObj *curr = Stack();
664  TJSONStackObj *stack = new TJSONStackObj();
665  stack->fLevel = (curr ? curr->fLevel : 0) + inclevel;
666  fStack.Add(stack);
667  return stack;
668 }
669 
670 ////////////////////////////////////////////////////////////////////////////////
671 /// remove one level from stack
672 
673 TJSONStackObj *TBufferJSON::PopStack()
674 {
675  TObject *last = fStack.Last();
676  if (last != 0) {
677  fStack.Remove(last);
678  delete last;
679  fStack.Compress();
680  }
681  return dynamic_cast<TJSONStackObj *>(fStack.Last());
682 }
683 
684 ////////////////////////////////////////////////////////////////////////////////
685 /// return stack object of specified depth
686 
687 TJSONStackObj *TBufferJSON::Stack(Int_t depth)
688 {
689  TJSONStackObj *stack = 0;
690  if (depth <= fStack.GetLast())
691  stack = dynamic_cast<TJSONStackObj *>(fStack.At(fStack.GetLast() - depth));
692  return stack;
693 }
694 
695 ////////////////////////////////////////////////////////////////////////////////
696 /// Info("AppendOutput"," '%s' '%s'", line0, line1?line1 : "---");
697 
698 void TBufferJSON::AppendOutput(const char *line0, const char *line1)
699 {
700  if (line0 != 0) fOutput->Append(line0);
701 
702  if (line1 != 0) {
703  if (fCompact < 2) fOutput->Append("\n");
704 
705  if (strlen(line1) > 0) {
706  if (fCompact < 1) {
707  TJSONStackObj *stack = Stack();
708  if ((stack != 0) && (stack->fLevel > 0))
709  fOutput->Append(' ', stack->fLevel);
710  }
711  fOutput->Append(line1);
712  }
713  }
714 }
715 
716 ////////////////////////////////////////////////////////////////////////////////
717 
718 void TBufferJSON::JsonStartElement(const TStreamerElement *elem, const TClass *base_class)
719 {
720  const char *elem_name = 0;
721 
722  if (base_class == 0) {
723  elem_name = elem->GetName();
724  } else {
725  switch (JsonSpecialClass(base_class)) {
726  case TClassEdit::kVector :
727  elem_name = "fVector";
728  break;
729  case TClassEdit::kList :
730  elem_name = "fList";
731  break;
732  case TClassEdit::kDeque :
733  elem_name = "fDeque";
734  break;
735  case TClassEdit::kMap :
736  elem_name = "fMap";
737  break;
738  case TClassEdit::kMultiMap :
739  elem_name = "fMultiMap";
740  break;
741  case TClassEdit::kSet :
742  elem_name = "fSet";
743  break;
744  case TClassEdit::kMultiSet :
745  elem_name = "fMultiSet";
746  break;
747  case TClassEdit::kBitSet :
748  elem_name = "fBitSet";
749  break;
750  case 100:
751  elem_name = "fArray";
752  break;
753  case 110:
754  case 120:
755  elem_name = "fString";
756  break;
757  }
758  }
759 
760  if (elem_name != 0) {
761  AppendOutput(",", "\"");
762  AppendOutput(elem_name);
763  AppendOutput("\"");
765  }
766 }
767 
768 ////////////////////////////////////////////////////////////////////////////////
769 
771 {
772  TJSONStackObj *stack = Stack();
773  if (stack != 0) stack->fIsPostProcessed = kTRUE;
774 }
775 
776 ////////////////////////////////////////////////////////////////////////////////
777 /// return non-zero value when class has special handling in JSON
778 /// it is TCollection (-130), TArray (100), TString (110), std::string (120) and STL containers (1..6)
779 
781 {
782  if (cl == 0) return 0;
783 
784  Bool_t isarray = strncmp("TArray", cl->GetName(), 6) == 0;
785  if (isarray) isarray = ((TClass *)cl)->GetBaseClassOffset(TArray::Class()) == 0;
786  if (isarray) return 100;
787 
788  // negative value used to indicate that collection stored as object
789  if (((TClass *)cl)->GetBaseClassOffset(TCollection::Class()) == 0) return -130;
790 
791  // special case for TString - it is saved as string in JSON
792  if (cl == TString::Class()) return 110;
793 
794  bool isstd = TClassEdit::IsStdClass(cl->GetName());
795  int isstlcont(ROOT::kNotSTL);
796  if (isstd) isstlcont = cl->GetCollectionType();
797  if (isstlcont > 0) return isstlcont;
798 
799  // also special handling for STL string, which handled similar to TString
800  if (isstd && !strcmp(cl->GetName(), "string")) return 120;
801 
802  return 0;
803 }
804 
805 ////////////////////////////////////////////////////////////////////////////////
806 /// Write object to buffer
807 /// If object was written before, only pointer will be stored
808 /// If check_map==kFALSE, object will be stored in any case and pointer will not be registered in the map
809 
810 void TBufferJSON::JsonWriteObject(const void *obj, const TClass *cl, Bool_t check_map)
811 {
812  // static int cnt = 0;
813 
814  if (!cl) obj = 0;
815 
816  //if (cnt++>100) return;
817 
818  if (gDebug > 0)
819  Info("JsonWriteObject", "Object %p class %s check_map %s", obj, cl ? cl->GetName() : "null", check_map ? "true" : "false");
820 
821  Int_t special_kind = JsonSpecialClass(cl);
822 
823  TString fObjectOutput, *fPrevOutput(0);
824 
825  TJSONStackObj *stack = Stack();
826 
827  if (stack && stack->fAccObjects && ((fValue.Length() > 0) || (stack->fValues.GetLast() >= 0))) {
828  // accumulate data of super-object in stack
829 
830  if (fValue.Length() > 0) {
831  stack->fValues.Add(new TObjString(fValue));
832  fValue.Clear();
833  }
834 
835  // redirect output to local buffer, use it later as value
836  fPrevOutput = fOutput;
837  fOutput = &fObjectOutput;
838  } else if ((special_kind <= 0) || (special_kind > 100)) {
839  // FIXME: later post processing should be active for all special classes, while they all keep output in the value
841  }
842 
843  if (obj == 0) {
844  AppendOutput("null");
845  goto post_process;
846  }
847 
848  if (special_kind <= 0) {
849  // add element name which should correspond to the object
850  if (check_map) {
851  std::map<const void *, unsigned>::const_iterator iter = fJsonrMap.find(obj);
852  if (iter != fJsonrMap.end()) {
853  AppendOutput(Form("\"$ref:%u\"", iter->second));
854  goto post_process;
855  }
856  fJsonrMap[obj] = fJsonrCnt;
857  }
858 
859  fJsonrCnt++; // object counts is important in dereferencing part
860 
861  stack = PushStack(2);
862  AppendOutput("{", "\"_typename\"");
864  AppendOutput("\"");
865  AppendOutput(cl->GetName());
866  AppendOutput("\"");
867  } else {
868  // for array, string and STL collections different handling -
869  // they not recognized at the end as objects in JSON
870  stack = PushStack(0);
871  }
872 
873  if (gDebug > 3)
874  Info("JsonWriteObject", "Starting object %p write for class: %s",
875  obj, cl->GetName());
876 
877  stack->fAccObjects = special_kind < 10;
878 
879  if (special_kind == -130)
880  JsonStreamCollection((TCollection *) obj, cl);
881  else
882  ((TClass *)cl)->Streamer((void *)obj, *this);
883 
884  if (gDebug > 3)
885  Info("JsonWriteObject", "Done object %p write for class: %s",
886  obj, cl->GetName());
887 
888  if (special_kind == 100) {
889  if (stack->fValues.GetLast() != 0)
890  Error("JsonWriteObject", "Problem when writing array");
891  stack->fValues.Delete();
892  } else if ((special_kind == 110) || (special_kind == 120)) {
893  if (stack->fValues.GetLast() > 1)
894  Error("JsonWriteObject", "Problem when writing TString or std::string");
895  stack->fValues.Delete();
897  fValue.Clear();
898  } else if ((special_kind > 0) && (special_kind <= TClassEdit::kBitSet)) {
899  // here make STL container processing
900 
901  if (stack->fValues.GetLast() < 0) {
902  // empty container
903  if (fValue != "0") Error("JsonWriteObject", "With empty stack fValue!=0");
904  fValue = "[]";
905  } else if (stack->fValues.GetLast() == 0) {
906  // case of simple vector, array already in the value
907  stack->fValues.Delete();
908  if (fValue.Length() == 0) {
909  Error("JsonWriteObject", "Empty value when it should contain something");
910  fValue = "[]";
911  }
912 
913  } else {
914  const char *separ = "[";
915 
916  if (fValue.Length() > 0) {
917  stack->fValues.Add(new TObjString(fValue));
918  fValue.Clear();
919  }
920 
921  Int_t size = TString(stack->fValues.At(0)->GetName()).Atoi();
922 
923  if ((size * 2 == stack->fValues.GetLast()) &&
924  ((special_kind == TClassEdit::kMap) || (special_kind == TClassEdit::kMultiMap))) {
925  // special handling for std::map. Create entries like { 'first' : key, 'second' : value }
926  for (Int_t k = 1; k < stack->fValues.GetLast(); k += 2) {
927  fValue.Append(separ);
928  separ = fArraySepar.Data();
929  fJsonrCnt++; // account each entry in map, can conflict with objects inside values
930  fValue.Append("{");
931  fValue.Append("\"first\"");
933  fValue.Append(stack->fValues.At(k)->GetName());
935  fValue.Append("\"second\"");
937  fValue.Append(stack->fValues.At(k + 1)->GetName());
938  fValue.Append("}");
939  }
940  } else {
941  // for most stl containers write just like blob, but skipping first element with size
942  for (Int_t k = 1; k <= stack->fValues.GetLast(); k++) {
943  fValue.Append(separ);
944  separ = fArraySepar.Data();
945  fValue.Append(stack->fValues.At(k)->GetName());
946  }
947  }
948 
949  fValue.Append("]");
950  stack->fValues.Delete();
951  }
952  }
953 
954  if ((special_kind == 0) &&
955  ((stack->fValues.GetLast() >= 0) || (fValue.Length() > 0))) {
956  if (gDebug > 0)
957  Info("JsonWriteObject", "Create blob value for class %s", cl->GetName());
958 
959  AppendOutput(fArraySepar.Data(), "\"_blob\"");
961 
962  const char *separ = "[";
963 
964  for (Int_t k = 0; k <= stack->fValues.GetLast(); k++) {
965  AppendOutput(separ);
966  separ = fArraySepar.Data();
967  AppendOutput(stack->fValues.At(k)->GetName());
968  }
969 
970  if (fValue.Length() > 0) {
971  AppendOutput(separ);
973  }
974 
975  AppendOutput("]");
976 
977  fValue.Clear();
978  stack->fValues.Delete();
979  }
980 
981  PopStack();
982 
983  if (special_kind <= 0) {
984  AppendOutput(0, "}");
985  }
986 
987 post_process:
988 
989  if (fPrevOutput != 0) {
990  fOutput = fPrevOutput;
991  // for STL containers and TArray object in fValue itself
992  if ((special_kind <= 0) || (special_kind > 100))
993  fValue = fObjectOutput;
994  else if (fObjectOutput.Length() != 0)
995  Error("JsonWriteObject", "Non-empty object output for special class %s", cl->GetName());
996  }
997 }
998 
999 ////////////////////////////////////////////////////////////////////////////////
1000 /// store content of collection
1001 
1003 {
1004  AppendOutput(",", "\"name\"");
1006  AppendOutput("\"");
1007  AppendOutput(col->GetName());
1008  AppendOutput("\",", "\"arr\"");
1010 
1011  // collection treated as JS Array and its reference kept in the objects map
1012  AppendOutput("["); // fJsonrCnt++; // account array of objects
1013 
1014  bool islist = col->InheritsFrom(TList::Class());
1015  TString sopt;
1016  sopt.Capacity(500);
1017  sopt = "[";
1018 
1019  TIter iter(col);
1020  TObject *obj;
1021  Bool_t first = kTRUE;
1022  while ((obj = iter()) != 0) {
1023  if (!first) {
1025  sopt.Append(fArraySepar.Data());
1026  }
1027  if (islist) {
1028  sopt.Append("\"");
1029  sopt.Append(iter.GetOption());
1030  sopt.Append("\"");
1031  }
1032 
1034 
1035  first = kFALSE;
1036  }
1037 
1038  sopt.Append("]");
1039 
1040  AppendOutput("]");
1041 
1042  if (islist) {
1043  AppendOutput(",", "\"opt\"");
1045  AppendOutput(sopt.Data());
1046  /* fJsonrCnt++; */ // account array of options
1047  }
1048  fValue.Clear();
1049 }
1050 
1051 
1052 ////////////////////////////////////////////////////////////////////////////////
1053 /// Function is called from TStreamerInfo WriteBuffer and ReadBuffer functions
1054 /// and indent new level in json structure.
1055 /// This call indicates, that TStreamerInfo functions starts streaming
1056 /// object data of correspondent class
1057 
1059 {
1060  if (gDebug > 2)
1061  Info("IncrementLevel", "Class: %s", (info ? info->GetClass()->GetName() : "custom"));
1062 
1063  WorkWithClass((TStreamerInfo *)info);
1064 }
1065 
1066 ////////////////////////////////////////////////////////////////////////////////
1067 /// Prepares buffer to stream data of specified class
1068 
1070 {
1072 
1073  if (sinfo != 0) cl = sinfo->GetClass();
1074 
1075  if (cl == 0) return;
1076 
1077  if (gDebug > 3) Info("WorkWithClass", "Class: %s", cl->GetName());
1078 
1079  TJSONStackObj *stack = Stack();
1080 
1081  if ((stack != 0) && stack->IsStreamerElement() && !stack->fIsObjStarted &&
1082  ((stack->fElem->GetType() == TStreamerInfo::kObject) ||
1083  (stack->fElem->GetType() == TStreamerInfo::kAny))) {
1084 
1085  stack->fIsObjStarted = kTRUE;
1086 
1087  fJsonrCnt++; // count object, but do not keep reference
1088 
1089  stack = PushStack(2);
1090  AppendOutput("{", "\"_typename\"");
1092  AppendOutput("\"");
1093  AppendOutput(cl->GetName());
1094  AppendOutput("\"");
1095  } else {
1096  stack = PushStack(0);
1097  }
1098 
1099  stack->fInfo = sinfo;
1100  stack->fIsStreamerInfo = kTRUE;
1101 }
1102 
1103 ////////////////////////////////////////////////////////////////////////////////
1104 /// Function is called from TStreamerInfo WriteBuffer and ReadBuffer functions
1105 /// and decrease level in json structure.
1106 
1108 {
1110 
1111  if (gDebug > 2)
1112  Info("DecrementLevel", "Class: %s",
1113  (info ? info->GetClass()->GetName() : "custom"));
1114 
1115  TJSONStackObj *stack = Stack();
1116 
1117  if (stack->IsStreamerElement()) {
1118  if (gDebug > 3)
1119  Info("DecrementLevel", " Perform post-processing elem: %s",
1120  stack->fElem->GetName());
1121 
1122  PerformPostProcessing(stack);
1123 
1124  stack = PopStack(); // remove stack of last element
1125  }
1126 
1127  if (stack->fInfo != (TStreamerInfo *) info)
1128  Error("DecrementLevel", " Mismatch of streamer info");
1129 
1130  PopStack(); // back from data of stack info
1131 
1132  if (gDebug > 3)
1133  Info("DecrementLevel", "Class: %s done",
1134  (info ? info->GetClass()->GetName() : "custom"));
1135 }
1136 
1137 ////////////////////////////////////////////////////////////////////////////////
1138 /// Function is called from TStreamerInfo WriteBuffer and Readbuffer functions
1139 /// and add/verify next element of json structure
1140 /// This calls allows separate data, correspondent to one class member, from another
1141 
1143 {
1144  if (gDebug > 3)
1145  Info("SetStreamerElementNumber", "Element name %s", elem->GetName());
1146 
1147  WorkWithElement(elem, comp_type);
1148 }
1149 
1150 ////////////////////////////////////////////////////////////////////////////////
1151 /// This is call-back from streamer which indicates
1152 /// that class member will be streamed
1153 /// Name of element used in JSON
1154 
1156 {
1158 
1159  TJSONStackObj *stack = Stack();
1160  if (stack == 0) {
1161  Error("WorkWithElement", "stack is empty");
1162  return;
1163  }
1164 
1165  if (gDebug > 0)
1166  Info("WorkWithElement", " Start element %s type %d typename %s",
1167  elem ? elem->GetName() : "---", elem ? elem->GetType() : -1, elem ? elem->GetTypeName() : "---");
1168 
1169  if (stack->IsStreamerElement()) {
1170  // this is post processing
1171 
1172  if (gDebug > 3)
1173  Info("WorkWithElement", " Perform post-processing elem: %s",
1174  stack->fElem->GetName());
1175 
1176  PerformPostProcessing(stack);
1177 
1178  stack = PopStack(); // go level back
1179  }
1180 
1181  fValue.Clear();
1182 
1183  if (stack == 0) {
1184  Error("WorkWithElement", "Lost of stack");
1185  return;
1186  }
1187 
1188  TStreamerInfo *info = stack->fInfo;
1189  if (!stack->IsStreamerInfo()) {
1190  Error("WorkWithElement", "Problem in Inc/Dec level");
1191  return;
1192  }
1193 
1194  Int_t number = info ? info->GetElements()->IndexOf(elem) : -1;
1195 
1196  if (elem == 0) {
1197  Error("WorkWithElement", "streamer info returns elem = 0");
1198  return;
1199  }
1200 
1201  Bool_t isBasicType = (elem->GetType() > 0) && (elem->GetType() < 20);
1202 
1203  fExpectedChain = isBasicType && (comp_type - elem->GetType() == TStreamerInfo::kOffsetL);
1204 
1205  if (fExpectedChain && (gDebug > 3))
1206  Info("WorkWithElement", " Expects chain for elem %s number %d",
1207  elem->GetName(), number);
1208 
1209  TClass *base_class = elem->IsBase() ? elem->GetClassPointer() : 0;
1210 
1211  stack = PushStack(0);
1212  stack->fElem = (TStreamerElement *) elem;
1213  stack->fElemNumber = number;
1214  stack->fIsElemOwner = (number < 0);
1215 
1216  JsonStartElement(elem, base_class);
1217 }
1218 
1219 ////////////////////////////////////////////////////////////////////////////////
1220 /// Should be called in the beginning of custom class streamer.
1221 /// Informs buffer data about class which will be streamed now.
1222 ///
1223 /// ClassBegin(), ClassEnd() and ClassMemeber() should be used in
1224 /// custom class streamers to specify which kind of data are
1225 /// now streamed. Such information is used to correctly
1226 /// convert class data to JSON. Without that functions calls
1227 /// classes with custom streamers cannot be used with TBufferJSON
1228 
1230 {
1231  WorkWithClass(0, cl);
1232 }
1233 
1234 ////////////////////////////////////////////////////////////////////////////////
1235 /// Should be called at the end of custom streamer
1236 /// See TBufferJSON::ClassBegin for more details
1237 
1239 {
1240  DecrementLevel(0);
1241 }
1242 
1243 ////////////////////////////////////////////////////////////////////////////////
1244 /// Method indicates name and typename of class member,
1245 /// which should be now streamed in custom streamer
1246 /// Following combinations are supported:
1247 /// 1. name = "ClassName", typeName = 0 or typename==ClassName
1248 /// This is a case, when data of parent class "ClassName" should be streamed.
1249 /// For instance, if class directly inherited from TObject, custom
1250 /// streamer should include following code:
1251 /// b.ClassMember("TObject");
1252 /// TObject::Streamer(b);
1253 /// 2. Basic data type
1254 /// b.ClassMember("fInt","Int_t");
1255 /// b >> fInt;
1256 /// 3. Array of basic data types
1257 /// b.ClassMember("fArr","Int_t", 5);
1258 /// b.ReadFastArray(fArr, 5);
1259 /// 4. Object as data member
1260 /// b.ClassMemeber("fName","TString");
1261 /// fName.Streamer(b);
1262 /// 5. Pointer on object as data member
1263 /// b.ClassMemeber("fObj","TObject*");
1264 /// b.StreamObject(fObj);
1265 /// arrsize1 and arrsize2 arguments (when specified) indicate first and
1266 /// second dimension of array. Can be used for array of basic types.
1267 /// See ClassBegin() method for more details.
1268 
1269 void TBufferJSON::ClassMember(const char *name, const char *typeName,
1270  Int_t arrsize1, Int_t arrsize2)
1271 {
1272  if (typeName == 0) typeName = name;
1273 
1274  if ((name == 0) || (strlen(name) == 0)) {
1275  Error("ClassMember", "Invalid member name");
1276  return;
1277  }
1278 
1279  TString tname = typeName;
1280 
1281  Int_t typ_id = -1;
1282 
1283  if (strcmp(typeName, "raw:data") == 0)
1284  typ_id = TStreamerInfo::kMissing;
1285 
1286  if (typ_id < 0) {
1287  TDataType *dt = gROOT->GetType(typeName);
1288  if (dt != 0)
1289  if ((dt->GetType() > 0) && (dt->GetType() < 20))
1290  typ_id = dt->GetType();
1291  }
1292 
1293  if (typ_id < 0)
1294  if (strcmp(name, typeName) == 0) {
1295  TClass *cl = TClass::GetClass(tname.Data());
1296  if (cl != 0) typ_id = TStreamerInfo::kBase;
1297  }
1298 
1299  if (typ_id < 0) {
1300  Bool_t isptr = kFALSE;
1301  if (tname[tname.Length() - 1] == '*') {
1302  tname.Resize(tname.Length() - 1);
1303  isptr = kTRUE;
1304  }
1305  TClass *cl = TClass::GetClass(tname.Data());
1306  if (cl == 0) {
1307  Error("ClassMember", "Invalid class specifier %s", typeName);
1308  return;
1309  }
1310 
1311  if (cl->IsTObject())
1313  else
1314  typ_id = isptr ? TStreamerInfo::kAnyp : TStreamerInfo::kAny;
1315 
1316  if ((cl == TString::Class()) && !isptr)
1317  typ_id = TStreamerInfo::kTString;
1318  }
1319 
1320  TStreamerElement *elem = 0;
1321 
1322  if (typ_id == TStreamerInfo::kMissing) {
1323  elem = new TStreamerElement(name, "title", 0, typ_id, "raw:data");
1324  } else if (typ_id == TStreamerInfo::kBase) {
1325  TClass *cl = TClass::GetClass(tname.Data());
1326  if (cl != 0) {
1327  TStreamerBase *b = new TStreamerBase(tname.Data(), "title", 0);
1328  b->SetBaseVersion(cl->GetClassVersion());
1329  elem = b;
1330  }
1331  } else if ((typ_id > 0) && (typ_id < 20)) {
1332  elem = new TStreamerBasicType(name, "title", 0, typ_id, typeName);
1333  } else if ((typ_id == TStreamerInfo::kObject) ||
1334  (typ_id == TStreamerInfo::kTObject) ||
1335  (typ_id == TStreamerInfo::kTNamed)) {
1336  elem = new TStreamerObject(name, "title", 0, tname.Data());
1337  } else if (typ_id == TStreamerInfo::kObjectp) {
1338  elem = new TStreamerObjectPointer(name, "title", 0, tname.Data());
1339  } else if (typ_id == TStreamerInfo::kAny) {
1340  elem = new TStreamerObjectAny(name, "title", 0, tname.Data());
1341  } else if (typ_id == TStreamerInfo::kAnyp) {
1342  elem = new TStreamerObjectAnyPointer(name, "title", 0, tname.Data());
1343  } else if (typ_id == TStreamerInfo::kTString) {
1344  elem = new TStreamerString(name, "title", 0);
1345  }
1346 
1347  if (elem == 0) {
1348  Error("ClassMember", "Invalid combination name = %s type = %s",
1349  name, typeName);
1350  return;
1351  }
1352 
1353  if (arrsize1 > 0) {
1354  elem->SetArrayDim(arrsize2 > 0 ? 2 : 1);
1355  elem->SetMaxIndex(0, arrsize1);
1356  if (arrsize2 > 0)
1357  elem->SetMaxIndex(1, arrsize2);
1358  }
1359 
1360  // we indicate that there is no streamerinfo
1361  WorkWithElement(elem, -1);
1362 }
1363 
1364 ////////////////////////////////////////////////////////////////////////////////
1365 /// Function is converts TObject and TString structures to more compact representation
1366 
1367 void TBufferJSON::PerformPostProcessing(TJSONStackObj *stack,
1368  const TStreamerElement *elem)
1369 {
1370  if ((elem == 0) && stack->fIsPostProcessed) return;
1371  if (elem == 0) elem = stack->fElem;
1372  if (elem == 0) return;
1373 
1374  if (gDebug > 3)
1375  Info("PerformPostProcessing", "Element %s type %s",
1376  elem->GetName(), elem->GetTypeName());
1377 
1378  stack->fIsPostProcessed = kTRUE;
1379 
1380  // when element was written as separate object, close only braces and exit
1381  if (stack->fIsObjStarted) {
1382  AppendOutput("", "}");
1383  return;
1384  }
1385 
1386  const char *typname = elem->IsBase() ? elem->GetName() : elem->GetTypeName();
1387  Bool_t isTObject = (elem->GetType() == TStreamerInfo::kTObject) || (strcmp("TObject", typname) == 0);
1388  Bool_t isTString = elem->GetType() == TStreamerInfo::kTString;
1389  Bool_t isSTLstring = elem->GetType() == TStreamerInfo::kSTLstring;
1390  Bool_t isOffsetPArray = (elem->GetType() > TStreamerInfo::kOffsetP) && (elem->GetType() < TStreamerInfo::kOffsetP + 20);
1391 
1392  Bool_t isTArray = (strncmp("TArray", typname, 6) == 0);
1393 
1394  if (isTString || isSTLstring) {
1395  // just remove all kind of string length information
1396 
1397  if (gDebug > 3)
1398  Info("PerformPostProcessing", "reformat string value = '%s'", fValue.Data());
1399 
1400  stack->fValues.Delete();
1401  } else if (isOffsetPArray) {
1402  // basic array with [fN] comment
1403 
1404  if ((stack->fValues.GetLast() < 0) && (fValue == "0")) {
1405  fValue = "[]";
1406  } else if ((stack->fValues.GetLast() == 0) &&
1407  (strcmp(stack->fValues.Last()->GetName(), "1") == 0)) {
1408  stack->fValues.Delete();
1409  } else {
1410  Error("PerformPostProcessing", "Wrong values for kOffsetP type %s name %s",
1411  typname, (elem ? elem->GetName() : "---"));
1412  stack->fValues.Delete();
1413  fValue = "[]";
1414  }
1415  } else if (isTObject) {
1416  if (stack->fValues.GetLast() != 0) {
1417  if (gDebug > 0)
1418  Error("PerformPostProcessing", "When storing TObject, number of items %d not equal to 2", stack->fValues.GetLast());
1419  AppendOutput(",", "\"dummy\"");
1421  } else {
1422  AppendOutput(",", "\"fUniqueID\"");
1424  AppendOutput(stack->fValues.At(0)->GetName());
1425  AppendOutput(",", "\"fBits\"");
1427  }
1428 
1429  stack->fValues.Delete();
1430  } else if (isTArray) {
1431  // for TArray one deletes complete stack
1432  stack->fValues.Delete();
1433  }
1434 
1435  if (elem->IsBase() && (fValue.Length() == 0)) {
1436  // here base class data already completely stored
1437  return;
1438  }
1439 
1440  if (stack->fValues.GetLast() >= 0) {
1441  // append element blob data just as abstract array, user is responsible to decode it
1442  AppendOutput("[");
1443  for (Int_t n = 0; n <= stack->fValues.GetLast(); n++) {
1444  AppendOutput(stack->fValues.At(n)->GetName());
1446  }
1447  }
1448 
1449  if (fValue.Length() == 0) {
1450  AppendOutput("null");
1451  } else {
1453  fValue.Clear();
1454  }
1455 
1456  if (stack->fValues.GetLast() >= 0)
1457  AppendOutput("]");
1458 }
1459 
1460 ////////////////////////////////////////////////////////////////////////////////
1461 /// suppressed function of TBuffer
1462 
1464 {
1465  return 0;
1466 }
1467 
1468 ////////////////////////////////////////////////////////////////////////////////
1469 /// suppressed function of TBuffer
1470 
1472 {
1473 }
1474 
1475 ////////////////////////////////////////////////////////////////////////////////
1476 /// suppressed function of TBuffer
1477 
1479  const TClass * /*cl*/)
1480 {
1481  return 0;
1482 }
1483 
1484 ////////////////////////////////////////////////////////////////////////////////
1485 /// suppressed function of TBuffer
1486 
1488 {
1489  return 0;
1490 }
1491 
1492 ////////////////////////////////////////////////////////////////////////////////
1493 /// suppressed function of TBuffer
1494 
1496 {
1497 }
1498 
1499 ////////////////////////////////////////////////////////////////////////////////
1500 /// Skip class version from I/O buffer.
1501 
1503 {
1504  ReadVersion(0, 0, cl);
1505 }
1506 
1507 ////////////////////////////////////////////////////////////////////////////////
1508 /// read version value from buffer
1509 
1511  const TClass * /*cl*/)
1512 {
1513  Version_t res = 0;
1514 
1515  if (start) *start = 0;
1516  if (bcnt) *bcnt = 0;
1517 
1518  if (gDebug > 3) Info("ReadVersion", "Version = %d", res);
1519 
1520  return res;
1521 }
1522 
1523 ////////////////////////////////////////////////////////////////////////////////
1524 /// Ignored in TBufferJSON
1525 
1526 UInt_t TBufferJSON::WriteVersion(const TClass * /*cl*/, Bool_t /* useBcnt */)
1527 {
1528  return 0;
1529 }
1530 
1531 ////////////////////////////////////////////////////////////////////////////////
1532 /// Read object from buffer. Only used from TBuffer
1533 
1535 {
1536  return 0;
1537 }
1538 
1539 ////////////////////////////////////////////////////////////////////////////////
1540 /// Skip any kind of object from buffer
1541 
1543 {
1544 }
1545 
1546 ////////////////////////////////////////////////////////////////////////////////
1547 /// Write object to buffer. Only used from TBuffer
1548 
1549 void TBufferJSON::WriteObjectClass(const void *actualObjStart,
1550  const TClass *actualClass)
1551 {
1552  if (gDebug > 3)
1553  Info("WriteObjectClass", "Class %s", (actualClass ? actualClass->GetName() : " null"));
1554 
1555  JsonWriteObject(actualObjStart, actualClass);
1556 }
1557 
1558 #define TJSONPushValue() \
1559  if (fValue.Length() > 0) Stack()->PushValue(fValue);
1560 
1561 
1562 // macro to read array, which include size attribute
1563 #define TBufferJSON_ReadArray(tname, vname) \
1564  { \
1565  if (!vname) return 0; \
1566  return 1; \
1567  }
1568 
1569 ////////////////////////////////////////////////////////////////////////////////
1570 /// read a Float16_t from the buffer
1571 
1573 {
1574 }
1575 
1576 ////////////////////////////////////////////////////////////////////////////////
1577 /// read a Double32_t from the buffer
1578 
1580 {
1581 }
1582 
1583 ////////////////////////////////////////////////////////////////////////////////
1584 /// Read a Double32_t from the buffer when the factor and minimun value have
1585 /// been specified
1586 /// see comments about Double32_t encoding at TBufferFile::WriteDouble32().
1587 /// Currently TBufferJSON does not optimize space in this case.
1588 
1590  Double_t /* minvalue */)
1591 {
1592 }
1593 
1594 ////////////////////////////////////////////////////////////////////////////////
1595 /// Read a Float16_t from the buffer when the number of bits is specified
1596 /// (explicitly or not)
1597 /// see comments about Float16_t encoding at TBufferFile::WriteFloat16().
1598 /// Currently TBufferJSON does not optimize space in this case.
1599 
1601 {
1602 }
1603 
1604 ////////////////////////////////////////////////////////////////////////////////
1605 /// Read a Double32_t from the buffer when the factor and minimun value have
1606 /// been specified
1607 /// see comments about Double32_t encoding at TBufferFile::WriteDouble32().
1608 /// Currently TBufferJSON does not optimize space in this case.
1609 
1611  Double_t /* minvalue */)
1612 {
1613 }
1614 
1615 ////////////////////////////////////////////////////////////////////////////////
1616 /// Read a Double32_t from the buffer when the number of bits is specified
1617 /// (explicitly or not)
1618 /// see comments about Double32_t encoding at TBufferFile::WriteDouble32().
1619 /// Currently TBufferJSON does not optimize space in this case.
1620 
1622 {
1623 }
1624 
1625 ////////////////////////////////////////////////////////////////////////////////
1626 /// write a Float16_t to the buffer
1627 
1629 {
1630  TJSONPushValue();
1631 
1632  JsonWriteBasic(*f);
1633 }
1634 
1635 ////////////////////////////////////////////////////////////////////////////////
1636 /// write a Double32_t to the buffer
1637 
1639 {
1640  TJSONPushValue();
1641 
1642  JsonWriteBasic(*d);
1643 }
1644 
1645 ////////////////////////////////////////////////////////////////////////////////
1646 /// Read array of Bool_t from buffer
1647 
1649 {
1651 }
1652 
1653 ////////////////////////////////////////////////////////////////////////////////
1654 /// Read array of Char_t from buffer
1655 
1657 {
1659 }
1660 
1661 ////////////////////////////////////////////////////////////////////////////////
1662 /// Read array of UChar_t from buffer
1663 
1665 {
1667 }
1668 
1669 ////////////////////////////////////////////////////////////////////////////////
1670 /// Read array of Short_t from buffer
1671 
1673 {
1675 }
1676 
1677 ////////////////////////////////////////////////////////////////////////////////
1678 /// Read array of UShort_t from buffer
1679 
1681 {
1683 }
1684 
1685 ////////////////////////////////////////////////////////////////////////////////
1686 /// Read array of Int_t from buffer
1687 
1689 {
1691 }
1692 
1693 ////////////////////////////////////////////////////////////////////////////////
1694 /// Read array of UInt_t from buffer
1695 
1697 {
1699 }
1700 
1701 ////////////////////////////////////////////////////////////////////////////////
1702 /// Read array of Long_t from buffer
1703 
1705 {
1707 }
1708 
1709 ////////////////////////////////////////////////////////////////////////////////
1710 /// Read array of ULong_t from buffer
1711 
1713 {
1715 }
1716 
1717 ////////////////////////////////////////////////////////////////////////////////
1718 /// Read array of Long64_t from buffer
1719 
1721 {
1723 }
1724 
1725 ////////////////////////////////////////////////////////////////////////////////
1726 /// Read array of ULong64_t from buffer
1727 
1729 {
1731 }
1732 
1733 ////////////////////////////////////////////////////////////////////////////////
1734 /// Read array of Float_t from buffer
1735 
1737 {
1739 }
1740 
1741 ////////////////////////////////////////////////////////////////////////////////
1742 /// Read array of Double_t from buffer
1743 
1745 {
1747 }
1748 
1749 ////////////////////////////////////////////////////////////////////////////////
1750 /// Read array of Float16_t from buffer
1751 
1753 {
1755 }
1756 
1757 ////////////////////////////////////////////////////////////////////////////////
1758 /// Read array of Double32_t from buffer
1759 
1761 {
1763 }
1764 
1765 // dummy macro to read array from json buffer
1766 #define TBufferJSON_ReadStaticArray(vname) \
1767  { \
1768  if (!vname) return 0; \
1769  return 1; \
1770  }
1771 
1772 ////////////////////////////////////////////////////////////////////////////////
1773 /// Read array of Bool_t from buffer
1774 
1776 {
1778 }
1779 
1780 ////////////////////////////////////////////////////////////////////////////////
1781 /// Read array of Char_t from buffer
1782 
1784 {
1786 }
1787 
1788 ////////////////////////////////////////////////////////////////////////////////
1789 /// Read array of UChar_t from buffer
1790 
1792 {
1794 }
1795 
1796 ////////////////////////////////////////////////////////////////////////////////
1797 /// Read array of Short_t from buffer
1798 
1800 {
1802 }
1803 
1804 ////////////////////////////////////////////////////////////////////////////////
1805 /// Read array of UShort_t from buffer
1806 
1808 {
1810 }
1811 
1812 ////////////////////////////////////////////////////////////////////////////////
1813 /// Read array of Int_t from buffer
1814 
1816 {
1818 }
1819 
1820 ////////////////////////////////////////////////////////////////////////////////
1821 /// Read array of UInt_t from buffer
1822 
1824 {
1826 }
1827 
1828 ////////////////////////////////////////////////////////////////////////////////
1829 /// Read array of Long_t from buffer
1830 
1832 {
1834 }
1835 
1836 ////////////////////////////////////////////////////////////////////////////////
1837 /// Read array of ULong_t from buffer
1838 
1840 {
1842 }
1843 
1844 ////////////////////////////////////////////////////////////////////////////////
1845 /// Read array of Long64_t from buffer
1846 
1848 {
1850 }
1851 
1852 ////////////////////////////////////////////////////////////////////////////////
1853 /// Read array of ULong64_t from buffer
1854 
1856 {
1858 }
1859 
1860 ////////////////////////////////////////////////////////////////////////////////
1861 /// Read array of Float_t from buffer
1862 
1864 {
1866 }
1867 
1868 ////////////////////////////////////////////////////////////////////////////////
1869 /// Read array of Double_t from buffer
1870 
1872 {
1874 }
1875 
1876 ////////////////////////////////////////////////////////////////////////////////
1877 /// Read array of Float16_t from buffer
1878 
1880 {
1882 }
1883 
1884 ////////////////////////////////////////////////////////////////////////////////
1885 /// Read array of Double32_t from buffer
1886 
1888 {
1890 }
1891 
1892 // macro to read content of array, which not include size of array
1893 // macro also treat situation, when instead of one single array chain
1894 // of several elements should be produced
1895 #define TBufferJSON_ReadFastArray(vname) \
1896  { \
1897  if (n <= 0) return; \
1898  if (!vname) return; \
1899  }
1900 
1901 ////////////////////////////////////////////////////////////////////////////////
1902 /// read array of Bool_t from buffer
1903 
1905 {
1907 }
1908 
1909 ////////////////////////////////////////////////////////////////////////////////
1910 /// read array of Char_t from buffer
1911 
1913 {
1915 }
1916 
1917 ////////////////////////////////////////////////////////////////////////////////
1918 /// read array of Char_t from buffer
1919 
1921 {
1923 }
1924 
1925 ////////////////////////////////////////////////////////////////////////////////
1926 /// read array of UChar_t from buffer
1927 
1929 {
1931 }
1932 
1933 ////////////////////////////////////////////////////////////////////////////////
1934 /// read array of Short_t from buffer
1935 
1937 {
1939 }
1940 
1941 ////////////////////////////////////////////////////////////////////////////////
1942 /// read array of UShort_t from buffer
1943 
1945 {
1947 }
1948 
1949 ////////////////////////////////////////////////////////////////////////////////
1950 /// read array of Int_t from buffer
1951 
1953 {
1955 }
1956 
1957 ////////////////////////////////////////////////////////////////////////////////
1958 /// read array of UInt_t from buffer
1959 
1961 {
1963 }
1964 
1965 ////////////////////////////////////////////////////////////////////////////////
1966 /// read array of Long_t from buffer
1967 
1969 {
1971 }
1972 
1973 ////////////////////////////////////////////////////////////////////////////////
1974 /// read array of ULong_t from buffer
1975 
1977 {
1979 }
1980 
1981 ////////////////////////////////////////////////////////////////////////////////
1982 /// read array of Long64_t from buffer
1983 
1985 {
1987 }
1988 
1989 ////////////////////////////////////////////////////////////////////////////////
1990 /// read array of ULong64_t from buffer
1991 
1993 {
1995 }
1996 
1997 ////////////////////////////////////////////////////////////////////////////////
1998 /// read array of Float_t from buffer
1999 
2001 {
2003 }
2004 
2005 ////////////////////////////////////////////////////////////////////////////////
2006 /// read array of Double_t from buffer
2007 
2009 {
2011 }
2012 
2013 ////////////////////////////////////////////////////////////////////////////////
2014 /// read array of Float16_t from buffer
2015 
2017  TStreamerElement * /*ele*/)
2018 {
2020 }
2021 
2022 ////////////////////////////////////////////////////////////////////////////////
2023 /// read array of Float16_t from buffer
2024 
2026  Double_t /* factor */,
2027  Double_t /* minvalue */)
2028 {
2030 }
2031 
2032 ////////////////////////////////////////////////////////////////////////////////
2033 /// read array of Float16_t from buffer
2034 
2036 {
2038 }
2039 
2040 ////////////////////////////////////////////////////////////////////////////////
2041 /// read array of Double32_t from buffer
2042 
2044  TStreamerElement * /*ele*/)
2045 {
2047 }
2048 
2049 ////////////////////////////////////////////////////////////////////////////////
2050 /// read array of Double32_t from buffer
2051 
2053  Double_t /* factor */,
2054  Double_t /* minvalue */)
2055 {
2057 }
2058 
2059 ////////////////////////////////////////////////////////////////////////////////
2060 /// read array of Double32_t from buffer
2061 
2063 {
2065 }
2066 
2067 ////////////////////////////////////////////////////////////////////////////////
2068 /// redefined here to avoid warning message from gcc
2069 
2070 void TBufferJSON::ReadFastArray(void * /*start*/, const TClass * /*cl*/,
2071  Int_t /*n*/, TMemberStreamer * /*s*/,
2072  const TClass * /*onFileClass*/)
2073 {
2074 }
2075 
2076 ////////////////////////////////////////////////////////////////////////////////
2077 /// redefined here to avoid warning message from gcc
2078 
2079 void TBufferJSON::ReadFastArray(void ** /*startp*/, const TClass * /*cl*/,
2080  Int_t /*n*/, Bool_t /*isPreAlloc*/,
2081  TMemberStreamer * /*s*/,
2082  const TClass * /*onFileClass*/)
2083 {
2084 }
2085 
2086 
2087 #define TJSONWriteArrayContent(vname, arrsize) \
2088  { \
2089  fValue.Append("["); /* fJsonrCnt++; */ \
2090  for (Int_t indx=0;indx<arrsize;indx++) { \
2091  if (indx>0) fValue.Append(fArraySepar.Data()); \
2092  JsonWriteBasic(vname[indx]); \
2093  } \
2094  fValue.Append("]"); \
2095  }
2096 
2097 // macro to write array, which include size
2098 #define TBufferJSON_WriteArray(vname) \
2099  { \
2100  TJSONPushValue(); \
2101  TJSONWriteArrayContent(vname, n); \
2102  }
2103 
2104 ////////////////////////////////////////////////////////////////////////////////
2105 /// Write array of Bool_t to buffer
2106 
2108 {
2110 }
2111 
2112 ////////////////////////////////////////////////////////////////////////////////
2113 /// Write array of Char_t to buffer
2114 
2116 {
2118 }
2119 
2120 ////////////////////////////////////////////////////////////////////////////////
2121 /// Write array of UChar_t to buffer
2122 
2124 {
2126 }
2127 
2128 ////////////////////////////////////////////////////////////////////////////////
2129 /// Write array of Short_t to buffer
2130 
2132 {
2134 }
2135 
2136 ////////////////////////////////////////////////////////////////////////////////
2137 /// Write array of UShort_t to buffer
2138 
2140 {
2142 }
2143 
2144 ////////////////////////////////////////////////////////////////////////////////
2145 /// Write array of Int_ to buffer
2146 
2148 {
2150 }
2151 
2152 ////////////////////////////////////////////////////////////////////////////////
2153 /// Write array of UInt_t to buffer
2154 
2156 {
2158 }
2159 
2160 ////////////////////////////////////////////////////////////////////////////////
2161 /// Write array of Long_t to buffer
2162 
2164 {
2166 }
2167 
2168 ////////////////////////////////////////////////////////////////////////////////
2169 /// Write array of ULong_t to buffer
2170 
2172 {
2174 }
2175 
2176 ////////////////////////////////////////////////////////////////////////////////
2177 /// Write array of Long64_t to buffer
2178 
2180 {
2182 }
2183 
2184 ////////////////////////////////////////////////////////////////////////////////
2185 /// Write array of ULong64_t to buffer
2186 
2188 {
2190 }
2191 
2192 ////////////////////////////////////////////////////////////////////////////////
2193 /// Write array of Float_t to buffer
2194 
2196 {
2198 }
2199 
2200 ////////////////////////////////////////////////////////////////////////////////
2201 /// Write array of Double_t to buffer
2202 
2204 {
2206 }
2207 
2208 ////////////////////////////////////////////////////////////////////////////////
2209 /// Write array of Float16_t to buffer
2210 
2212  TStreamerElement * /*ele*/)
2213 {
2215 }
2216 
2217 ////////////////////////////////////////////////////////////////////////////////
2218 /// Write array of Double32_t to buffer
2219 
2221  TStreamerElement * /*ele*/)
2222 {
2224 }
2225 
2226 // write array without size attribute
2227 // macro also treat situation, when instead of one single array
2228 // chain of several elements should be produced
2229 #define TBufferJSON_WriteFastArray(vname) \
2230  { \
2231  TJSONPushValue(); \
2232  if (n <= 0) { /*fJsonrCnt++;*/ fValue.Append("[]"); return; } \
2233  TStreamerElement* elem = Stack(0)->fElem; \
2234  if ((elem != 0) && (elem->GetType()>TStreamerInfo::kOffsetL) && \
2235  (elem->GetType() < TStreamerInfo::kOffsetP) && \
2236  (elem->GetArrayLength() != n)) fExpectedChain = kTRUE; \
2237  if (fExpectedChain) { \
2238  TStreamerInfo* info = Stack(1)->fInfo; \
2239  Int_t startnumber = Stack(0)->fElemNumber; \
2240  fExpectedChain = kFALSE; \
2241  Int_t index(0); \
2242  while (index<n) { \
2243  elem = (TStreamerElement*)info->GetElements()->At(startnumber++);\
2244  if (index>0) JsonStartElement(elem); \
2245  if (elem->GetType()<TStreamerInfo::kOffsetL) { \
2246  JsonWriteBasic(vname[index]); \
2247  index++; \
2248  } else { \
2249  TJSONWriteArrayContent((vname+index), elem->GetArrayLength());\
2250  index+=elem->GetArrayLength(); \
2251  } \
2252  PerformPostProcessing(Stack(0), elem); \
2253  } \
2254  } else \
2255  if ((elem!=0) && (elem->GetArrayDim()>1) && (elem->GetArrayLength()==n)) { \
2256  TArrayI indexes(elem->GetArrayDim() - 1); \
2257  indexes.Reset(0); \
2258  Int_t cnt = 0; \
2259  while (cnt >= 0) { \
2260  if (indexes[cnt] >= elem->GetMaxIndex(cnt)) { \
2261  fValue.Append("]"); \
2262  indexes[cnt--] = 0; \
2263  if (cnt >= 0) indexes[cnt]++; \
2264  continue; \
2265  } \
2266  fValue.Append(indexes[cnt] == 0 ? "[" : fArraySepar.Data()); \
2267  if (++cnt == indexes.GetSize()) { \
2268  Int_t shift = 0; \
2269  for (Int_t k = 0; k < indexes.GetSize(); k++) \
2270  shift = shift * elem->GetMaxIndex(k) + indexes[k]; \
2271  Int_t len = elem->GetMaxIndex(indexes.GetSize()); \
2272  shift *= len; \
2273  TJSONWriteArrayContent((vname+shift), len); \
2274  indexes[--cnt]++; \
2275  } \
2276  } \
2277  } else { \
2278  TJSONWriteArrayContent(vname, n); \
2279  } \
2280  }
2281 
2282 ////////////////////////////////////////////////////////////////////////////////
2283 /// Write array of Bool_t to buffer
2284 
2286 {
2288 }
2289 
2290 ////////////////////////////////////////////////////////////////////////////////
2291 /// Write array of Char_t to buffer
2292 /// If array does not include any special characters,
2293 /// it will be reproduced as CharStar node with string as attribute
2294 
2296 {
2297  Bool_t asarray = fExpectedChain;
2298  if (Stack(0)->fElem != 0)
2299  if (Stack(0)->fElem->GetType() == TStreamerInfo::kOffsetP + TStreamerInfo::kChar) asarray = kTRUE;
2300 
2301  if (asarray) {
2303  } else {
2304  TJSONPushValue();
2305  JsonWriteConstChar(c, n);
2306  }
2307 }
2308 
2309 ////////////////////////////////////////////////////////////////////////////////
2310 /// Write array of Char_t to buffer
2311 
2313 {
2314  WriteFastArray(c, n);
2315 }
2316 
2317 
2318 ////////////////////////////////////////////////////////////////////////////////
2319 /// Write array of UChar_t to buffer
2320 
2322 {
2324 }
2325 
2326 ////////////////////////////////////////////////////////////////////////////////
2327 /// Write array of Short_t to buffer
2328 
2330 {
2332 }
2333 
2334 ////////////////////////////////////////////////////////////////////////////////
2335 /// Write array of UShort_t to buffer
2336 
2338 {
2340 }
2341 
2342 ////////////////////////////////////////////////////////////////////////////////
2343 /// Write array of Int_t to buffer
2344 
2346 {
2348 }
2349 
2350 ////////////////////////////////////////////////////////////////////////////////
2351 /// Write array of UInt_t to buffer
2352 
2354 {
2356 }
2357 
2358 ////////////////////////////////////////////////////////////////////////////////
2359 /// Write array of Long_t to buffer
2360 
2362 {
2364 }
2365 
2366 ////////////////////////////////////////////////////////////////////////////////
2367 /// Write array of ULong_t to buffer
2368 
2370 {
2372 }
2373 
2374 ////////////////////////////////////////////////////////////////////////////////
2375 /// Write array of Long64_t to buffer
2376 
2378 {
2380 }
2381 
2382 ////////////////////////////////////////////////////////////////////////////////
2383 /// Write array of ULong64_t to buffer
2384 
2386 {
2388 }
2389 
2390 ////////////////////////////////////////////////////////////////////////////////
2391 /// Write array of Float_t to buffer
2392 
2394 {
2396 }
2397 
2398 ////////////////////////////////////////////////////////////////////////////////
2399 /// Write array of Double_t to buffer
2400 
2402 {
2404 }
2405 
2406 ////////////////////////////////////////////////////////////////////////////////
2407 /// Write array of Float16_t to buffer
2408 
2410  TStreamerElement * /*ele*/)
2411 {
2413 }
2414 
2415 ////////////////////////////////////////////////////////////////////////////////
2416 /// Write array of Double32_t to buffer
2417 
2419  TStreamerElement * /*ele*/)
2420 {
2422 }
2423 
2424 ////////////////////////////////////////////////////////////////////////////////
2425 /// Recall TBuffer function to avoid gcc warning message
2426 
2427 void TBufferJSON::WriteFastArray(void *start, const TClass *cl, Int_t n,
2428  TMemberStreamer *streamer)
2429 {
2430  if (gDebug > 2)
2431  Info("WriteFastArray", "void *start cl %s n %d streamer %p",
2432  cl ? cl->GetName() : "---", n, streamer);
2433 
2434  if (streamer) {
2436  (*streamer)(*this, start, 0);
2437  return;
2438  }
2439 
2440  char *obj = (char *)start;
2441  if (!n) n = 1;
2442  int size = cl->Size();
2443 
2444  if (n > 1) {
2446  AppendOutput("[");
2447  /* fJsonrCnt++; */ // count array, but do not add to references
2448  }
2449 
2450  for (Int_t j = 0; j < n; j++, obj += size) {
2451  if (j > 0) AppendOutput(fArraySepar.Data());
2452 
2453  JsonWriteObject(obj, cl, kFALSE);
2454  }
2455 
2456  if (n > 1) {
2457  AppendOutput("]");
2458  }
2459 
2460 }
2461 
2462 ////////////////////////////////////////////////////////////////////////////////
2463 /// Recall TBuffer function to avoid gcc warning message
2464 
2466  Bool_t isPreAlloc, TMemberStreamer *streamer)
2467 {
2468  if (gDebug > 2)
2469  Info("WriteFastArray", "void **startp cl %s n %d streamer %p",
2470  cl->GetName(), n, streamer);
2471 
2472  if (streamer) {
2474  (*streamer)(*this, (void *)start, 0);
2475  return 0;
2476  }
2477 
2478  Int_t res = 0;
2479 
2480  if (n > 1) {
2482  AppendOutput("[");
2483  /* fJsonrCnt++; */ // count array, but do not add to references
2484  }
2485 
2486  if (!isPreAlloc) {
2487 
2488  for (Int_t j = 0; j < n; j++) {
2489  if (j > 0) AppendOutput(fArraySepar.Data());
2490  res |= WriteObjectAny(start[j], cl);
2491  }
2492 
2493  } else {
2494  //case //-> in comment
2495 
2496  for (Int_t j = 0; j < n; j++) {
2497  if (j > 0) AppendOutput(fArraySepar.Data());
2498 
2499  if (!start[j]) start[j] = ((TClass *)cl)->New();
2500  // ((TClass*)cl)->Streamer(start[j],*this);
2501  JsonWriteObject(start[j], cl, kFALSE);
2502  }
2503  }
2504 
2505  if (n > 1) {
2506  AppendOutput("]");
2507  }
2508 
2509  return res;
2510 }
2511 
2512 ////////////////////////////////////////////////////////////////////////////////
2513 /// stream object to/from buffer
2514 
2515 void TBufferJSON::StreamObject(void *obj, const std::type_info &typeinfo,
2516  const TClass * /* onFileClass */)
2517 {
2518  StreamObject(obj, TClass::GetClass(typeinfo));
2519 }
2520 
2521 ////////////////////////////////////////////////////////////////////////////////
2522 /// stream object to/from buffer
2523 
2524 void TBufferJSON::StreamObject(void *obj, const char *className,
2525  const TClass * /* onFileClass */)
2526 {
2527  StreamObject(obj, TClass::GetClass(className));
2528 }
2529 
2531 {
2532  // stream object to/from buffer
2533 
2534  StreamObject(obj, obj ? obj->IsA() : TObject::Class());
2535 }
2536 
2537 ////////////////////////////////////////////////////////////////////////////////
2538 /// stream object to/from buffer
2539 
2540 void TBufferJSON::StreamObject(void *obj, const TClass *cl,
2541  const TClass * /* onfileClass */)
2542 {
2543  if (gDebug > 3)
2544  Info("StreamObject", "Class: %s", (cl ? cl->GetName() : "none"));
2545 
2546  JsonWriteObject(obj, cl);
2547 }
2548 
2549 ////////////////////////////////////////////////////////////////////////////////
2550 /// Reads Bool_t value from buffer
2551 
2553 {
2554 }
2555 
2556 ////////////////////////////////////////////////////////////////////////////////
2557 /// Reads Char_t value from buffer
2558 
2560 {
2561 }
2562 
2563 ////////////////////////////////////////////////////////////////////////////////
2564 /// Reads UChar_t value from buffer
2565 
2567 {
2568 }
2569 
2570 ////////////////////////////////////////////////////////////////////////////////
2571 /// Reads Short_t value from buffer
2572 
2574 {
2575 }
2576 
2577 ////////////////////////////////////////////////////////////////////////////////
2578 /// Reads UShort_t value from buffer
2579 
2581 {
2582 }
2583 
2584 ////////////////////////////////////////////////////////////////////////////////
2585 /// Reads Int_t value from buffer
2586 
2588 {
2589 }
2590 
2591 ////////////////////////////////////////////////////////////////////////////////
2592 /// Reads UInt_t value from buffer
2593 
2595 {
2596 }
2597 
2598 ////////////////////////////////////////////////////////////////////////////////
2599 /// Reads Long_t value from buffer
2600 
2602 {
2603 }
2604 
2605 ////////////////////////////////////////////////////////////////////////////////
2606 /// Reads ULong_t value from buffer
2607 
2609 {
2610 }
2611 
2612 ////////////////////////////////////////////////////////////////////////////////
2613 /// Reads Long64_t value from buffer
2614 
2616 {
2617 }
2618 
2619 ////////////////////////////////////////////////////////////////////////////////
2620 /// Reads ULong64_t value from buffer
2621 
2623 {
2624 }
2625 
2626 ////////////////////////////////////////////////////////////////////////////////
2627 /// Reads Float_t value from buffer
2628 
2630 {
2631 }
2632 
2633 ////////////////////////////////////////////////////////////////////////////////
2634 /// Reads Double_t value from buffer
2635 
2637 {
2638 }
2639 
2640 ////////////////////////////////////////////////////////////////////////////////
2641 /// Reads array of characters from buffer
2642 
2644 {
2645 }
2646 
2647 ////////////////////////////////////////////////////////////////////////////////
2648 /// Reads a TString
2649 
2651 {
2652 }
2653 
2654 ////////////////////////////////////////////////////////////////////////////////
2655 /// Reads a std::string
2656 
2657 void TBufferJSON::ReadStdString(std::string &/*s*/)
2658 {
2659 }
2660 
2661 ////////////////////////////////////////////////////////////////////////////////
2662 /// Writes Bool_t value to buffer
2663 
2665 {
2666  TJSONPushValue();
2667 
2668  JsonWriteBasic(b);
2669 }
2670 
2671 ////////////////////////////////////////////////////////////////////////////////
2672 /// Writes Char_t value to buffer
2673 
2675 {
2676  TJSONPushValue();
2677 
2678  JsonWriteBasic(c);
2679 }
2680 
2681 ////////////////////////////////////////////////////////////////////////////////
2682 /// Writes UChar_t value to buffer
2683 
2685 {
2686  TJSONPushValue();
2687 
2688  JsonWriteBasic(c);
2689 }
2690 
2691 ////////////////////////////////////////////////////////////////////////////////
2692 /// Writes Short_t value to buffer
2693 
2695 {
2696  TJSONPushValue();
2697 
2698  JsonWriteBasic(h);
2699 }
2700 
2701 ////////////////////////////////////////////////////////////////////////////////
2702 /// Writes UShort_t value to buffer
2703 
2705 {
2706  TJSONPushValue();
2707 
2708  JsonWriteBasic(h);
2709 }
2710 
2711 ////////////////////////////////////////////////////////////////////////////////
2712 /// Writes Int_t value to buffer
2713 
2715 {
2716  TJSONPushValue();
2717 
2718  JsonWriteBasic(i);
2719 }
2720 
2721 ////////////////////////////////////////////////////////////////////////////////
2722 /// Writes UInt_t value to buffer
2723 
2725 {
2726  TJSONPushValue();
2727 
2728  JsonWriteBasic(i);
2729 }
2730 
2731 ////////////////////////////////////////////////////////////////////////////////
2732 /// Writes Long_t value to buffer
2733 
2735 {
2736  TJSONPushValue();
2737 
2738  JsonWriteBasic(l);
2739 }
2740 
2741 ////////////////////////////////////////////////////////////////////////////////
2742 /// Writes ULong_t value to buffer
2743 
2745 {
2746  TJSONPushValue();
2747 
2748  JsonWriteBasic(l);
2749 }
2750 
2751 ////////////////////////////////////////////////////////////////////////////////
2752 /// Writes Long64_t value to buffer
2753 
2755 {
2756  TJSONPushValue();
2757 
2758  JsonWriteBasic(l);
2759 }
2760 
2761 ////////////////////////////////////////////////////////////////////////////////
2762 /// Writes ULong64_t value to buffer
2763 
2765 {
2766  TJSONPushValue();
2767 
2768  JsonWriteBasic(l);
2769 }
2770 
2771 ////////////////////////////////////////////////////////////////////////////////
2772 /// Writes Float_t value to buffer
2773 
2775 {
2776  TJSONPushValue();
2777 
2778  JsonWriteBasic(f);
2779 }
2780 
2781 ////////////////////////////////////////////////////////////////////////////////
2782 /// Writes Double_t value to buffer
2783 
2785 {
2786  TJSONPushValue();
2787 
2788  JsonWriteBasic(d);
2789 }
2790 
2791 ////////////////////////////////////////////////////////////////////////////////
2792 /// Writes array of characters to buffer
2793 
2795 {
2796  TJSONPushValue();
2797 
2798  JsonWriteConstChar(c);
2799 }
2800 
2801 ////////////////////////////////////////////////////////////////////////////////
2802 /// Writes a TString
2803 
2805 {
2806  TJSONPushValue();
2807 
2808  JsonWriteConstChar(s.Data(), s.Length());
2809 }
2810 
2811 ////////////////////////////////////////////////////////////////////////////////
2812 /// Writes a std::string
2813 
2814 void TBufferJSON::WriteStdString(const std::string &s)
2815 {
2816  TJSONPushValue();
2817 
2818  JsonWriteConstChar(s.c_str(), s.length());
2819 }
2820 
2821 ////////////////////////////////////////////////////////////////////////////////
2822 /// converts Char_t to string and add to json value buffer
2823 
2825 {
2826  char buf[50];
2827  snprintf(buf, sizeof(buf), "%d", value);
2828  fValue.Append(buf);
2829 }
2830 
2831 ////////////////////////////////////////////////////////////////////////////////
2832 /// converts Short_t to string and add to json value buffer
2833 
2835 {
2836  char buf[50];
2837  snprintf(buf, sizeof(buf), "%hd", value);
2838  fValue.Append(buf);
2839 }
2840 
2841 ////////////////////////////////////////////////////////////////////////////////
2842 /// converts Int_t to string and add to json value buffer
2843 
2845 {
2846  char buf[50];
2847  snprintf(buf, sizeof(buf), "%d", value);
2848  fValue.Append(buf);
2849 }
2850 
2851 ////////////////////////////////////////////////////////////////////////////////
2852 /// converts Long_t to string and add to json value buffer
2853 
2855 {
2856  char buf[50];
2857  snprintf(buf, sizeof(buf), "%ld", value);
2858  fValue.Append(buf);
2859 }
2860 
2861 ////////////////////////////////////////////////////////////////////////////////
2862 /// converts Long64_t to string and add to json value buffer
2863 
2865 {
2866  char buf[50];
2867  snprintf(buf, sizeof(buf), FLong64, value);
2868  fValue.Append(buf);
2869 }
2870 
2871 ////////////////////////////////////////////////////////////////////////////////
2872 /// converts Float_t to string and add to json value buffer
2873 
2875 {
2876  char buf[200];
2877  if (value == floor(value))
2878  snprintf(buf, sizeof(buf), "%1.0f", value);
2879  else
2880  snprintf(buf, sizeof(buf), fgFloatFmt, value);
2881  fValue.Append(buf);
2882 }
2883 
2884 ////////////////////////////////////////////////////////////////////////////////
2885 /// converts Double_t to string and add to json value buffer
2886 
2888 {
2889  char buf[200];
2890  if (value == floor(value))
2891  snprintf(buf, sizeof(buf), "%1.0f", value);
2892  else
2893  snprintf(buf, sizeof(buf), fgFloatFmt, value);
2894  fValue.Append(buf);
2895 }
2896 
2897 ////////////////////////////////////////////////////////////////////////////////
2898 /// converts Bool_t to string and add to json value buffer
2899 
2901 {
2902  fValue.Append(value ? "true" : "false");
2903 }
2904 
2905 ////////////////////////////////////////////////////////////////////////////////
2906 /// converts UChar_t to string and add to json value buffer
2907 
2909 {
2910  char buf[50];
2911  snprintf(buf, sizeof(buf), "%u", value);
2912  fValue.Append(buf);
2913 }
2914 
2915 ////////////////////////////////////////////////////////////////////////////////
2916 /// converts UShort_t to string and add to json value buffer
2917 
2919 {
2920  char buf[50];
2921  snprintf(buf, sizeof(buf), "%hu", value);
2922  fValue.Append(buf);
2923 }
2924 
2925 ////////////////////////////////////////////////////////////////////////////////
2926 /// converts UInt_t to string and add to json value buffer
2927 
2929 {
2930  char buf[50];
2931  snprintf(buf, sizeof(buf), "%u", value);
2932  fValue.Append(buf);
2933 }
2934 
2935 ////////////////////////////////////////////////////////////////////////////////
2936 /// converts ULong_t to string and add to json value buffer
2937 
2939 {
2940  char buf[50];
2941  snprintf(buf, sizeof(buf), "%lu", value);
2942  fValue.Append(buf);
2943 }
2944 
2945 ////////////////////////////////////////////////////////////////////////////////
2946 /// converts ULong64_t to string and add to json value buffer
2947 
2949 {
2950  char buf[50];
2951  snprintf(buf, sizeof(buf), FULong64, value);
2952  fValue.Append(buf);
2953 }
2954 
2955 ////////////////////////////////////////////////////////////////////////////////
2956 /// writes string value, processing all kind of special characters
2957 
2958 void TBufferJSON::JsonWriteConstChar(const char* value, Int_t len)
2959 {
2960  fValue.Append("\"");
2961 
2962  if (value!=0) {
2963  if (len<0) len = strlen(value);
2964 
2965  for (Int_t n=0;n<len;n++) {
2966  char c = value[n];
2967  switch(c) {
2968  case '\n':
2969  fValue.Append("\\n");
2970  break;
2971  case '\t':
2972  fValue.Append("\\t");
2973  break;
2974  case '\"':
2975  fValue.Append("\\\"");
2976  break;
2977  case '\\':
2978  fValue.Append("\\\\");
2979  break;
2980  case '\b':
2981  fValue.Append("\\b");
2982  break;
2983  case '\f':
2984  fValue.Append("\\f");
2985  break;
2986  case '\r':
2987  fValue.Append("\\r");
2988  break;
2989  case '/':
2990  fValue.Append("\\/");
2991  break;
2992  default:
2993  if ((c > 31) && (c < 127))
2994  fValue.Append(c);
2995  else
2996  fValue.Append(TString::Format("\\u%04x", (unsigned) c));
2997  }
2998  }
2999  }
3000 
3001  fValue.Append("\"");
3002 }
3003 
3004 
3005 ////////////////////////////////////////////////////////////////////////////////
3006 /// set printf format for float/double members, default "%e"
3007 
3008 void TBufferJSON::SetFloatFormat(const char *fmt)
3009 {
3010  if (fmt == 0) fmt = "%e";
3011  fgFloatFmt = fmt;
3012 }
3013 
3014 ////////////////////////////////////////////////////////////////////////////////
3015 /// return current printf format for float/double members, default "%e"
3016 
3018 {
3019  return fgFloatFmt;
3020 }
3021 
3022 ////////////////////////////////////////////////////////////////////////////////
3023 /// Read one collection of objects from the buffer using the StreamerInfoLoopAction.
3024 /// The collection needs to be a split TClonesArray or a split vector of pointers.
3025 
3027  void *obj)
3028 {
3029  TVirtualStreamerInfo *info = sequence.fStreamerInfo;
3030  IncrementLevel(info);
3031 
3032  if (gDebug) {
3033  //loop on all active members
3034  TStreamerInfoActions::ActionContainer_t::const_iterator end = sequence.fActions.end();
3035  for (TStreamerInfoActions::ActionContainer_t::const_iterator iter = sequence.fActions.begin();
3036  iter != end; ++iter) {
3037  // Idea: Try to remove this function call as it is really needed only for JSON streaming.
3038  SetStreamerElementNumber((*iter).fConfiguration->fCompInfo->fElem, (*iter).fConfiguration->fCompInfo->fType);
3039  (*iter).PrintDebug(*this, obj);
3040  (*iter)(*this, obj);
3041  }
3042  } else {
3043  //loop on all active members
3044  TStreamerInfoActions::ActionContainer_t::const_iterator end = sequence.fActions.end();
3045  for (TStreamerInfoActions::ActionContainer_t::const_iterator iter = sequence.fActions.begin();
3046  iter != end; ++iter) {
3047  // Idea: Try to remove this function call as it is really needed only for JSON streaming.
3048  SetStreamerElementNumber((*iter).fConfiguration->fCompInfo->fElem, (*iter).fConfiguration->fCompInfo->fType);
3049  (*iter)(*this, obj);
3050  }
3051  }
3052  DecrementLevel(info);
3053  return 0;
3054 }
3055 
3056 ////////////////////////////////////////////////////////////////////////////////
3057 /// Read one collection of objects from the buffer using the StreamerInfoLoopAction.
3058 /// The collection needs to be a split TClonesArray or a split vector of pointers.
3059 
3061  void *start_collection, void *end_collection)
3062 {
3063  TVirtualStreamerInfo *info = sequence.fStreamerInfo;
3064  IncrementLevel(info);
3065 
3066  if (gDebug) {
3067  //loop on all active members
3068  TStreamerInfoActions::ActionContainer_t::const_iterator end = sequence.fActions.end();
3069  for (TStreamerInfoActions::ActionContainer_t::const_iterator iter = sequence.fActions.begin();
3070  iter != end; ++iter) {
3071  // Idea: Try to remove this function call as it is really needed only for JSON streaming.
3072  SetStreamerElementNumber((*iter).fConfiguration->fCompInfo->fElem, (*iter).fConfiguration->fCompInfo->fType);
3073  (*iter).PrintDebug(*this, *(char **)start_collection); // Warning: This limits us to TClonesArray and vector of pointers.
3074  (*iter)(*this, start_collection, end_collection);
3075  }
3076  } else {
3077  //loop on all active members
3078  TStreamerInfoActions::ActionContainer_t::const_iterator end = sequence.fActions.end();
3079  for (TStreamerInfoActions::ActionContainer_t::const_iterator iter = sequence.fActions.begin();
3080  iter != end; ++iter) {
3081  // Idea: Try to remove this function call as it is really needed only for JSON streaming.
3082  SetStreamerElementNumber((*iter).fConfiguration->fCompInfo->fElem, (*iter).fConfiguration->fCompInfo->fType);
3083  (*iter)(*this, start_collection, end_collection);
3084  }
3085  }
3086  DecrementLevel(info);
3087  return 0;
3088 }
3089 
3090 ////////////////////////////////////////////////////////////////////////////////
3091 /// Read one collection of objects from the buffer using the StreamerInfoLoopAction.
3092 
3094  void *start_collection, void *end_collection)
3095 {
3096  TVirtualStreamerInfo *info = sequence.fStreamerInfo;
3097  IncrementLevel(info);
3098 
3100  if (gDebug) {
3101 
3102  // Get the address of the first item for the PrintDebug.
3103  // (Performance is not essential here since we are going to print to
3104  // the screen anyway).
3105  void *arr0 = loopconfig->GetFirstAddress(start_collection, end_collection);
3106  // loop on all active members
3107  TStreamerInfoActions::ActionContainer_t::const_iterator end = sequence.fActions.end();
3108  for (TStreamerInfoActions::ActionContainer_t::const_iterator iter = sequence.fActions.begin();
3109  iter != end; ++iter) {
3110  // Idea: Try to remove this function call as it is really needed only for JSON streaming.
3111  SetStreamerElementNumber((*iter).fConfiguration->fCompInfo->fElem, (*iter).fConfiguration->fCompInfo->fType);
3112  (*iter).PrintDebug(*this, arr0);
3113  (*iter)(*this, start_collection, end_collection, loopconfig);
3114  }
3115  } else {
3116  //loop on all active members
3117  TStreamerInfoActions::ActionContainer_t::const_iterator end = sequence.fActions.end();
3118  for (TStreamerInfoActions::ActionContainer_t::const_iterator iter = sequence.fActions.begin();
3119  iter != end; ++iter) {
3120  // Idea: Try to remove this function call as it is really needed only for JSON streaming.
3121  SetStreamerElementNumber((*iter).fConfiguration->fCompInfo->fElem, (*iter).fConfiguration->fCompInfo->fType);
3122  (*iter)(*this, start_collection, end_collection, loopconfig);
3123  }
3124  }
3125  DecrementLevel(info);
3126  return 0;
3127 }
3128 
3129 
3130 ////////////////////////////////////////////////////////////////////////////////
3131 /// Interface to TStreamerInfo::WriteBufferClones.
3132 
3134 {
3135  Info("WriteClones", "Not yet tested");
3136 
3137  if (a != 0)
3138  JsonStreamCollection(a, a->IsA());
3139 
3140  return 0;
3141 }
3142 
3143 namespace {
3144  struct DynamicType {
3145  // Helper class to enable typeid on any address
3146  // Used in code similar to:
3147  // typeid( * (DynamicType*) void_ptr );
3148  virtual ~DynamicType() {}
3149  };
3150 }
3151 
3152 ////////////////////////////////////////////////////////////////////////////////
3153 /// Write object to I/O buffer.
3154 /// This function assumes that the value in 'obj' is the value stored in
3155 /// a pointer to a "ptrClass". The actual type of the object pointed to
3156 /// can be any class derived from "ptrClass".
3157 /// Return:
3158 /// 0: failure
3159 /// 1: success
3160 /// 2: truncated success (i.e actual class is missing. Only ptrClass saved.)
3161 
3162 Int_t TBufferJSON::WriteObjectAny(const void *obj, const TClass *ptrClass)
3163 {
3164  if (!obj) {
3165  WriteObjectClass(0, 0);
3166  return 1;
3167  }
3168 
3169  if (!ptrClass) {
3170  Error("WriteObjectAny", "ptrClass argument may not be 0");
3171  return 0;
3172  }
3173 
3174  TClass *clActual = ptrClass->GetActualClass(obj);
3175 
3176  if (clActual == 0) {
3177  // The ptrClass is a class with a virtual table and we have no
3178  // TClass with the actual type_info in memory.
3179 
3180  DynamicType *d_ptr = (DynamicType *)obj;
3181  Warning("WriteObjectAny",
3182  "An object of type %s (from type_info) passed through a %s pointer was truncated (due a missing dictionary)!!!",
3183  typeid(*d_ptr).name(), ptrClass->GetName());
3184  WriteObjectClass(obj, ptrClass);
3185  return 2;
3186  } else if (clActual && (clActual != ptrClass)) {
3187  const char *temp = (const char *) obj;
3188  temp -= clActual->GetBaseClassOffset(ptrClass);
3189  WriteObjectClass(temp, clActual);
3190  return 1;
3191  } else {
3192  WriteObjectClass(obj, ptrClass);
3193  return 1;
3194  }
3195 }
3196 
3197 ////////////////////////////////////////////////////////////////////////////////
3198 /// Function called by the Streamer functions to serialize object at p
3199 /// to buffer b. The optional argument info may be specified to give an
3200 /// alternative StreamerInfo instead of using the default StreamerInfo
3201 /// automatically built from the class definition.
3202 /// For more information, see class TStreamerInfo.
3203 
3204 Int_t TBufferJSON::WriteClassBuffer(const TClass *cl, void *pointer)
3205 {
3206 
3207  //build the StreamerInfo if first time for the class
3208  TStreamerInfo *sinfo = (TStreamerInfo *)const_cast<TClass *>(cl)->GetCurrentStreamerInfo();
3209  if (sinfo == 0) {
3210  //Have to be sure between the check and the taking of the lock if the current streamer has changed
3212  sinfo = (TStreamerInfo *)const_cast<TClass *>(cl)->GetCurrentStreamerInfo();
3213  if (sinfo == 0) {
3214  const_cast<TClass *>(cl)->BuildRealData(pointer);
3215  sinfo = new TStreamerInfo(const_cast<TClass *>(cl));
3216  const_cast<TClass *>(cl)->SetCurrentStreamerInfo(sinfo);
3217  const_cast<TClass *>(cl)->RegisterStreamerInfo(sinfo);
3218  if (gDebug > 0)
3219  printf("Creating StreamerInfo for class: %s, version: %d\n",
3220  cl->GetName(), cl->GetClassVersion());
3221  sinfo->Build();
3222  }
3223  } else if (!sinfo->IsCompiled()) {
3225  // Redo the test in case we have been victim of a data race on fIsCompiled.
3226  if (!sinfo->IsCompiled()) {
3227  const_cast<TClass *>(cl)->BuildRealData(pointer);
3228  sinfo->BuildOld();
3229  }
3230  }
3231 
3232  //write the class version number and reserve space for the byte count
3233  // UInt_t R__c = WriteVersion(cl, kTRUE);
3234 
3235  //NOTE: In the future Philippe wants this to happen via a custom action
3236  TagStreamerInfo(sinfo);
3237  ApplySequence(*(sinfo->GetWriteObjectWiseActions()), (char *)pointer);
3238 
3239  //write the byte count at the start of the buffer
3240  // SetByteCount(R__c, kTRUE);
3241 
3242  if (gDebug > 2)
3243  Info("WriteClassBuffer", "class: %s version %d done", cl->GetName(), cl->GetClassVersion());
3244  return 0;
3245 }
Abstract array base class.
Definition: TArray.h:33
Describe Streamer information for one class version.
Definition: TStreamerInfo.h:47
virtual UInt_t WriteVersion(const TClass *cl, Bool_t useBcnt=kFALSE)
Ignored in TBufferJSON.
TStreamerInfoActions::TActionSequence * GetWriteObjectWiseActions()
#define TBufferJSON_ReadFastArray(vname)
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 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()
const char * GetTypeName() const
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.
virtual const char * GetName() const
Return name of this collection.
virtual Bool_t InheritsFrom(const char *classname) const
Returns kTRUE if object inherits from class "classname".
Definition: TObject.cxx:488
short Version_t
Definition: RtypesCore.h:61
virtual void WriteLong64(Long64_t l)
Writes Long64_t value to buffer.
Int_t GetType() const
Definition: TDataType.h:70
Ssiz_t Length() const
Definition: TString.h:390
TLoopConfiguration * fLoopConfig
If this is a bundle of memberwise streaming action, this configures the looping.
Collectable string class.
Definition: TObjString.h:32
float Float_t
Definition: RtypesCore.h:53
Int_t GetLast() const
Return index of last object in array.
Definition: TObjArray.cxx:528
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:462
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 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...
Bool_t IsTObject() const
Return kTRUE is the class inherits from TObject.
Definition: TClass.cxx:5571
virtual void Info(const char *method, const char *msgfmt,...) const
Issue info message.
Definition: TObject.cxx:899
TString fArraySepar
depending from compression level, " : " or ":"
Definition: TBufferJSON.h:463
virtual void ReadFastArrayWithFactor(Float_t *ptr, Int_t n, Double_t factor, Double_t minvalue)
read array of Float16_t from buffer
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:461
virtual void WriteDouble(Double_t d)
Writes Double_t value to buffer.
virtual void ReadLong64(Long64_t &l)
Reads Long64_t value from buffer.
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
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
virtual void ReadFastArray(Bool_t *b, Int_t n)
read array of Bool_t from buffer
virtual void ReadStdString(std::string &s)
Reads a std::string.
int Int_t
Definition: RtypesCore.h:41
bool Bool_t
Definition: RtypesCore.h:59
TDataType * GetDataType() const
Definition: TDataMember.h:74
TArc * a
Definition: textangle.C:12
Bool_t IsaPointer() const
Return true if data member is a pointer.
const Bool_t kFALSE
Definition: Rtypes.h:92
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
virtual Bool_t IsBase() const
Return kTRUE if the element represent a base class.
virtual void SetArrayDim(Int_t dim)
Set number of array dimensions.
const char * Class
Definition: TXMLSetup.cxx:64
virtual void WriteFastArrayString(const Char_t *c, Int_t n)
Write array of Char_t to buffer.
Int_t GetMaxIndex(Int_t dim) const
Return maximum index for array dimension "dim".
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
const char * GetArrayIndex() const
If the data member is pointer and has a valid array size in its comments GetArrayIndex returns a stri...
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
const char * Data() const
Definition: TString.h:349
Int_t GetBaseClassOffset(const TClass *toBase, void *address=0, bool isDerivedObject=true)
Definition: TClass.cxx:2706
virtual void ReadChar(Char_t &c)
Reads Char_t value from buffer.
#define FULong64
Definition: TBufferJSON.cxx:72
const char * GetTrueTypeName() const
Get full type description of data member, e,g.: "class TDirectory*".
virtual void ReadFastArrayDouble32(Double_t *d, Int_t n, TStreamerElement *ele=0)
read array of Double32_t from buffer
#define TJSONPushValue()
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:454
virtual void ReadUShort(UShort_t &s)
Reads UShort_t value from buffer.
TClass * GetActualClass(const void *object) const
Return a pointer the the real class of the object.
Definition: TClass.cxx:2525
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.
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)
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:457
unsigned fJsonrCnt
map of recorded objects, used in JsonR to restore references
Definition: TBufferJSON.h:458
Int_t Atoi() const
Return integer value of string.
Definition: TString.cxx:1965
TObjArray fStack
counter for all objects and arrays
Definition: TBufferJSON.h:459
virtual void ReadUChar(UChar_t &c)
Reads UChar_t value from buffer.
TClass * GetClass() const
Ssiz_t Capacity() const
Definition: TString.h:337
#define TBufferJSON_ReadStaticArray(vname)
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition: TObject.cxx:925
Base class of the Configurations for the member wise looping routines.
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
#define TBufferJSON_WriteArray(vname)
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:464
virtual void ReadInt(Int_t &i)
Reads Int_t value from buffer.
TString fValue
current output buffer for json code
Definition: TBufferJSON.h:456
virtual void SetStreamerElementNumber(TStreamerElement *elem, Int_t comp_type)
Function is called from TStreamerInfo WriteBuffer and Readbuffer functions and add/verify next elemen...
TRealData * GetRealData(const char *name) const
Return pointer to TRealData element with name "name".
Definition: TClass.cxx:3276
virtual void * GetFirstAddress(void *start, const void *end) const =0
const char * GetTypeName() const
Get type of data member, e,g.: "class TDirectory*" -> "TDirectory".
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...
Int_t IndexOf(const TObject *obj) const
Definition: TObjArray.cxx:552
TObjArray * GetElements() const
void BuildOld()
rebuild the TStreamerInfo structure
virtual void TagStreamerInfo(TVirtualStreamerInfo *)
Definition: TBufferJSON.h:232
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
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:455
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
char * Form(const char *fmt,...)
virtual void SkipVersion(const TClass *cl=0)
Skip class version from I/O buffer.
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
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:51
The ROOT global object gROOT contains a list of all defined classes.
Definition: TClass.h:81
static const char * fgFloatFmt
stored value of setlocale(LC_NUMERIC), which should be recovered at the end
Definition: TBufferJSON.h:466
virtual void WriteUShort(UShort_t s)
Writes UShort_t value to buffer.
Version_t GetClassVersion() const
Definition: TClass.h:382
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
Int_t GetSize() const
Definition: TArray.h:49
void PerformPostProcessing(TJSONStackObj *stack, const TStreamerElement *elem=0)
Function is converts TObject and TString structures to more compact representation.
long Long_t
Definition: RtypesCore.h:50
Option_t * GetOption() const
Definition: TCollection.h:160
virtual void WriteFastArrayFloat16(const Float_t *d, Int_t n, TStreamerElement *ele=0)
Write array of Float16_t to buffer.
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/double 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 TClass * GetClassPointer() const
Returns a pointer to the TClass of this element.
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.
unsigned long long ULong64_t
Definition: RtypesCore.h:70
Bool_t fExpectedChain
stack of streamer infos
Definition: TBufferJSON.h:460
unsigned long ULong_t
Definition: RtypesCore.h:51
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.
you should not use this method at all Int_t Int_t Double_t Double_t Double_t e
Definition: TRolke.cxx:630
#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:2882
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:44
static void SetFloatFormat(const char *fmt="%e")
set printf format for float/double members, default "%e"
Int_t GetArrayDim() const
Return number of array dimensions.
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
virtual void WriteStdString(const std::string &s)
Writes a std::string.
virtual void WriteChar(Char_t c)
Writes Char_t value to buffer.
TObject * Last() const
Return the object in the last filled slot. Returns 0 if no entries.
Definition: TObjArray.cxx:479
An array of clone (identical) objects.
Definition: TClonesArray.h:32
virtual Int_t ReadArrayFloat16(Float_t *&f, TStreamerElement *ele=0)
Read array of Float16_t from buffer.
virtual TClass * GetClass() const =0
virtual void WriteCharP(const Char_t *c)
Writes array of characters to buffer.
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_ReadArray(tname, vname)
#define snprintf
Definition: civetweb.c:822
Int_t fBufSize
Definition: TBuffer.h:49
void Reset()
Definition: TArrayI.h:49
Int_t GetType() const
R__EXTERN Int_t gDebug
Definition: Rtypes.h:128
ROOT::ESTLType GetCollectionType() const
Return the &#39;type&#39; of the STL the TClass is representing.
Definition: TClass.cxx:2800
Bool_t IsBasic() const
Return true if data member is a basic type, e.g. char, int, long...
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
TDataMember * GetDataMember() const
Definition: TRealData.h:57
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
TObject * At(Int_t idx) const
Definition: TObjArray.h:167
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
Abstract Interface class describing Streamer information for one class.
const Bool_t kTRUE
Definition: Rtypes.h:91
Long_t GetThisOffset() const
Definition: TRealData.h:59
#define TBufferJSON_WriteFastArray(vname)
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.
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
Int_t Size() const
Return size of object of this class.
Definition: TClass.cxx:5344
const char * cnt
Definition: TXMLSetup.cxx:75
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...
TVirtualStreamerInfo * fStreamerInfo
StreamerInfo used to derive these actions.
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition: TObject.cxx:911