/src/gdal/port/cpl_json_streaming_parser.h
Line | Count | Source (jump to first uncovered line) |
1 | | /****************************************************************************** |
2 | | * |
3 | | * Project: CPL - Common Portability Library |
4 | | * Purpose: JSon streaming parser |
5 | | * Author: Even Rouault, even.rouault at spatialys.com |
6 | | * |
7 | | ****************************************************************************** |
8 | | * Copyright (c) 2017, Even Rouault <even.rouault at spatialys.com> |
9 | | * |
10 | | * SPDX-License-Identifier: MIT |
11 | | ****************************************************************************/ |
12 | | |
13 | | #ifndef CPL_JSON_STREAMIN_PARSER_H |
14 | | #define CPL_JSON_STREAMIN_PARSER_H |
15 | | |
16 | | /*! @cond Doxygen_Suppress */ |
17 | | |
18 | | #if defined(__cplusplus) && !defined(CPL_SUPRESS_CPLUSPLUS) |
19 | | |
20 | | #include <vector> |
21 | | #include <string> |
22 | | #include "cpl_port.h" |
23 | | |
24 | | class CPL_DLL CPLJSonStreamingParser |
25 | | { |
26 | | public: |
27 | | CPLJSonStreamingParser(); |
28 | | virtual ~CPLJSonStreamingParser(); |
29 | | |
30 | | void SetMaxDepth(size_t nVal); |
31 | | void SetMaxStringSize(size_t nVal); |
32 | | |
33 | | bool ExceptionOccurred() const |
34 | 0 | { |
35 | 0 | return m_bExceptionOccurred; |
36 | 0 | } |
37 | | |
38 | | static std::string GetSerializedString(const char *pszStr); |
39 | | |
40 | | virtual void Reset(); |
41 | | virtual bool Parse(const char *pStr, size_t nLength, bool bFinished); |
42 | | |
43 | | protected: |
44 | | bool EmitException(const char *pszMessage); |
45 | | void StopParsing(); |
46 | | |
47 | | virtual void String(const char * /*pszValue*/, size_t /*nLength*/) |
48 | 0 | { |
49 | 0 | } |
50 | | |
51 | | virtual void Number(const char * /*pszValue*/, size_t /*nLength*/) |
52 | 0 | { |
53 | 0 | } |
54 | | |
55 | | virtual void Boolean(bool /*b*/) |
56 | 0 | { |
57 | 0 | } |
58 | | |
59 | | virtual void Null() |
60 | 0 | { |
61 | 0 | } |
62 | | |
63 | | virtual void StartObject() |
64 | 0 | { |
65 | 0 | } |
66 | | |
67 | | virtual void EndObject() |
68 | 0 | { |
69 | 0 | } |
70 | | |
71 | | virtual void StartObjectMember(const char * /*pszKey*/, size_t /*nLength*/) |
72 | 0 | { |
73 | 0 | } |
74 | | |
75 | | virtual void StartArray() |
76 | 0 | { |
77 | 0 | } |
78 | | |
79 | | virtual void EndArray() |
80 | 0 | { |
81 | 0 | } |
82 | | |
83 | | virtual void StartArrayMember() |
84 | 0 | { |
85 | 0 | } |
86 | | |
87 | | virtual void Exception(const char * /*pszMessage*/) |
88 | 0 | { |
89 | 0 | } |
90 | | |
91 | | private: |
92 | | CPL_DISALLOW_COPY_ASSIGN(CPLJSonStreamingParser) |
93 | | |
94 | | enum State |
95 | | { |
96 | | INIT, |
97 | | OBJECT, |
98 | | ARRAY, |
99 | | STRING, |
100 | | NUMBER, |
101 | | STATE_TRUE, |
102 | | STATE_FALSE, |
103 | | STATE_NULL |
104 | | }; |
105 | | |
106 | | bool m_bExceptionOccurred = false; |
107 | | bool m_bElementFound = false; |
108 | | bool m_bStopParsing = false; |
109 | | int m_nLastChar = 0; |
110 | | int m_nLineCounter = 1; |
111 | | int m_nCharCounter = 1; |
112 | | std::vector<State> m_aState{}; |
113 | | std::string m_osToken{}; |
114 | | enum class ArrayState |
115 | | { |
116 | | INIT, |
117 | | AFTER_COMMA, |
118 | | AFTER_VALUE |
119 | | }; |
120 | | std::vector<ArrayState> m_abArrayState{}; |
121 | | bool m_bInStringEscape = false; |
122 | | bool m_bInUnicode = false; |
123 | | std::string m_osUnicodeHex{}; |
124 | | size_t m_nMaxDepth = 1024; |
125 | | size_t m_nMaxStringSize = 10000000; |
126 | | |
127 | | enum MemberState |
128 | | { |
129 | | WAITING_KEY, |
130 | | IN_KEY, |
131 | | KEY_FINISHED, |
132 | | IN_VALUE |
133 | | }; |
134 | | |
135 | | std::vector<MemberState> m_aeObjectState{}; |
136 | | |
137 | | enum State currentState() |
138 | 0 | { |
139 | 0 | return m_aState.back(); |
140 | 0 | } |
141 | | |
142 | | void SkipSpace(const char *&pStr, size_t &nLength); |
143 | | void AdvanceChar(const char *&pStr, size_t &nLength); |
144 | | bool EmitUnexpectedChar(char ch, const char *pszExpecting = nullptr); |
145 | | bool StartNewToken(const char *&pStr, size_t &nLength); |
146 | | bool CheckAndEmitTrueFalseOrNull(char ch); |
147 | | bool CheckStackEmpty(); |
148 | | void DecodeUnicode(); |
149 | | }; |
150 | | |
151 | | #endif // __cplusplus |
152 | | |
153 | | /*! @endcond */ |
154 | | |
155 | | #endif // CPL_JSON_STREAMIN_PARSER_H |