Protocol Buffers - Google's data interchange format (grpc依赖)
https://developers.google.com/protocol-buffers/
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
139 lines
4.0 KiB
139 lines
4.0 KiB
/* |
|
* upb - a minimalist implementation of protocol buffers. |
|
* |
|
* Copyright (c) 2014 Google Inc. See LICENSE for details. |
|
* Author: Josh Haberman <jhaberman@gmail.com> |
|
* |
|
* upb::json::Parser can parse 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 Parser; |
|
} // namespace json |
|
} // namespace upb |
|
#endif |
|
|
|
UPB_DECLARE_TYPE(upb::json::Parser, upb_json_parser); |
|
|
|
// Internal-only struct used by the parser. A parser frame corresponds |
|
// one-to-one with a handler (sink) frame. |
|
typedef struct { |
|
UPB_PRIVATE_FOR_CPP |
|
upb_sink sink; |
|
// The current message in which we're parsing, and the field whose value we're |
|
// expecting next. |
|
const upb_msgdef *m; |
|
const upb_fielddef *f; |
|
|
|
// We are in a repeated-field context, ready to emit mapentries as |
|
// submessages. This flag alters the start-of-object (open-brace) behavior to |
|
// begin a sequence of mapentry messages rather than a single submessage. |
|
bool is_map; |
|
// We are in a map-entry message context. This flag is set when parsing the |
|
// value field of a single map entry and indicates to all value-field parsers |
|
// (subobjects, strings, numbers, and bools) that the map-entry submessage |
|
// should end as soon as the value is parsed. |
|
bool is_mapentry; |
|
// If |is_map| or |is_mapentry| is true, |mapfield| refers to the parent |
|
// message's map field that we're currently parsing. This differs from |f| |
|
// because |f| is the field in the *current* message (i.e., the map-entry |
|
// message itself), not the parent's field that leads to this map. |
|
const upb_fielddef *mapfield; |
|
} upb_jsonparser_frame; |
|
|
|
|
|
/* upb::json::Parser **********************************************************/ |
|
|
|
#define UPB_JSON_MAX_DEPTH 64 |
|
|
|
// Parses an incoming BytesStream, pushing the results to the destination sink. |
|
UPB_DEFINE_CLASS0(upb::json::Parser, |
|
public: |
|
Parser(Status* status); |
|
~Parser(); |
|
|
|
// Resets the state of the printer, so that it will expect to begin a new |
|
// document. |
|
void Reset(); |
|
|
|
// Resets the output pointer which will serve as our closure. Implies |
|
// Reset(). |
|
void ResetOutput(Sink* output); |
|
|
|
// The input to the printer. |
|
BytesSink* input(); |
|
, |
|
UPB_DEFINE_STRUCT0(upb_json_parser, |
|
upb_byteshandler input_handler_; |
|
upb_bytessink input_; |
|
|
|
// Stack to track the JSON scopes we are in. |
|
upb_jsonparser_frame stack[UPB_JSON_MAX_DEPTH]; |
|
upb_jsonparser_frame *top; |
|
upb_jsonparser_frame *limit; |
|
|
|
upb_status *status; |
|
|
|
// Ragel's internal parsing stack for the parsing state machine. |
|
int current_state; |
|
int parser_stack[UPB_JSON_MAX_DEPTH]; |
|
int parser_top; |
|
|
|
// The handle for the current buffer. |
|
const upb_bufhandle *handle; |
|
|
|
// Accumulate buffer. See details in parser.rl. |
|
const char *accumulated; |
|
size_t accumulated_len; |
|
char *accumulate_buf; |
|
size_t accumulate_buf_size; |
|
|
|
// Multi-part text data. See details in parser.rl. |
|
int multipart_state; |
|
upb_selector_t string_selector; |
|
|
|
// Input capture. See details in parser.rl. |
|
const char *capture; |
|
|
|
// Intermediate result of parsing a unicode escape sequence. |
|
uint32_t digit; |
|
)); |
|
|
|
UPB_BEGIN_EXTERN_C |
|
|
|
void upb_json_parser_init(upb_json_parser *p, upb_status *status); |
|
void upb_json_parser_uninit(upb_json_parser *p); |
|
void upb_json_parser_reset(upb_json_parser *p); |
|
void upb_json_parser_resetoutput(upb_json_parser *p, upb_sink *output); |
|
upb_bytessink *upb_json_parser_input(upb_json_parser *p); |
|
|
|
UPB_END_EXTERN_C |
|
|
|
#ifdef __cplusplus |
|
|
|
namespace upb { |
|
namespace json { |
|
inline Parser::Parser(Status* status) { upb_json_parser_init(this, status); } |
|
inline Parser::~Parser() { upb_json_parser_uninit(this); } |
|
inline void Parser::Reset() { upb_json_parser_reset(this); } |
|
inline void Parser::ResetOutput(Sink* output) { |
|
upb_json_parser_resetoutput(this, output); |
|
} |
|
inline BytesSink* Parser::input() { |
|
return upb_json_parser_input(this); |
|
} |
|
} // namespace json |
|
} // namespace upb |
|
|
|
#endif |
|
|
|
|
|
#endif // UPB_JSON_PARSER_H_
|
|
|