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