HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
UT_JSONWriter.h
Go to the documentation of this file.
1 /*
2  * PROPRIETARY INFORMATION. This software is proprietary to
3  * Side Effects Software Inc., and is not to be reproduced,
4  * transmitted, or disclosed in any way without written permission.
5  *
6  * NAME: UT_JSONWriter.h ( UT Library, C++)
7  *
8  * COMMENTS:
9  */
10 
11 #ifndef __UT_JSONWriter__
12 #define __UT_JSONWriter__
13 
14 #include "UT_API.h"
15 #include "UT_Compression.h"
16 #include "UT_IntArray.h"
17 #include "UT_JSONDefines.h"
18 #include "UT_NonCopyable.h"
19 #include "UT_Set.h"
20 #include "UT_StringMap.h"
21 #include "UT_WorkBuffer.h"
22 #include <SYS/SYS_Deprecated.h>
23 #include <SYS/SYS_TypeTraits.h>
24 #include <ostream>
25 #include <streambuf>
26 #include <string>
27 
28 class UT_Options;
29 class UT_BitArray;
30 class UT_JSONValue;
31 
32 /// @brief Class which writes ASCII or binary JSON streams
33 ///
34 /// The JSON format (http://www.json.org) is a generic way to store data.
35 /// Houdini extends JSON to a byte-stream binary encoding (see UT_JID for
36 /// details). The UT_JSONWriter class is used to write JSON (binary or
37 /// ASCII) to a stream.
38 /// @see UT_JID, UT_JSONValue, UT_AutoJSONWriter
40 {
41 public:
42  /// @param options @n
43  /// A UT_Options class which sets specific format options.
44  /// @see setOptions()
45  UT_JSONWriter(const UT_Options *options=0);
46  virtual ~UT_JSONWriter();
47 
48  UT_JSONWriter(const UT_JSONWriter &) = delete;
49  UT_JSONWriter &operator=(const UT_JSONWriter &) = delete;
50 
51  /// Allocate a JSON Writer which will fill a UT_WorkBuffer.
52  /// Please delete when finished with the writer.
53  static UT_JSONWriter *allocWriter(UT_WorkBuffer &buffer);
54 
55  /// Allocate a JSON Writer which writes to an output stream.
56  /// Please delete when finished with the writer.
57  static UT_JSONWriter *allocWriter(
58  std::ostream &os,
59  bool binary,
60  UT_CompressionType compression_type = UT_COMPRESSION_TYPE_NONE);
61 
62  /// Allocate a JSON Writer which writes to a named file.
63  /// Please delete when finished with the writer.
64  static UT_JSONWriter *allocWriter(
65  const char *filename,
66  bool binary,
67  UT_CompressionType compression_type = UT_COMPRESSION_TYPE_NONE);
68 
69  /// Allocate a JSON Writer which writes into a given UT_JSONValue. The
70  /// value will only be set properly at the conclusion of writing.
71  /// Please delete when finished with the writer.
72  static UT_JSONWriter *allocWriter(UT_JSONValue &value);
73 
74  /// Set formatting/control options base on the UT_Options. The following
75  /// options are scanned:
76  /// - @b int @b "json:precision" -- ASCII float precision [9].
77  /// Note half-precision floats will use half this precision, while double
78  /// precision will use twice the digits.
79  /// - @b int @b "json:indentstep" -- ASCII indent step for maps/arrays [8]
80  /// - @b int @b "json:textwidth" -- ASCII wrap lines after byte count [256]
81  /// - @b bool @b "json:comments" -- Allow comments in ASCII stream [false]
82  /// - @b bool @b "json:prettyprint" -- Pretty print ASCII stream [true]
83  /// - @b bool @b "json:usetokens" -- Binary string token compression [true]
84  /// - @b bool @b "json:prettycompact" -- Add a space after separators, a
85  /// more compact pretty print matching Python [false]
86  void setOptions(const UT_Options &options);
87 
88  /// Get the current options. This will set the token/values in
89  /// the UT_Options based on options from setOptions()
90  void getOptions(UT_Options &options) const;
91 
92  /// Direct access to options.
93  void setPrecision(int precision) { myPrecision = SYSmax(1, precision); }
94  int getPrecision() const { return myPrecision; }
95  void setIndentStep(int indentstep) { myIndentStep = indentstep; }
96  int getIndentStep() const { return myIndentStep; }
97  void setUseTokens(bool usetokens) { myTokenStrings = usetokens; }
98  bool getUseTokens() const { return myTokenStrings; }
99  void setTextWidth(int width) { myTextWidth = width; }
100  int getTextWidth() const { return myTextWidth; }
101  void setComments(bool comment) { myComments = comment; }
102  bool getComments() const { return myComments; }
103  void setPrettyPrint(bool prettyprint) { myPrettyPrint = prettyprint; }
104  bool getPrettyPrint() const { return myPrettyPrint; }
105  void setPrettyCompact(bool compact) { myPrettyCompact = compact; }
106  bool getPrettyCompact() const { return myPrettyCompact; }
107 
108  /// Turn the JSON writer into a binary JSON (bJSON) writer.
109  /// @warning This method must be called before any other data is written to
110  /// the JSON file. It's a @b good idea to call in the sub-class
111  /// constructor.
112  bool setBinary(bool bin);
113 
114  /// Return whether writing binary or ASCII JSON
115  bool getBinary() const { return myBinary; }
116 
117  /// Get the number of bytes written to output so far.
118  int64 getNumBytesWritten() const { return myCurrentFilePosition; }
119 
120  /// Start a new embedded file
121  void startNewFile();
122 
123  /// End a started embedded file
124  void endNewFile();
125 
126  /// Output a comment in the JSON stream. Not all JSON parsers (actually
127  /// very few) support comments. The json:comments must be enabled for this
128  /// statement to have any effect.
129  bool jsonComment(const char *format, ...)
131 
132  // Standard JSON types
133  /// Write a @b null to the stream
134  bool jsonNull();
135  /// Write true/false
136  bool jsonBool(bool value);
137  /// Write an integer value
138  bool jsonInt(int32 value);
139  /// Write a 64 bit integer value
140  bool jsonInt(int64 value);
141  /// Write a 64 bit integer as a 64 bit integer
142  bool jsonInt64(int64 value);
143  /// Write a 16 bit real
144  bool jsonReal(fpreal16 value);
145  bool jsonRealPreserveType(fpreal16 value);
146  /// Write a 32 bit real
147  bool jsonReal(fpreal32 value);
148  bool jsonRealPreserveType(fpreal32 value);
149  /// Write a 64 bit real
150  bool jsonReal(fpreal64 value);
151  bool jsonRealPreserveType(fpreal64 value);
152  /// Write a quoted string.
153  /// @warning Please use jsonKey() to write key strings.
154  /// @note Use jsonStringToken() to take advantage of token compression
155  /// (this can be turned off with the @c usetokens option in the
156  /// constructor).
157  /// @see UT_JID
158  bool jsonString(const char *value, int64 length=0);
159 
160  /// For binary streams, common strings can be output more efficiently using
161  /// the token interface. Token strings will appear as strings in ASCII
162  /// streams.
163  bool jsonStringToken(const UT_StringRef &value);
164  bool jsonStringToken(const char *value, int64 length)
165  {
167  if (length <= 0)
168  result.reference(value);
169  else
170  result.fastReferenceWithStrlen(value, length);
171  return jsonStringToken(result);
172  }
173 
174  /// @{
175  /// Write a standard JSON value to the stream. Overloaded method to allow
176  /// convenient use in templated code.
177  bool jsonValue(bool value) { return jsonBool(value); }
178  bool jsonValue(int8 value) { return jsonInt((int32)value); }
179  bool jsonValue(int16 value) { return jsonInt((int32)value); }
180  bool jsonValue(int32 value) { return jsonInt(value); }
181  bool jsonValue(unsigned value) { return jsonInt((int32)value); }
182  bool jsonValue(int64 value) { return jsonInt(value); }
183  bool jsonValue(fpreal16 value) { return jsonReal(value); }
184  bool jsonValue(fpreal32 value) { return jsonReal(value); }
185  bool jsonValue(fpreal64 value) { return jsonReal(value); }
186  bool jsonValue(const char *v) { return jsonStringToken(v); }
187  bool jsonValue(const UT_String &v)
188  { return jsonStringToken(v.c_str(), v.length()); }
189  bool jsonValue(const std::string &v)
190  { return jsonStringToken(v.c_str(), v.length()); }
191  bool jsonValue(const UT_StringRef &v) { return jsonStringToken(v); }
192  bool jsonValue(const UT_Int16Array &v)
193  { return jsonUniformArray(v); }
194  bool jsonValue(const UT_Int32Array &v)
195  { return jsonUniformArray(v); }
196  bool jsonValue(const UT_Int64Array &v)
197  { return jsonUniformArray(v); }
199  { return jsonUniformArray(v); }
201  { return jsonUniformArray(v); }
203  { return jsonStringTokenArray(v); }
204  bool jsonValue(const UT_JSONValue &v);
205  template <typename T>
206  bool jsonValue(const UT_Set<T>& v)
207  {
208  return jsonSetAsArray(v);
209  }
210  /// @}
211 
212  /// Begin a map/object dictionary
213  bool jsonBeginMap();
214  /// Write a quoted key for the object
215  /// @note Use jsonKeyToken() to take advantage of token compression
216  /// (this can be turned off with the @c usetokens option in the
217  /// constructor).
218  /// @see UT_JID
219  bool jsonKey(const char *value, int64 length=0);
220  /// For binary streams, common key strings can be output more efficiently
221  /// using the token interface. Token key strings will appear as strings in
222  /// ASCII streams.
223  bool jsonKeyToken(const UT_StringRef &value);
224  bool jsonKeyToken(const char *value, int64 length)
225  {
227  if (length <= 0)
228  result.reference(value);
229  else
230  result.fastReferenceWithStrlen(value, length);
231  return jsonKeyToken(result);
232  }
233 
234  /// @{
235  /// Convenience method to write the key/value pair to a map
236  template <typename T> SYS_FORCE_INLINE bool
237  jsonKeyValue(const UT_StringRef &key, const T &value)
238  {
239  bool ok = jsonKeyToken(key);
240  return ok && jsonValue(value);
241  }
242 
243  template <typename T> SYS_FORCE_INLINE bool
244  jsonKeyTokenValue(const UT_StringRef &key, const T &value)
245  {
246  bool ok = jsonKeyToken(key);
247  return ok && jsonValue(value);
248  }
249  /// @}
250 
251  /// End the object
252  bool jsonEndMap();
253 
254  /// Begin a generic array object
255  bool jsonBeginArray();
256  /// End a generic array object
257  /// By default, a new line will be output for pretty printing. The newline
258  /// can give a hint to omit the new line before the end of the array
259  /// marker.
260  bool jsonEndArray(bool newline=true);
261 
262  /// When writing binary JSON files, uniform arrays can be encoded without
263  /// repetition of the type information which results in a more compressed
264  /// data format.
265  ///
266  /// @c beingUniformArray() starts a uniform array.
267  /// The @c id should be one of:
268  /// - UT_JID_BOOL
269  /// - UT_JID_INT8
270  /// - UT_JID_INT16
271  /// - UT_JID_INT32
272  /// - UT_JID_INT64
273  /// - UT_JID_UINT8
274  /// - UT_JID_UINT16
275  /// - UT_JID_REAL16
276  /// - UT_JID_REAL32
277  /// - UT_JID_REAL64
278  /// - UT_JID_STRING
279  bool beginUniformArray(int64 length, UT_JID id);
280  /// Write a bool value to a uniform array. The bool values are packed into
281  /// a bit array (where each 32-bit word stores 32 bits).
282  bool uniformWrite(bool value);
283  /// Write an 8 bit integer value to the uniform array
284  bool uniformWrite(int8 value);
285  /// Write an 16 bit integer value to the uniform array
286  bool uniformWrite(int16 value);
287  /// Write an 32 bit integer value to the uniform array
288  bool uniformWrite(int32 value);
289  /// Write an 64 bit integer value to the uniform array
290  bool uniformWrite(int64 value);
291  /// Write an 16 bit float/real value to the uniform array
292  bool uniformWrite(fpreal16 value);
293  /// Write an 32 bit float/real value to the uniform array
294  bool uniformWrite(fpreal32 value);
295  /// Write an 64 bit float/real value to the uniform array
296  bool uniformWrite(fpreal64 value);
297  /// Write an 8 bit unsigned integer value to the uniform array
298  bool uniformWrite(uint8 value);
299  /// Write an 16 bit unsigned integer value to the uniform array
300  bool uniformWrite(uint16 value);
301  /// Write a string to the uniform array
302  bool uniformWrite(const char *value, int64 length=0);
303  /// Write a block of 8 bit integer values to the uniform array
304  bool uniformBlockWrite(const int8 *value, int64 count);
305  /// Write a block of 16 bit integer values to the uniform array
306  bool uniformBlockWrite(const int16 *value, int64 count);
307  /// Write a block of 32 bit integer values to the uniform array
308  bool uniformBlockWrite(const int32 *value, int64 count);
309  /// Write a block of 64 bit integer values to the uniform array
310  bool uniformBlockWrite(const int64 *value, int64 count);
311  /// Write a block of 16 bit float/real values to the uniform array
312  bool uniformBlockWrite(const fpreal16 *value, int64 count);
313  /// Write a block of 32 bit float/real values to the uniform array
314  bool uniformBlockWrite(const fpreal32 *value, int64 count);
315  /// Write a block of 64 bit float/real values to the uniform array
316  bool uniformBlockWrite(const fpreal64 *value, int64 count);
317  /// Write a block of 8 bit unsigned integer values to the uniform array
318  bool uniformBlockWrite(const uint8 *value, int64 count);
319  /// Write a block of 16 bit unsigned integer values to the uniform array
320  bool uniformBlockWrite(const uint16 *value, int64 count);
321  /// End the uniform array.
322  /// @param nwritten @n
323  /// If provided, the number of items written is returned.
324  /// @note The JSONWriter class will automatically clamp or fill the uniform
325  /// array with 0, but nwritten will return the actual number of calls to
326  /// uniformWrite().
327  bool endUniformArray(int64 *nwritten=0);
328 
329  /// Internally called to write raw data to output.
330  virtual bool writeData(const void *data, int64 bytes);
331 
332  /// Returns the JID that matches the given type.
333  SYS_DEPRECATED_REPLACE("21.5", "jidFromType<T>()")
334  static UT_JID jidFromValue(const bool *) { return UT_JID_BOOL; }
335  SYS_DEPRECATED_REPLACE("21.5", "jidFromType<T>()")
336  static UT_JID jidFromValue(const int8 *) { return UT_JID_INT8; }
337  SYS_DEPRECATED_REPLACE("21.5", "jidFromType<T>()")
338  static UT_JID jidFromValue(const int16 *) { return UT_JID_INT16; }
339  SYS_DEPRECATED_REPLACE("21.5", "jidFromType<T>()")
340  static UT_JID jidFromValue(const int32 *) { return UT_JID_INT32; }
341  SYS_DEPRECATED_REPLACE("21.5", "jidFromType<T>()")
342  static UT_JID jidFromValue(const int64 *) { return UT_JID_INT64; }
343  SYS_DEPRECATED_REPLACE("21.5", "jidFromType<T>()")
344  static UT_JID jidFromValue(const fpreal16 *) { return UT_JID_REAL16; }
345  SYS_DEPRECATED_REPLACE("21.5", "jidFromType<T>()")
346  static UT_JID jidFromValue(const fpreal32 *) { return UT_JID_REAL32; }
347  SYS_DEPRECATED_REPLACE("21.5", "jidFromType<T>()")
348  static UT_JID jidFromValue(const fpreal64 *) { return UT_JID_REAL64; }
349  SYS_DEPRECATED_REPLACE("21.5", "jidFromType<T>()")
350  static UT_JID jidFromValue(const uint8 *) { return UT_JID_UINT8; }
351  SYS_DEPRECATED_REPLACE("21.5", "jidFromType<T>()")
352  static UT_JID jidFromValue(const uint16 *) { return UT_JID_UINT16; }
353 
354  /// Returns the JID that matches the given type.
355  template <typename T>
356  static UT_JID jid()
357  {
358  if constexpr (SYSisSame<T, bool>())
359  return UT_JID_BOOL;
360  else if constexpr (SYSisSame<T, int8>())
361  return UT_JID_INT8;
362  else if constexpr (SYSisSame<T, int16>())
363  return UT_JID_INT16;
364  else if constexpr (SYSisSame<T, int32>())
365  return UT_JID_INT32;
366  else if constexpr (SYSisSame<T, int64>())
367  return UT_JID_INT64;
368  else if constexpr (SYSisSame<T, fpreal16>())
369  return UT_JID_REAL16;
370  else if constexpr (SYSisSame<T, fpreal32>())
371  return UT_JID_REAL32;
372  else if constexpr (SYSisSame<T, fpreal64>())
373  return UT_JID_REAL64;
374  else if constexpr (SYSisSame<T, uint8>())
375  return UT_JID_UINT8;
376  else if constexpr (SYSisSame<T, uint16>())
377  return UT_JID_UINT16;
378  else
379  {
380  // Note we can't use static_assert(false) here until newer compilers implement
381  // https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2593r1.html
382  static_assert(!SYSisSame<T, T>(), "Unsupported type for UT_JID");
383  }
384  }
385 
386  /// Efficent method of writing a uniform array of int8 values
387  bool jsonUniformArray(int64 length, const int8 *value);
388  /// Efficent method of writing a uniform array of int16 values
389  bool jsonUniformArray(int64 length, const int16 *value);
390  /// Efficent method of writing a uniform array of int32 values
391  bool jsonUniformArray(int64 length, const int32 *value);
392  /// Efficent method of writing a uniform array of int64 values
393  bool jsonUniformArray(int64 length, const int64 *value);
394  /// Efficent method of writing a uniform array of fpreal16 values
395  bool jsonUniformArray(int64 length, const fpreal16 *value);
396  /// Efficent method of writing a uniform array of fpreal32 values
397  bool jsonUniformArray(int64 length, const fpreal32 *value);
398  /// Efficent method of writing a uniform array of fpreal64 values
399  bool jsonUniformArray(int64 length, const fpreal64 *value);
400 
401  /// Efficent method of writing a uniform array of uint8 values
402  bool jsonUniformArray(int64 length, const uint8 *value);
403  /// Efficent method of writing a uniform array of uint16 values
404  bool jsonUniformArray(int64 length, const uint16 *value);
405 
406  /// Efficient method of writing a uniform array of bool values
407  bool jsonUniformArray(int64 length, const UT_BitArray &value,
408  bool verbose_ascii = false);
409 
410  /// @{
411  /// Convenience method for saving common array types
413  { return jsonUniformArray(a.size(), a.data()); }
415  { return jsonUniformArray(a.size(), a.data()); }
417  { return jsonUniformArray(a.size(), a.data()); }
419  { return jsonUniformArray(a.size(), a.data()); }
421  { return jsonUniformArray(a.size(), a.data()); }
422  /// @}
423 
424  /// Convenience method to save a set as an array of strings
425  template <typename T>
427  {
428  if (!jsonBeginArray())
429  return false;
430 
431  for (auto&& v : a)
432  jsonValue(v);
433 
434  return jsonEndArray();
435  }
436 
437  /// Convenience method to save an array of strings
438  bool jsonStringArray(const UT_StringArray &a);
439  /// Convenience method to save an array of strings (as tokens)
440  bool jsonStringTokenArray(const UT_StringArray &a);
441 
442  /// A TiledStream allows you to write a blob of binary data to a JSON
443  /// stream in an efficient manner. The data is buffered into uniform
444  /// arrays which are output into a standard JSON array. The resulting data
445  /// looks something like: @code
446  /// [ {options} tile1-data tile2-data ]
447  /// @endcode
448  /// The tile-data is written as JSON string objects. You can read these
449  /// yourself, or use the TiledStream in UT_JSONParser.
450  ///
451  /// You should never write to the JSONWriter while the TiledStream is open.
452  ///
453  /// An example of using this might be something like: @code
454  /// bool storeStream(UT_IStream &is)
455  /// {
456  /// UT_JSONWriter::TiledStream os(writer);
457  /// char buffer[128];
458  /// int nread;
459  /// while ((nread = is.bread(buffer, 128)) > 0)
460  /// if (!os.write(buffer, nread)) return false;
461  /// return true;
462  /// }
463  /// @endcode
464  class UT_API TiledStreamBuf : public std::streambuf
465  {
466  public:
468  ~TiledStreamBuf() override;
469 
470  TiledStreamBuf(const TiledStreamBuf &) = delete;
471  TiledStreamBuf &operator=(const TiledStreamBuf &) = delete;
472 
473  protected:
474  // write one character
475  int_type overflow(int_type c) override;
476 
477  // write multiple characters
478  std::streamsize xsputn(const char* s, std::streamsize num) override;
479 
480  private:
481  bool write(const void *data, exint bytes);
482  void close();
483 
484  bool writeTile(const char *data, exint bytes);
485  bool flush();
486  UT_JSONWriter &myWriter;
487  char *myBuffer;
488  exint myLength;
489  };
490 
491  class UT_API TiledStream : public std::ostream
492  {
493  public:
495  ~TiledStream() override;
496 
498 
499  private:
500  TiledStreamBuf myBuf;
501  };
502 
503 protected:
504  /// The sub-class must implement this method to write data
505  virtual bool subclassWriteData(const void* data, int64 bytes) = 0;
506 
507 protected:
508  /// Get the nesting level (i.e. how deeply nested in maps/arrays)
509  int getNesting() const { return myStack.entries(); }
510 private:
511  int precision16() const { return (myPrecision+1)/2; }
512  int precision32() const { return myPrecision; }
513  int precision64() const { return myPrecision*2; }
514  /// @private: ASCII indent
515  bool indent();
516  /// @private: ASCII prefix
517  bool prefix();
518  /// @private: Convenience method to write a UT_JID
519  bool writeId(UT_JID id);
520  /// @private: Convenience method to write an encoded length @see UT_JID
521  bool writeLength(int64 length);
522  /// @private: Write a token string
523  bool writeTokenString(const UT_StringRef &str);
524  /// @private: Write a string of data (not quoted)
525  bool writeString(const char *str, int64 bytes=0);
526  /// @private: Write a quoted string
527  bool quotedString(const char *str, int64 bytes=0);
528  /// @private: Write an ASCII "bool" value
529  bool writeAB(bool i);
530  /// @private: Write an ASCII "integer" value
531  bool writeAI(int64 i);
532  /// @private: Write an ASCII "float" value
533  bool writeAF(fpreal64 i, int precision);
534  /// @private: Write an ASCII "float" value and ensure it has a decimal point
535  bool writeAFPreserveType(fpreal64, int precision);
536  /// @private: Start an array (possibly uniform encoding)
537  bool startArray(UT_JID id, UT_JID type=UT_JID_NULL);
538  /// @private: Finish array
539  bool finishArray(UT_JID id, bool newline=true);
540  /// @private: Flush bits for a uniform array of bools
541  bool flushBits();
542  /// @private: Push nesting of map/array
543  void pushState(UT_JID id);
544  /// @private: Pop state
545  void popState(UT_JID id);
546  /// @private: Set the prefix for ASCII encoding
547  void setPrefix();
548  /// @private: Build indent string
549  void bumpIndent(int dir);
550  /// @private: New line & indent
551  bool newLine(bool force=false);
552 
553  /// Method to detail with long lines in ASCII files
554  bool countAndWrite(const void *data, int64 bytes);
555 
556  template <typename T> bool
557  uniformArrayI(UT_JID id, int64 length, const T *data);
558  template <typename T> bool
559  uniformArrayF(UT_JID id, int64 length, const T *data);
560  template <typename T> bool
561  uniformBlockWriteImplI(const T *data, int64 count);
562  template <typename T> bool
563  uniformBlockWriteImplF(const T *data, int64 count, int prec);
564 
565  enum
566  {
567  PREFIX_FIRST, // First element (no prefix)
568  PREFIX_ARRAY, // Use array prefix
569  PREFIX_MAP, // Use object prefix
570  };
571 
572  UT_IntArray myStack;
573  UT_WorkBuffer myIndentString;
574  // Note - carefully test performance if you are switching this to a
575  // different hash table like UT_ArrayStringMap (see bug 122906)
576  UT_StringMap<int64> myTokens;
577  UT_Int64Array myTokenCountStack;
578  int64 myCurrentFilePosition;
579  int64 myUWriteSize; // Uniform write size
580  int64 myUWriteCount; // Uniform entities written
581  int64 myTokenCount;
582  UT_JID myUniform; // Type of data for fixed array
583  uint32 myBitValue; // For packing bit arrays
584  int myBitCount;
585  int myPrefix;
586 
587  bool myBinary; // ASCII or binary
588 
589  // Options
590  int myPrecision; // ASCII float precision
591  int myIndentStep; // ASCII indent step
592  int myTextWidth; // ASCII max line length
593  bool myTokenStrings; // Use token strings
594  bool myComments; // Emit comments
595  bool myPrettyPrint; // Pretty print
596  bool myPrettyCompact; // Python style, spaces after sepators, no newlines.
597 
598  // State required for formatting.
599  bool myNewLine; // Pending newline, for line wrapping
600  bool myJoinNext;
601  int myIndent; // ASCII indent level
602  int myLineLength; // ASCII line length
603 };
604 
605 /// Convenience class to allocate a writer which is automatically deleted
606 /// For example: @code
607 /// bool save(UT_JSONWriter &w) { ... } // Method to save to standard writer
608 ///
609 /// bool save(UT_WorkBuffer &buffer) // Save to a UT_WorkBuffer
610 /// {
611 /// UT_AutoJSONWriter w(buffer);
612 /// return save(w);
613 /// }
614 /// bool save(UT_JSONValue &value) // Save to a UT_JSONValue
615 /// {
616 /// UT_AutoJSONWriter w(value);
617 /// return save(w);
618 /// }
619 /// @endcode
621 {
622 public:
623  /// Write directly to the UT_WorkBuffer
625  : myWriter(UT_JSONWriter::allocWriter(b))
626  {
627  }
628  /// Write to the given ostream (binary and optionally gzipped)
629  UT_AutoJSONWriter(std::ostream &os,
630  bool binary,
631  UT_CompressionType compression_type = UT_COMPRESSION_TYPE_NONE )
632  : myWriter(UT_JSONWriter::allocWriter(os, binary, compression_type))
633  {
634  }
635  /// Write to the given filename (binary and optionally gzipped)
636  UT_AutoJSONWriter(const char *filename,
637  bool binary,
638  UT_CompressionType compression_type = UT_COMPRESSION_TYPE_NONE)
639  : myWriter(UT_JSONWriter::allocWriter(filename, binary, compression_type))
640  {
641  }
642  /// Write directly to the UT_JSONValue
644  : myWriter(UT_JSONWriter::allocWriter(value))
645  {
646  }
648  {
649  delete myWriter;
650  }
651 
652  UT_AutoJSONWriter(const UT_AutoJSONWriter &) = delete;
653  UT_AutoJSONWriter &operator=(const UT_AutoJSONWriter &) = delete;
654 
655  /// @{
656  /// Access to the writer
657  UT_JSONWriter &writer() const { return *myWriter; }
658  UT_JSONWriter &operator*() const { return *myWriter; }
659  UT_JSONWriter *operator->() const { return myWriter; }
660  /// @}
661 
662  /// Allow implicit casting between an auto-writer and the underlying writer
663  operator UT_JSONWriter &() { return *myWriter; }
664 
665  /// Close the stream (causing all data to be flushed)
666  void close()
667  {
668  delete myWriter;
669  myWriter = NULL;
670  }
671 private:
672  UT_JSONWriter *myWriter;
673 };
674 
675 #endif
UT_JSONWriter & operator*() const
The following byte represents an 8 bit integer.
#define SYSmax(a, b)
Definition: SYS_Math.h:1952
bool jsonValue(bool value)
UT_AutoJSONWriter(std::ostream &os, bool binary, UT_CompressionType compression_type=UT_COMPRESSION_TYPE_NONE)
Write to the given ostream (binary and optionally gzipped)
unsigned short uint16
Definition: SYS_Types.h:38
No data follows the NULL token.
GT_API const UT_StringHolder filename
int64 getNumBytesWritten() const
Get the number of bytes written to output so far.
UT_AutoJSONWriter(UT_WorkBuffer &b)
Write directly to the UT_WorkBuffer.
int int32
Definition: SYS_Types.h:39
The following 4 bytes represent an 32 bit real (float)
bool jsonKeyToken(const char *value, int64 length)
UT_JID
The UT_JID enums are used in byte-stream encoding of binary JSON.
bool getUseTokens() const
Definition: UT_JSONWriter.h:98
bool getBinary() const
Return whether writing binary or ASCII JSON.
void writeData(std::ostream &os, const T *data, Index count, uint32_t compression)
Definition: Compression.h:364
const GLdouble * v
Definition: glcorearb.h:837
bool jsonValue(int32 value)
GLsizei const GLfloat * value
Definition: glcorearb.h:824
0x23 and 0x24 are reserved for future use (32/64 bit unsigned)
const GLuint GLenum const void * binary
Definition: glcorearb.h:1924
int64 exint
Definition: SYS_Types.h:125
GLboolean GLboolean GLboolean GLboolean a
Definition: glcorearb.h:1222
GLdouble s
Definition: glad.h:3009
GLuint GLsizei GLsizei * length
Definition: glcorearb.h:795
The following byte represents an unsigned 8 bit integer.
#define UT_API
Definition: UT_API.h:14
Class which writes ASCII or binary JSON streams.
Definition: UT_JSONWriter.h:39
**But if you need a result
Definition: thread.h:622
bool jsonValue(fpreal16 value)
void close() override
UT_JSONWriter & writer() const
bool jsonValue(const UT_String &v)
float fpreal32
Definition: SYS_Types.h:200
bool jsonUniformArray(const UT_Int32Array &a)
GLuint buffer
Definition: glcorearb.h:660
exint size() const
Definition: UT_Array.h:667
const char * c_str() const
Definition: UT_String.h:524
bool jsonValue(const char *v)
unsigned length() const
Return length of string.
Definition: UT_String.h:568
bool getComments() const
double fpreal64
Definition: SYS_Types.h:201
#define SYS_DEPRECATED_REPLACE(__V__, __R__)
unsigned char uint8
Definition: SYS_Types.h:36
void setPrettyPrint(bool prettyprint)
The following 8 bytes represent an 64 bit real (float)
The following 8 bytes represent an 64 bit integer.
bool jsonValue(const UT_Fpreal32Array &v)
bool jsonValue(const UT_StringRef &v)
GLint GLint GLsizei GLint GLenum GLenum type
Definition: glcorearb.h:108
The following 2 bytes represent an 16 bit integer.
static UT_JID jid()
Returns the JID that matches the given type.
SYS_FORCE_INLINE bool jsonKeyTokenValue(const UT_StringRef &key, const T &value)
void writeString(std::ostream &os, const Name &name)
Definition: Name.h:33
UT_AutoJSONWriter(UT_JSONValue &value)
Write directly to the UT_JSONValue.
#define SYS_PRINTF_CHECK_ATTRIBUTE(string_index, first_to_check)
Definition: SYS_Types.h:453
#define SYS_FORCE_INLINE
Definition: SYS_Inline.h:45
GLint GLint GLsizei GLint GLenum format
Definition: glcorearb.h:108
bool getPrettyCompact() const
bool jsonValue(int16 value)
#define UT_NON_COPYABLE(CLASS)
Define deleted copy constructor and assignment operator inside a class.
long long int64
Definition: SYS_Types.h:116
bool jsonValue(unsigned value)
signed char int8
Definition: SYS_Types.h:35
The following 4 bytes represent an 32 bit integer.
GLboolean GLboolean GLboolean b
Definition: glcorearb.h:1222
int getPrecision() const
Definition: UT_JSONWriter.h:94
void setPrettyCompact(bool compact)
void fastReferenceWithStrlen(const char *src, exint length)
old name of method:
bool jsonUniformArray(const UT_Int16Array &a)
bool jsonValue(const UT_Int16Array &v)
bool jsonUniformArray(const UT_Int64Array &a)
GLenum GLint GLint * precision
Definition: glcorearb.h:1925
void setComments(bool comment)
void setIndentStep(int indentstep)
Definition: UT_JSONWriter.h:95
bool jsonUniformArray(const UT_Fpreal32Array &a)
A map of string to various well defined value types.
Definition: UT_Options.h:87
SIM_API const UT_StringHolder force
bool jsonValue(const std::string &v)
short int16
Definition: SYS_Types.h:37
UT_CompressionType
T * data()
Definition: UT_Array.h:866
LeafData & operator=(const LeafData &)=delete
bool jsonSetAsArray(const UT_Set< T > &a)
Convenience method to save a set as an array of strings.
SYS_FORCE_INLINE bool jsonKeyValue(const UT_StringRef &key, const T &value)
bool jsonValue(int8 value)
bool jsonValue(const UT_Int32Array &v)
Class to store JSON objects as C++ objects.
Definition: UT_JSONValue.h:99
unsigned int uint32
Definition: SYS_Types.h:40
UT_JSONWriter * operator->() const
void reference(const char *src)
GLint GLsizei width
Definition: glcorearb.h:103
bool jsonValue(int64 value)
int getNesting() const
Get the nesting level (i.e. how deeply nested in maps/arrays)
GLubyte GLubyte GLubyte GLubyte w
Definition: glcorearb.h:857
int getIndentStep() const
Definition: UT_JSONWriter.h:96
bool jsonUniformArray(const UT_Fpreal64Array &a)
bool jsonValue(const UT_Fpreal64Array &v)
void setTextWidth(int width)
Definition: UT_JSONWriter.h:99
UT_AutoJSONWriter(const char *filename, bool binary, UT_CompressionType compression_type=UT_COMPRESSION_TYPE_NONE)
Write to the given filename (binary and optionally gzipped)
bool jsonValue(fpreal64 value)
The following 2 bytes represents an unsigned 16 bit integer.
void close()
Close the stream (causing all data to be flushed)
bool jsonValue(fpreal32 value)
bool getPrettyPrint() const
void setUseTokens(bool usetokens)
Definition: UT_JSONWriter.h:97
bool jsonValue(const UT_Set< T > &v)
bool jsonValue(const UT_StringArray &v)
GLint GLsizei count
Definition: glcorearb.h:405
Definition: format.h:1821
Definition: format.h:4365
int getTextWidth() const
void setPrecision(int precision)
Direct access to options.
Definition: UT_JSONWriter.h:93
bool jsonValue(const UT_Int64Array &v)