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