Line data Source code
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 : * 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_STREAMIN_PARSER_H
30 : #define CPL_JSON_STREAMIN_PARSER_H
31 :
32 : /*! @cond Doxygen_Suppress */
33 :
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 CPLJSonStreamingParser
41 : {
42 : CPL_DISALLOW_COPY_ASSIGN(CPLJSonStreamingParser)
43 :
44 : enum State
45 : {
46 : INIT,
47 : OBJECT,
48 : ARRAY,
49 : STRING,
50 : NUMBER,
51 : STATE_TRUE,
52 : STATE_FALSE,
53 : STATE_NULL
54 : };
55 :
56 : bool m_bExceptionOccurred = false;
57 : bool m_bElementFound = false;
58 : int m_nLastChar = 0;
59 : int m_nLineCounter = 1;
60 : int m_nCharCounter = 1;
61 : std::vector<State> m_aState{};
62 : std::string m_osToken{};
63 : enum class ArrayState
64 : {
65 : INIT,
66 : AFTER_COMMA,
67 : AFTER_VALUE
68 : };
69 : std::vector<ArrayState> m_abArrayState{};
70 : bool m_bInStringEscape = false;
71 : bool m_bInUnicode = false;
72 : std::string m_osUnicodeHex{};
73 : size_t m_nMaxDepth = 1024;
74 : size_t m_nMaxStringSize = 10000000;
75 :
76 : enum MemberState
77 : {
78 : WAITING_KEY,
79 : IN_KEY,
80 : KEY_FINISHED,
81 : IN_VALUE
82 : };
83 :
84 : std::vector<MemberState> m_aeObjectState{};
85 :
86 1568410 : enum State currentState()
87 : {
88 1568410 : return m_aState.back();
89 : }
90 :
91 : void SkipSpace(const char *&pStr, size_t &nLength);
92 : void AdvanceChar(const char *&pStr, size_t &nLength);
93 : bool EmitUnexpectedChar(char ch, const char *pszExpecting = nullptr);
94 : bool StartNewToken(const char *&pStr, size_t &nLength);
95 : bool CheckAndEmitTrueFalseOrNull(char ch);
96 : bool CheckStackEmpty();
97 : void DecodeUnicode();
98 :
99 : protected:
100 : bool EmitException(const char *pszMessage);
101 :
102 : public:
103 : CPLJSonStreamingParser();
104 : virtual ~CPLJSonStreamingParser();
105 :
106 : void SetMaxDepth(size_t nVal);
107 : void SetMaxStringSize(size_t nVal);
108 :
109 27509 : bool ExceptionOccurred() const
110 : {
111 27509 : return m_bExceptionOccurred;
112 : }
113 :
114 : static std::string GetSerializedString(const char *pszStr);
115 :
116 : virtual void Reset();
117 : virtual bool Parse(const char *pStr, size_t nLength, bool bFinished);
118 :
119 0 : virtual void String(const char * /*pszValue*/, size_t /*nLength*/)
120 : {
121 0 : }
122 :
123 0 : virtual void Number(const char * /*pszValue*/, size_t /*nLength*/)
124 : {
125 0 : }
126 :
127 0 : virtual void Boolean(bool /*b*/)
128 : {
129 0 : }
130 :
131 0 : virtual void Null()
132 : {
133 0 : }
134 :
135 0 : virtual void StartObject()
136 : {
137 0 : }
138 :
139 0 : virtual void EndObject()
140 : {
141 0 : }
142 :
143 0 : virtual void StartObjectMember(const char * /*pszKey*/, size_t /*nLength*/)
144 : {
145 0 : }
146 :
147 0 : virtual void StartArray()
148 : {
149 0 : }
150 :
151 0 : virtual void EndArray()
152 : {
153 0 : }
154 :
155 0 : virtual void StartArrayMember()
156 : {
157 0 : }
158 :
159 0 : virtual void Exception(const char * /*pszMessage*/)
160 : {
161 0 : }
162 : };
163 :
164 : #endif // __cplusplus
165 :
166 : /*! @endcond */
167 :
168 : #endif // CPL_JSON_STREAMIN_PARSER_H
|