Browse Source
The second stage of our JSON parser is a simple state machine that identifies individual JSON values by counting the levels of nesting of tokens. It does not perform grammar validation. We use this to emit a full JSON value to the parser. Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>remotes/github/stable-0.12
3 changed files with 128 additions and 0 deletions
@ -0,0 +1,88 @@ |
|||
/*
|
|||
* JSON streaming support |
|||
* |
|||
* Copyright IBM, Corp. 2009 |
|||
* |
|||
* Authors: |
|||
* Anthony Liguori <aliguori@us.ibm.com> |
|||
* |
|||
* This work is licensed under the terms of the GNU LGPL, version 2.1 or later. |
|||
* See the COPYING.LIB file in the top-level directory. |
|||
* |
|||
*/ |
|||
|
|||
#include "qlist.h" |
|||
#include "qint.h" |
|||
#include "qdict.h" |
|||
#include "qemu-common.h" |
|||
#include "json-lexer.h" |
|||
#include "json-streamer.h" |
|||
|
|||
static void json_message_process_token(JSONLexer *lexer, QString *token, JSONTokenType type, int x, int y) |
|||
{ |
|||
JSONMessageParser *parser = container_of(lexer, JSONMessageParser, lexer); |
|||
QDict *dict; |
|||
|
|||
if (type == JSON_OPERATOR) { |
|||
switch (qstring_get_str(token)[0]) { |
|||
case '{': |
|||
parser->brace_count++; |
|||
break; |
|||
case '}': |
|||
parser->brace_count--; |
|||
break; |
|||
case '[': |
|||
parser->bracket_count++; |
|||
break; |
|||
case ']': |
|||
parser->bracket_count--; |
|||
break; |
|||
default: |
|||
break; |
|||
} |
|||
} |
|||
|
|||
dict = qdict_new(); |
|||
qdict_put_obj(dict, "type", QOBJECT(qint_from_int(type))); |
|||
QINCREF(token); |
|||
qdict_put_obj(dict, "token", QOBJECT(token)); |
|||
qdict_put_obj(dict, "x", QOBJECT(qint_from_int(x))); |
|||
qdict_put_obj(dict, "y", QOBJECT(qint_from_int(y))); |
|||
|
|||
qlist_append(parser->tokens, dict); |
|||
|
|||
if (parser->brace_count == 0 && |
|||
parser->bracket_count == 0) { |
|||
parser->emit(parser, parser->tokens); |
|||
QDECREF(parser->tokens); |
|||
parser->tokens = qlist_new(); |
|||
} |
|||
} |
|||
|
|||
void json_message_parser_init(JSONMessageParser *parser, |
|||
void (*func)(JSONMessageParser *, QList *)) |
|||
{ |
|||
parser->emit = func; |
|||
parser->brace_count = 0; |
|||
parser->bracket_count = 0; |
|||
parser->tokens = qlist_new(); |
|||
|
|||
json_lexer_init(&parser->lexer, json_message_process_token); |
|||
} |
|||
|
|||
int json_message_parser_feed(JSONMessageParser *parser, |
|||
const char *buffer, size_t size) |
|||
{ |
|||
return json_lexer_feed(&parser->lexer, buffer, size); |
|||
} |
|||
|
|||
int json_message_parser_flush(JSONMessageParser *parser) |
|||
{ |
|||
return json_lexer_flush(&parser->lexer); |
|||
} |
|||
|
|||
void json_message_parser_destroy(JSONMessageParser *parser) |
|||
{ |
|||
json_lexer_destroy(&parser->lexer); |
|||
QDECREF(parser->tokens); |
|||
} |
|||
@ -0,0 +1,39 @@ |
|||
/*
|
|||
* JSON streaming support |
|||
* |
|||
* Copyright IBM, Corp. 2009 |
|||
* |
|||
* Authors: |
|||
* Anthony Liguori <aliguori@us.ibm.com> |
|||
* |
|||
* This work is licensed under the terms of the GNU LGPL, version 2.1 or later. |
|||
* See the COPYING.LIB file in the top-level directory. |
|||
* |
|||
*/ |
|||
|
|||
#ifndef QEMU_JSON_STREAMER_H |
|||
#define QEMU_JSON_STREAMER_H |
|||
|
|||
#include "qlist.h" |
|||
#include "json-lexer.h" |
|||
|
|||
typedef struct JSONMessageParser |
|||
{ |
|||
void (*emit)(struct JSONMessageParser *parser, QList *tokens); |
|||
JSONLexer lexer; |
|||
int brace_count; |
|||
int bracket_count; |
|||
QList *tokens; |
|||
} JSONMessageParser; |
|||
|
|||
void json_message_parser_init(JSONMessageParser *parser, |
|||
void (*func)(JSONMessageParser *, QList *)); |
|||
|
|||
int json_message_parser_feed(JSONMessageParser *parser, |
|||
const char *buffer, size_t size); |
|||
|
|||
int json_message_parser_flush(JSONMessageParser *parser); |
|||
|
|||
void json_message_parser_destroy(JSONMessageParser *parser); |
|||
|
|||
#endif |
|||
Loading…
Reference in new issue