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