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 std::vector<MemberState> m_aeObjectState{}; 84 currentState()85 enum State currentState() { return m_aState.back(); } 86 void SkipSpace(const char*& pStr, size_t& nLength); 87 void AdvanceChar(const char*& pStr, size_t& nLength); 88 bool EmitException(const char* pszMessage); 89 bool EmitUnexpectedChar(char ch, const char* pszExpecting = nullptr); 90 bool StartNewToken(const char*& pStr, size_t& nLength); 91 bool CheckAndEmitTrueFalseOrNull(char ch); 92 bool CheckStackEmpty(); 93 void DecodeUnicode(); 94 95 public: 96 CPLJSonStreamingParser(); 97 virtual ~CPLJSonStreamingParser(); 98 99 void SetMaxDepth(size_t nVal); 100 void SetMaxStringSize(size_t nVal); ExceptionOccurred()101 bool ExceptionOccurred() const { return m_bExceptionOccurred; } 102 103 static std::string GetSerializedString(const char* pszStr); 104 105 virtual void Reset(); 106 virtual bool Parse(const char* pStr, size_t nLength, bool bFinished); 107 String(const char *,size_t)108 virtual void String(const char* /*pszValue*/, size_t /*nLength*/) {} Number(const char *,size_t)109 virtual void Number(const char* /*pszValue*/, size_t /*nLength*/) {} Boolean(bool)110 virtual void Boolean(bool /*b*/) {} Null()111 virtual void Null() {} 112 StartObject()113 virtual void StartObject() {} EndObject()114 virtual void EndObject() {} StartObjectMember(const char *,size_t)115 virtual void StartObjectMember(const char* /*pszKey*/, size_t /*nLength*/) {} 116 StartArray()117 virtual void StartArray() {} EndArray()118 virtual void EndArray() {} StartArrayMember()119 virtual void StartArrayMember() {} 120 Exception(const char *)121 virtual void Exception(const char* /*pszMessage*/) {} 122 }; 123 124 #endif // __cplusplus 125 126 /*! @endcond */ 127 128 #endif // CPL_JSON_STREAMIN_PARSER_H 129