1 /* 2 ** upb::json::Parser (upb_json_parser) 3 ** 4 ** Parses JSON according to a specific schema. 5 ** Support for parsing arbitrary JSON (schema-less) will be added later. 6 */ 7 8 #ifndef UPB_JSON_PARSER_H_ 9 #define UPB_JSON_PARSER_H_ 10 11 #include "upb/sink.h" 12 13 #ifdef __cplusplus 14 namespace upb { 15 namespace json { 16 class CodeCache; 17 class ParserPtr; 18 class ParserMethodPtr; 19 } /* namespace json */ 20 } /* namespace upb */ 21 #endif 22 23 /* upb_json_parsermethod ******************************************************/ 24 25 struct upb_json_parsermethod; 26 typedef struct upb_json_parsermethod upb_json_parsermethod; 27 28 #ifdef __cplusplus 29 extern "C" { 30 #endif 31 32 const upb_byteshandler* upb_json_parsermethod_inputhandler( 33 const upb_json_parsermethod* m); 34 35 #ifdef __cplusplus 36 } /* extern "C" */ 37 38 class upb::json::ParserMethodPtr { 39 public: ParserMethodPtr()40 ParserMethodPtr() : ptr_(nullptr) {} ParserMethodPtr(const upb_json_parsermethod * ptr)41 ParserMethodPtr(const upb_json_parsermethod* ptr) : ptr_(ptr) {} 42 ptr()43 const upb_json_parsermethod* ptr() const { return ptr_; } 44 input_handler()45 const BytesHandler* input_handler() const { 46 return upb_json_parsermethod_inputhandler(ptr()); 47 } 48 49 private: 50 const upb_json_parsermethod* ptr_; 51 }; 52 53 #endif /* __cplusplus */ 54 55 /* upb_json_parser ************************************************************/ 56 57 /* Preallocation hint: parser won't allocate more bytes than this when first 58 * constructed. This hint may be an overestimate for some build configurations. 59 * But if the parser library is upgraded without recompiling the application, 60 * it may be an underestimate. */ 61 #define UPB_JSON_PARSER_SIZE 5712 62 63 struct upb_json_parser; 64 typedef struct upb_json_parser upb_json_parser; 65 66 #ifdef __cplusplus 67 extern "C" { 68 #endif 69 70 upb_json_parser* upb_json_parser_create(upb_arena* a, 71 const upb_json_parsermethod* m, 72 const upb_symtab* symtab, 73 upb_sink output, 74 upb_status *status, 75 bool ignore_json_unknown); 76 upb_bytessink upb_json_parser_input(upb_json_parser* p); 77 78 #ifdef __cplusplus 79 } /* extern "C" */ 80 81 /* Parses an incoming BytesStream, pushing the results to the destination 82 * sink. */ 83 class upb::json::ParserPtr { 84 public: ParserPtr(upb_json_parser * ptr)85 ParserPtr(upb_json_parser* ptr) : ptr_(ptr) {} 86 Create(Arena * arena,ParserMethodPtr method,SymbolTable * symtab,Sink output,Status * status,bool ignore_json_unknown)87 static ParserPtr Create(Arena* arena, ParserMethodPtr method, 88 SymbolTable* symtab, Sink output, Status* status, 89 bool ignore_json_unknown) { 90 upb_symtab* symtab_ptr = symtab ? symtab->ptr() : nullptr; 91 return ParserPtr(upb_json_parser_create( 92 arena->ptr(), method.ptr(), symtab_ptr, output.sink(), status->ptr(), 93 ignore_json_unknown)); 94 } 95 input()96 BytesSink input() { return upb_json_parser_input(ptr_); } 97 98 private: 99 upb_json_parser* ptr_; 100 }; 101 102 #endif /* __cplusplus */ 103 104 /* upb_json_codecache *********************************************************/ 105 106 /* Lazily builds and caches decoder methods that will push data to the given 107 * handlers. The upb_symtab object(s) must outlive this object. */ 108 109 struct upb_json_codecache; 110 typedef struct upb_json_codecache upb_json_codecache; 111 112 #ifdef __cplusplus 113 extern "C" { 114 #endif 115 116 upb_json_codecache *upb_json_codecache_new(void); 117 void upb_json_codecache_free(upb_json_codecache *cache); 118 const upb_json_parsermethod* upb_json_codecache_get(upb_json_codecache* cache, 119 const upb_msgdef* md); 120 121 #ifdef __cplusplus 122 } /* extern "C" */ 123 124 class upb::json::CodeCache { 125 public: CodeCache()126 CodeCache() : ptr_(upb_json_codecache_new(), upb_json_codecache_free) {} 127 128 /* Returns a DecoderMethod that can push data to the given handlers. 129 * If a suitable method already exists, it will be returned from the cache. */ Get(MessageDefPtr md)130 ParserMethodPtr Get(MessageDefPtr md) { 131 return upb_json_codecache_get(ptr_.get(), md.ptr()); 132 } 133 134 private: 135 std::unique_ptr<upb_json_codecache, decltype(&upb_json_codecache_free)> ptr_; 136 }; 137 138 #endif 139 140 #endif /* UPB_JSON_PARSER_H_ */ 141