GDAL
cpl_json_streaming_writer.h
1 /******************************************************************************
2  *
3  * Project: CPL - Common Portability Library
4  * Purpose: JSon streaming writer
5  * Author: Even Rouault, even.rouault at spatialys.com
6  *
7  ******************************************************************************
8  * Copyright (c) 2019, Even Rouault <even.rouault at spatialys.com>
9  *
10  * Permission is hereby granted, free of charge, to any person obtaining a
11  * copy of this software and associated documentation files (the "Software"),
12  * to deal in the Software without restriction, including without limitation
13  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
14  * and/or sell copies of the Software, and to permit persons to whom the
15  * Software is furnished to do so, subject to the following conditions:
16  *
17  * The above copyright notice and this permission notice shall be included
18  * in all copies or substantial portions of the Software.
19  *
20  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
21  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
23  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
25  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
26  * DEALINGS IN THE SOFTWARE.
27  ****************************************************************************/
28 
29 #ifndef CPL_JSON_STREAMING_WRITER_H
30 #define CPL_JSON_STREAMING_WRITER_H
31 
34 #if defined(__cplusplus) && !defined(CPL_SUPRESS_CPLUSPLUS)
35 
36 #include <vector>
37 #include <string>
38 #include "cpl_port.h"
39 
40 class CPL_DLL CPLJSonStreamingWriter
41 {
42 public:
43  typedef void (*SerializationFuncType)(const char* pszTxt, void* pUserData);
44 
45 private:
46  CPLJSonStreamingWriter(const CPLJSonStreamingWriter&) = delete;
47  CPLJSonStreamingWriter& operator=(const CPLJSonStreamingWriter&) = delete;
48 
49  std::string m_osStr{};
50  SerializationFuncType m_pfnSerializationFunc = nullptr;
51  void* m_pUserData = nullptr;
52  bool m_bPretty = true;
53  std::string m_osIndent = std::string(" ");
54  std::string m_osIndentAcc{};
55  int m_nLevel = 0;
56  bool m_bNewLineEnabled = true;
57  struct State
58  {
59  bool bIsObj = false;
60  bool bFirstChild = true;
61  explicit State(bool bIsObjIn): bIsObj(bIsObjIn) {}
62  };
63  std::vector<State> m_states{};
64  bool m_bWaitForValue = false;
65 
66  void Print(const std::string& text);
67  void IncIndent();
68  void DecIndent();
69  static std::string FormatString(const std::string& str);
70  void EmitCommaIfNeeded();
71 
72 public:
73  CPLJSonStreamingWriter(SerializationFuncType pfnSerializationFunc,
74  void* pUserData);
75  ~CPLJSonStreamingWriter();
76 
77  void SetPrettyFormatting(bool bPretty) { m_bPretty = bPretty; }
78  void SetIndentationSize(int nSpaces);
79 
80  // cppcheck-suppress functionStatic
81  const std::string& GetString() const { return m_osStr; }
82 
83  void Add(const std::string& str);
84  void Add(const char* pszStr);
85  void Add(bool bVal);
86  void Add(int nVal) { Add(static_cast<GIntBig>(nVal)); }
87  void Add(unsigned int nVal) { Add(static_cast<GIntBig>(nVal)); }
88  void Add(GIntBig nVal);
89  void Add(GUInt64 nVal);
90  void Add(float fVal, int nPrecision = 9);
91  void Add(double dfVal, int nPrecision = 18);
92  void AddNull();
93 
94  void StartObj();
95  void EndObj();
96  void AddObjKey(const std::string& key);
97  struct CPL_DLL ObjectContext
98  {
99  CPLJSonStreamingWriter& m_serializer;
100 
101  ObjectContext(const ObjectContext &) = delete;
102  ObjectContext(ObjectContext&&) = default;
103 
104  explicit inline ObjectContext(CPLJSonStreamingWriter& serializer):
105  m_serializer(serializer) { m_serializer.StartObj(); }
106  ~ObjectContext() { m_serializer.EndObj(); }
107  };
108  inline ObjectContext MakeObjectContext() { return ObjectContext(*this); }
109 
110  void StartArray();
111  void EndArray();
112  struct CPL_DLL ArrayContext
113  {
114  CPLJSonStreamingWriter& m_serializer;
115  bool m_bForceSingleLine;
116  bool m_bNewLineEnabledBackup;
117 
118  ArrayContext(const ArrayContext &) = delete;
119  ArrayContext(ArrayContext&&) = default;
120 
121  inline explicit ArrayContext(CPLJSonStreamingWriter& serializer,
122  bool bForceSingleLine = false):
123  m_serializer(serializer),
124  m_bForceSingleLine(bForceSingleLine),
125  m_bNewLineEnabledBackup(serializer.GetNewLine())
126  {
127  if( m_bForceSingleLine )
128  serializer.SetNewline(false);
129  m_serializer.StartArray();
130 
131  }
132  ~ArrayContext()
133  {
134  m_serializer.EndArray();
135  if( m_bForceSingleLine )
136  m_serializer.SetNewline(m_bNewLineEnabledBackup);
137  }
138  };
139  inline ArrayContext MakeArrayContext(bool bForceSingleLine = false)
140  { return ArrayContext(*this, bForceSingleLine); }
141 
142  bool GetNewLine() const { return m_bNewLineEnabled; }
143  void SetNewline(bool bEnabled) { m_bNewLineEnabled = bEnabled; }
144 };
145 
146 #endif // __cplusplus
147 
150 #endif // CPL_JSON_STREAMING_WRITER_H
Core portability definitions for CPL.
GUIntBig GUInt64
Unsigned 64 bit integer type.
Definition: cpl_port.h:265
long long GIntBig
Large signed integer type (generally 64-bit integer type).
Definition: cpl_port.h:244