diff --git a/Makefile b/Makefile index 446942d927..453306b82b 100644 --- a/Makefile +++ b/Makefile @@ -138,6 +138,7 @@ obj-y += qemu-char.o aio.o savevm.o obj-y += msmouse.o ps2.o obj-y += qdev.o qdev-properties.o obj-y += qint.o qstring.o qdict.o qlist.o qfloat.o qbool.o json-lexer.o +obj-y += json-streamer.o obj-y += qemu-config.o block-migration.o obj-$(CONFIG_BRLAPI) += baum.o diff --git a/json-streamer.c b/json-streamer.c new file mode 100644 index 0000000000..610ffea6db --- /dev/null +++ b/json-streamer.c @@ -0,0 +1,88 @@ +/* + * JSON streaming support + * + * Copyright IBM, Corp. 2009 + * + * Authors: + * Anthony Liguori + * + * 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); +} diff --git a/json-streamer.h b/json-streamer.h new file mode 100644 index 0000000000..09f3bd70e4 --- /dev/null +++ b/json-streamer.h @@ -0,0 +1,39 @@ +/* + * JSON streaming support + * + * Copyright IBM, Corp. 2009 + * + * Authors: + * Anthony Liguori + * + * 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