|
|
|
/*
|
|
|
|
** upb::json::Parser (upb_json_parser)
|
|
|
|
**
|
|
|
|
** Parses JSON according to a specific schema.
|
|
|
|
** Support for parsing arbitrary JSON (schema-less) will be added later.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef UPB_JSON_PARSER_H_
|
|
|
|
#define UPB_JSON_PARSER_H_
|
|
|
|
|
|
|
|
#include "upb/sink.h"
|
|
|
|
|
|
|
|
#ifdef __cplusplus
|
|
|
|
namespace upb {
|
|
|
|
namespace json {
|
|
|
|
class CodeCache;
|
|
|
|
class ParserPtr;
|
|
|
|
class ParserMethodPtr;
|
|
|
|
} /* namespace json */
|
|
|
|
} /* namespace upb */
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/* upb_json_parsermethod ******************************************************/
|
|
|
|
|
|
|
|
struct upb_json_parsermethod;
|
|
|
|
typedef struct upb_json_parsermethod upb_json_parsermethod;
|
|
|
|
|
|
|
|
#ifdef __cplusplus
|
|
|
|
extern "C" {
|
|
|
|
#endif
|
|
|
|
|
|
|
|
const upb_byteshandler* upb_json_parsermethod_inputhandler(
|
|
|
|
const upb_json_parsermethod* m);
|
|
|
|
|
|
|
|
#ifdef __cplusplus
|
|
|
|
} /* extern "C" */
|
|
|
|
|
|
|
|
class upb::json::ParserMethodPtr {
|
|
|
|
public:
|
|
|
|
ParserMethodPtr() : ptr_(nullptr) {}
|
|
|
|
ParserMethodPtr(const upb_json_parsermethod* ptr) : ptr_(ptr) {}
|
|
|
|
|
|
|
|
const upb_json_parsermethod* ptr() const { return ptr_; }
|
|
|
|
|
|
|
|
const BytesHandler* input_handler() const {
|
|
|
|
return upb_json_parsermethod_inputhandler(ptr());
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
const upb_json_parsermethod* ptr_;
|
|
|
|
};
|
|
|
|
|
|
|
|
#endif /* __cplusplus */
|
|
|
|
|
|
|
|
/* upb_json_parser ************************************************************/
|
|
|
|
|
|
|
|
/* Preallocation hint: parser won't allocate more bytes than this when first
|
|
|
|
* constructed. This hint may be an overestimate for some build configurations.
|
|
|
|
* But if the parser library is upgraded without recompiling the application,
|
|
|
|
* it may be an underestimate. */
|
|
|
|
#define UPB_JSON_PARSER_SIZE 5712
|
|
|
|
|
|
|
|
struct upb_json_parser;
|
|
|
|
typedef struct upb_json_parser upb_json_parser;
|
|
|
|
|
|
|
|
#ifdef __cplusplus
|
|
|
|
extern "C" {
|
|
|
|
#endif
|
|
|
|
|
|
|
|
upb_json_parser* upb_json_parser_create(upb_arena* a,
|
|
|
|
const upb_json_parsermethod* m,
|
|
|
|
const upb_symtab* symtab,
|
|
|
|
upb_sink output,
|
|
|
|
upb_status *status,
|
|
|
|
bool ignore_json_unknown);
|
|
|
|
upb_bytessink upb_json_parser_input(upb_json_parser* p);
|
|
|
|
|
|
|
|
#ifdef __cplusplus
|
|
|
|
} /* extern "C" */
|
|
|
|
|
|
|
|
/* Parses an incoming BytesStream, pushing the results to the destination
|
|
|
|
* sink. */
|
|
|
|
class upb::json::ParserPtr {
|
|
|
|
public:
|
|
|
|
ParserPtr(upb_json_parser* ptr) : ptr_(ptr) {}
|
|
|
|
|
|
|
|
static ParserPtr Create(Arena* arena, ParserMethodPtr method,
|
|
|
|
SymbolTable* symtab, Sink output, Status* status,
|
|
|
|
bool ignore_json_unknown) {
|
|
|
|
upb_symtab* symtab_ptr = symtab ? symtab->ptr() : nullptr;
|
|
|
|
return ParserPtr(upb_json_parser_create(
|
|
|
|
arena->ptr(), method.ptr(), symtab_ptr, output.sink(), status->ptr(),
|
|
|
|
ignore_json_unknown));
|
|
|
|
}
|
|
|
|
|
|
|
|
BytesSink input() { return upb_json_parser_input(ptr_); }
|
|
|
|
|
|
|
|
private:
|
|
|
|
upb_json_parser* ptr_;
|
|
|
|
};
|
|
|
|
|
|
|
|
#endif /* __cplusplus */
|
|
|
|
|
|
|
|
/* upb_json_codecache *********************************************************/
|
|
|
|
|
|
|
|
/* Lazily builds and caches decoder methods that will push data to the given
|
|
|
|
* handlers. The upb_symtab object(s) must outlive this object. */
|
|
|
|
|
|
|
|
struct upb_json_codecache;
|
|
|
|
typedef struct upb_json_codecache upb_json_codecache;
|
|
|
|
|
|
|
|
#ifdef __cplusplus
|
|
|
|
extern "C" {
|
|
|
|
#endif
|
|
|
|
|
|
|
|
upb_json_codecache *upb_json_codecache_new(void);
|
|
|
|
void upb_json_codecache_free(upb_json_codecache *cache);
|
|
|
|
const upb_json_parsermethod* upb_json_codecache_get(upb_json_codecache* cache,
|
|
|
|
const upb_msgdef* md);
|
|
|
|
|
|
|
|
#ifdef __cplusplus
|
|
|
|
} /* extern "C" */
|
|
|
|
|
|
|
|
class upb::json::CodeCache {
|
|
|
|
public:
|
|
|
|
CodeCache() : ptr_(upb_json_codecache_new(), upb_json_codecache_free) {}
|
|
|
|
|
|
|
|
/* Returns a DecoderMethod that can push data to the given handlers.
|
|
|
|
* If a suitable method already exists, it will be returned from the cache. */
|
|
|
|
ParserMethodPtr Get(MessageDefPtr md) {
|
|
|
|
return upb_json_codecache_get(ptr_.get(), md.ptr());
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
std::unique_ptr<upb_json_codecache, decltype(&upb_json_codecache_free)> ptr_;
|
|
|
|
};
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#endif /* UPB_JSON_PARSER_H_ */
|