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 : * 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 2867 : bool ExceptionOccurred() const 34 : { 35 2867 : return m_bExceptionOccurred; 36 : } 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 44 : virtual void String(const char * /*pszValue*/, size_t /*nLength*/) 48 : { 49 44 : } 50 : 51 201 : virtual void Number(const char * /*pszValue*/, size_t /*nLength*/) 52 : { 53 201 : } 54 : 55 8 : virtual void Boolean(bool /*b*/) 56 : { 57 8 : } 58 : 59 3 : virtual void Null() 60 : { 61 3 : } 62 : 63 0 : virtual void StartObject() 64 : { 65 0 : } 66 : 67 0 : virtual void EndObject() 68 : { 69 0 : } 70 : 71 0 : virtual void StartObjectMember(const char * /*pszKey*/, size_t /*nLength*/) 72 : { 73 0 : } 74 : 75 0 : virtual void StartArray() 76 : { 77 0 : } 78 : 79 0 : virtual void EndArray() 80 : { 81 0 : } 82 : 83 247 : virtual void StartArrayMember() 84 : { 85 247 : } 86 : 87 28 : virtual void Exception(const char * /*pszMessage*/) 88 : { 89 28 : } 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 2076390 : enum State currentState() 138 : { 139 2076390 : return m_aState.back(); 140 : } 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