Logo ROOT   6.30.04
Reference Guide
 All Namespaces Files Pages
TBufferJSON.h
Go to the documentation of this file.
1 // $Id$
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 #ifndef ROOT_TBufferJSON
13 #define ROOT_TBufferJSON
14 
15 #include "TBufferText.h"
16 #include "TString.h"
17 
18 #include <deque>
19 #include <memory>
20 #include <string>
21 #include <vector>
22 
23 class TVirtualStreamerInfo;
24 class TStreamerInfo;
25 class TStreamerElement;
26 class TMemberStreamer;
27 class TDataMember;
28 class TJSONStackObj;
29 
30 class TBufferJSON final : public TBufferText {
31 
32 public:
33 
34  enum {
35  // values 0..3 are exclusive, define text formating, JSON data are same
36  kNoCompress = 0, ///< no any compression, maximal size of JSON (default)
37  kNoIndent = 1, ///< remove spaces in the beginning showing JSON indentation level
38  kNoNewLine = 2, ///< no indent plus skip newline symbols
39  kNoSpaces = 3, ///< no new lines plus remove all spaces around "," and ":" symbols
40 
41  kMapAsObject = 5, ///< store std::map, std::unodered_map as JSON object
42 
43  // algorithms for array compression - exclusive
44  kZeroSuppression = 10, ///< if array has much zeros in begin and/or end, they will be removed
45  kSameSuppression = 20, ///< zero suppression plus compress many similar values together
46  kBase64 = 30, ///< all binary arrays will be compressed with base64 coding, supported by JSROOT
47 
48  kSkipTypeInfo = 100 // do not store typenames in JSON
49  };
50 
51  TBufferJSON(TBuffer::EMode mode = TBuffer::kWrite);
52  virtual ~TBufferJSON();
53 
54  void SetCompact(int level);
55  void SetTypenameTag(const char *tag = "_typename");
56  void SetTypeversionTag(const char *tag = nullptr);
57  void SetSkipClassInfo(const TClass *cl);
58  Bool_t IsSkipClassInfo(const TClass *cl) const;
59 
60  TString StoreObject(const void *obj, const TClass *cl);
61  void *RestoreObject(const char *str, TClass **cl);
62 
63  static TString ConvertToJSON(const TObject *obj, Int_t compact = 0, const char *member_name = nullptr);
64  static TString
65  ConvertToJSON(const void *obj, const TClass *cl, Int_t compact = 0, const char *member_name = nullptr);
66  static TString ConvertToJSON(const void *obj, TDataMember *member, Int_t compact = 0, Int_t arraylen = -1);
67 
68  static Int_t ExportToFile(const char *filename, const TObject *obj, const char *option = nullptr);
69  static Int_t ExportToFile(const char *filename, const void *obj, const TClass *cl, const char *option = nullptr);
70 
71  static TObject *ConvertFromJSON(const char *str);
72  static void *ConvertFromJSONAny(const char *str, TClass **cl = nullptr);
73 
74  template <class T>
75  static TString ToJSON(const T *obj, Int_t compact = 0, const char *member_name = nullptr)
76  {
77  return ConvertToJSON(obj, TClass::GetClass<T>(), compact, member_name);
78  }
79 
80  template <class T>
81  static Bool_t FromJSON(T *&obj, const char *json)
82  {
83  if (obj)
84  return kFALSE;
85  obj = (T *)ConvertFromJSONChecked(json, TClass::GetClass<T>());
86  return obj != nullptr;
87  }
88 
89  template <class T>
90  static std::unique_ptr<T> FromJSON(const std::string &json)
91  {
92  T *obj = (T *)ConvertFromJSONChecked(json.c_str(), TClass::GetClass<T>());
93  return std::unique_ptr<T>(obj);
94  }
95 
96  // suppress class writing/reading
97 
98  TClass *ReadClass(const TClass *cl = nullptr, UInt_t *objTag = nullptr) final;
99  void WriteClass(const TClass *cl) final;
100 
101  // redefined virtual functions of TBuffer
102 
103  Version_t ReadVersion(UInt_t *start = nullptr, UInt_t *bcnt = nullptr, const TClass *cl = nullptr) final;
104  UInt_t WriteVersion(const TClass *cl, Bool_t useBcnt = kFALSE) final;
105 
106  void *ReadObjectAny(const TClass *clCast) final;
107  void SkipObjectAny() final;
108 
109  // these methods used in streamer info to indicate currently streamed element,
110  void IncrementLevel(TVirtualStreamerInfo *) final;
111  void SetStreamerElementNumber(TStreamerElement *elem, Int_t comp_type) final;
112  void DecrementLevel(TVirtualStreamerInfo *) final;
113 
114  void ClassBegin(const TClass *, Version_t = -1) final;
115  void ClassEnd(const TClass *) final;
116  void ClassMember(const char *name, const char *typeName = nullptr, Int_t arrsize1 = -1, Int_t arrsize2 = -1) final;
117 
118  Int_t ReadArray(Bool_t *&b) final;
119  Int_t ReadArray(Char_t *&c) final;
120  Int_t ReadArray(UChar_t *&c) final;
121  Int_t ReadArray(Short_t *&h) final;
122  Int_t ReadArray(UShort_t *&h) final;
123  Int_t ReadArray(Int_t *&i) final;
124  Int_t ReadArray(UInt_t *&i) final;
125  Int_t ReadArray(Long_t *&l) final;
126  Int_t ReadArray(ULong_t *&l) final;
127  Int_t ReadArray(Long64_t *&l) final;
128  Int_t ReadArray(ULong64_t *&l) final;
129  Int_t ReadArray(Float_t *&f) final;
130  Int_t ReadArray(Double_t *&d) final;
131 
132  Int_t ReadStaticArray(Bool_t *b) final;
133  Int_t ReadStaticArray(Char_t *c) final;
134  Int_t ReadStaticArray(UChar_t *c) final;
135  Int_t ReadStaticArray(Short_t *h) final;
136  Int_t ReadStaticArray(UShort_t *h) final;
137  Int_t ReadStaticArray(Int_t *i) final;
138  Int_t ReadStaticArray(UInt_t *i) final;
139  Int_t ReadStaticArray(Long_t *l) final;
140  Int_t ReadStaticArray(ULong_t *l) final;
141  Int_t ReadStaticArray(Long64_t *l) final;
142  Int_t ReadStaticArray(ULong64_t *l) final;
143  Int_t ReadStaticArray(Float_t *f) final;
144  Int_t ReadStaticArray(Double_t *d) final;
145 
146  void ReadFastArray(Bool_t *b, Int_t n) final;
147  void ReadFastArray(Char_t *c, Int_t n) final;
148  void ReadFastArrayString(Char_t *c, Int_t n) final;
149  void ReadFastArray(UChar_t *c, Int_t n) final;
150  void ReadFastArray(Short_t *h, Int_t n) final;
151  void ReadFastArray(UShort_t *h, Int_t n) final;
152  void ReadFastArray(Int_t *i, Int_t n) final;
153  void ReadFastArray(UInt_t *i, Int_t n) final;
154  void ReadFastArray(Long_t *l, Int_t n) final;
155  void ReadFastArray(ULong_t *l, Int_t n) final;
156  void ReadFastArray(Long64_t *l, Int_t n) final;
157  void ReadFastArray(ULong64_t *l, Int_t n) final;
158  void ReadFastArray(Float_t *f, Int_t n) final;
159  void ReadFastArray(Double_t *d, Int_t n) final;
160  void ReadFastArray(void *start, const TClass *cl, Int_t n = 1, TMemberStreamer *s = nullptr,
161  const TClass *onFileClass = nullptr) final;
162  void ReadFastArray(void **startp, const TClass *cl, Int_t n = 1, Bool_t isPreAlloc = kFALSE,
163  TMemberStreamer *s = nullptr, const TClass *onFileClass = nullptr) final;
164 
165  void WriteArray(const Bool_t *b, Int_t n) final;
166  void WriteArray(const Char_t *c, Int_t n) final;
167  void WriteArray(const UChar_t *c, Int_t n) final;
168  void WriteArray(const Short_t *h, Int_t n) final;
169  void WriteArray(const UShort_t *h, Int_t n) final;
170  void WriteArray(const Int_t *i, Int_t n) final;
171  void WriteArray(const UInt_t *i, Int_t n) final;
172  void WriteArray(const Long_t *l, Int_t n) final;
173  void WriteArray(const ULong_t *l, Int_t n) final;
174  void WriteArray(const Long64_t *l, Int_t n) final;
175  void WriteArray(const ULong64_t *l, Int_t n) final;
176  void WriteArray(const Float_t *f, Int_t n) final;
177  void WriteArray(const Double_t *d, Int_t n) final;
178 
179  void WriteFastArray(const Bool_t *b, Int_t n) final;
180  void WriteFastArray(const Char_t *c, Int_t n) final;
181  void WriteFastArrayString(const Char_t *c, Int_t n) final;
182  void WriteFastArray(const UChar_t *c, Int_t n) final;
183  void WriteFastArray(const Short_t *h, Int_t n) final;
184  void WriteFastArray(const UShort_t *h, Int_t n) final;
185  void WriteFastArray(const Int_t *i, Int_t n) final;
186  void WriteFastArray(const UInt_t *i, Int_t n) final;
187  void WriteFastArray(const Long_t *l, Int_t n) final;
188  void WriteFastArray(const ULong_t *l, Int_t n) final;
189  void WriteFastArray(const Long64_t *l, Int_t n) final;
190  void WriteFastArray(const ULong64_t *l, Int_t n) final;
191  void WriteFastArray(const Float_t *f, Int_t n) final;
192  void WriteFastArray(const Double_t *d, Int_t n) final;
193  void WriteFastArray(void *start, const TClass *cl, Int_t n = 1, TMemberStreamer *s = nullptr) final;
194  Int_t WriteFastArray(void **startp, const TClass *cl, Int_t n = 1, Bool_t isPreAlloc = kFALSE,
195  TMemberStreamer *s = nullptr) final;
196 
197  void StreamObject(void *obj, const TClass *cl, const TClass *onFileClass = nullptr) final;
198  using TBufferText::StreamObject;
199 
200  void ReadBool(Bool_t &b) final;
201  void ReadChar(Char_t &c) final;
202  void ReadUChar(UChar_t &c) final;
203  void ReadShort(Short_t &s) final;
204  void ReadUShort(UShort_t &s) final;
205  void ReadInt(Int_t &i) final;
206  void ReadUInt(UInt_t &i) final;
207  void ReadLong(Long_t &l) final;
208  void ReadULong(ULong_t &l) final;
209  void ReadLong64(Long64_t &l) final;
210  void ReadULong64(ULong64_t &l) final;
211  void ReadFloat(Float_t &f) final;
212  void ReadDouble(Double_t &d) final;
213  void ReadCharP(Char_t *c) final;
214  void ReadTString(TString &s) final;
215  void ReadStdString(std::string *s) final;
216  using TBuffer::ReadStdString;
217  void ReadCharStar(char *&s) final;
218 
219  void WriteBool(Bool_t b) final;
220  void WriteChar(Char_t c) final;
221  void WriteUChar(UChar_t c) final;
222  void WriteShort(Short_t s) final;
223  void WriteUShort(UShort_t s) final;
224  void WriteInt(Int_t i) final;
225  void WriteUInt(UInt_t i) final;
226  void WriteLong(Long_t l) final;
227  void WriteULong(ULong_t l) final;
228  void WriteLong64(Long64_t l) final;
229  void WriteULong64(ULong64_t l) final;
230  void WriteFloat(Float_t f) final;
231  void WriteDouble(Double_t d) final;
232  void WriteCharP(const Char_t *c) final;
233  void WriteTString(const TString &s) final;
234  void WriteStdString(const std::string *s) final;
235  using TBuffer::WriteStdString;
236  void WriteCharStar(char *s) final;
237 
238  TVirtualStreamerInfo *GetInfo() final;
239 
240  // end of redefined virtual functions
241 
242  void ReadBaseClass(void *start, TStreamerBase *elem) final;
243 
244 protected:
245  // redefined protected virtual functions
246 
247  void WriteObjectClass(const void *actualObjStart, const TClass *actualClass, Bool_t cacheReuse) final;
248 
249  // end redefined protected virtual functions
250 
251  static void *ConvertFromJSONChecked(const char *str, const TClass *expectedClass);
252 
253  TString JsonWriteMember(const void *ptr, TDataMember *member, TClass *memberClass, Int_t arraylen);
254 
255  TJSONStackObj *PushStack(Int_t inclevel = 0, void *readnode = nullptr);
256  TJSONStackObj *PopStack();
257  TJSONStackObj *Stack() { return fStack.back().get(); }
258 
259  void WorkWithClass(TStreamerInfo *info, const TClass *cl = nullptr);
260  void WorkWithElement(TStreamerElement *elem, Int_t);
261 
262  void JsonDisablePostprocessing();
263  Int_t JsonSpecialClass(const TClass *cl) const;
264 
265  TJSONStackObj *JsonStartObjectWrite(const TClass *obj_class, TStreamerInfo *info = nullptr);
266 
267  void JsonStartElement(const TStreamerElement *elem, const TClass *base_class);
268 
269  void PerformPostProcessing(TJSONStackObj *stack, const TClass *obj_cl = nullptr);
270 
271  void JsonWriteBasic(Char_t value);
272  void JsonWriteBasic(Short_t value);
273  void JsonWriteBasic(Int_t value);
274  void JsonWriteBasic(Long_t value);
275  void JsonWriteBasic(Long64_t value);
276  void JsonWriteBasic(Float_t value);
277  void JsonWriteBasic(Double_t value);
278  void JsonWriteBasic(Bool_t value);
279  void JsonWriteBasic(UChar_t value);
280  void JsonWriteBasic(UShort_t value);
281  void JsonWriteBasic(UInt_t value);
282  void JsonWriteBasic(ULong_t value);
283  void JsonWriteBasic(ULong64_t value);
284 
285  void JsonWriteConstChar(const char *value, Int_t len = -1, const char * /*typname*/ = nullptr);
286 
287  void JsonWriteObject(const void *obj, const TClass *objClass, Bool_t check_map = kTRUE);
288 
289  void JsonWriteCollection(TCollection *obj, const TClass *objClass);
290 
291  void JsonReadCollection(TCollection *obj, const TClass *objClass);
292 
293  void JsonReadTObjectMembers(TObject *obj, void *node = nullptr);
294 
295  void *JsonReadObject(void *obj, const TClass *objClass = nullptr, TClass **readClass = nullptr);
296 
297  void AppendOutput(const char *line0, const char *line1 = nullptr);
298 
299  void JsonPushValue();
300 
301  template <typename T>
302  R__ALWAYS_INLINE void JsonWriteArrayCompress(const T *vname, Int_t arrsize, const char *typname);
303 
304  template <typename T>
305  R__ALWAYS_INLINE void JsonReadBasic(T &value);
306 
307  template <typename T>
308  R__ALWAYS_INLINE Int_t JsonReadArray(T *value);
309 
310  template <typename T>
311  R__ALWAYS_INLINE void JsonReadFastArray(T *arr, Int_t arrsize, bool asstring = false);
312 
313  template <typename T>
314  R__ALWAYS_INLINE void JsonWriteFastArray(const T *arr, Int_t arrsize, const char *typname,
315  void (TBufferJSON::*method)(const T *, Int_t, const char *));
316 
317  TString fOutBuffer; ///<! main output buffer for json code
318  TString *fOutput{nullptr}; ///<! current output buffer for json code
319  TString fValue; ///<! buffer for current value
320  unsigned fJsonrCnt{0}; ///<! counter for all objects, used for referencing
321  std::deque<std::unique_ptr<TJSONStackObj>> fStack; ///<! hierarchy of currently streamed element
322  Int_t fCompact{0}; ///<! 0 - no any compression, 1 - no spaces in the begin, 2 - no new lines, 3 - no spaces at all
323  Bool_t fMapAsObject{kFALSE}; ///<! when true, std::map will be converted into JSON object
324  TString fSemicolon; ///<! depending from compression level, " : " or ":"
325  Int_t fArrayCompact{0}; ///<! 0 - no array compression, 1 - exclude leading/trailing zeros, 2 - check value repetition
326  TString fArraySepar; ///<! depending from compression level, ", " or ","
327  TString fNumericLocale; ///<! stored value of setlocale(LC_NUMERIC), which should be recovered at the end
328  TString fTypeNameTag; ///<! JSON member used for storing class name, when empty - no class name will be stored
329  TString fTypeVersionTag; ///<! JSON member used to store class version, default empty
330  std::vector<const TClass *> fSkipClasses; ///<! list of classes, which class info is not stored
331 
332  ClassDefOverride(TBufferJSON, 0) // a specialized TBuffer to only write objects into JSON format
333 };
334 
335 #endif