Commit d2ca7c0b authored by Paolo Bonzini's avatar Paolo Bonzini Committed by Markus Armbruster
Browse files

qjson: replace QString in JSONLexer with GString



JSONLexer only needs a simple resizable buffer.  json-streamer.c
can allocate memory for each token instead of relying on reference
counting of QStrings.

Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
Message-Id: <1448300659-23559-2-git-send-email-pbonzini@redhat.com>
[Straightforwardly rebased on my patches, checkpatch made happy]
Signed-off-by: default avatarMarkus Armbruster <armbru@redhat.com>
Reviewed-by: default avatarEric Blake <eblake@redhat.com>
parent 6b9606f6
Loading
Loading
Loading
Loading
+4 −4
Original line number Diff line number Diff line
@@ -14,8 +14,7 @@
#ifndef QEMU_JSON_LEXER_H
#define QEMU_JSON_LEXER_H

#include "qapi/qmp/qstring.h"
#include "qapi/qmp/qlist.h"
#include "glib-compat.h"

typedef enum json_token_type {
    JSON_MIN = 100,
@@ -36,13 +35,14 @@ typedef enum json_token_type {

typedef struct JSONLexer JSONLexer;

typedef void (JSONLexerEmitter)(JSONLexer *, QString *, JSONTokenType, int x, int y);
typedef void (JSONLexerEmitter)(JSONLexer *, GString *,
                                JSONTokenType, int x, int y);

struct JSONLexer
{
    JSONLexerEmitter *emit;
    int state;
    QString *token;
    GString *token;
    int x, y;
};

+1 −0
Original line number Diff line number Diff line
@@ -14,6 +14,7 @@
#ifndef QEMU_JSON_STREAMER_H
#define QEMU_JSON_STREAMER_H

#include <stdint.h>
#include "qapi/qmp/qlist.h"
#include "qapi/qmp/json-lexer.h"

+8 −14
Original line number Diff line number Diff line
@@ -11,12 +11,9 @@
 *
 */

#include "qapi/qmp/qstring.h"
#include "qapi/qmp/qlist.h"
#include "qapi/qmp/qdict.h"
#include "qapi/qmp/qint.h"
#include "qemu-common.h"
#include "qapi/qmp/json-lexer.h"
#include <stdint.h>

#define MAX_TOKEN_SIZE (64ULL << 20)

@@ -276,7 +273,7 @@ void json_lexer_init(JSONLexer *lexer, JSONLexerEmitter func)
{
    lexer->emit = func;
    lexer->state = IN_START;
    lexer->token = qstring_new();
    lexer->token = g_string_sized_new(3);
    lexer->x = lexer->y = 0;
}

@@ -295,7 +292,7 @@ static int json_lexer_feed_char(JSONLexer *lexer, char ch, bool flush)
        new_state = json_lexer[lexer->state][(uint8_t)ch];
        char_consumed = !TERMINAL_NEEDED_LOOKAHEAD(lexer->state, new_state);
        if (char_consumed) {
            qstring_append_chr(lexer->token, ch);
            g_string_append_c(lexer->token, ch);
        }

        switch (new_state) {
@@ -313,8 +310,7 @@ static int json_lexer_feed_char(JSONLexer *lexer, char ch, bool flush)
            lexer->emit(lexer, lexer->token, new_state, lexer->x, lexer->y);
            /* fall through */
        case JSON_SKIP:
            QDECREF(lexer->token);
            lexer->token = qstring_new();
            g_string_truncate(lexer->token, 0);
            new_state = IN_START;
            break;
        case IN_ERROR:
@@ -332,8 +328,7 @@ static int json_lexer_feed_char(JSONLexer *lexer, char ch, bool flush)
             * induce an error/flush state.
             */
            lexer->emit(lexer, lexer->token, JSON_ERROR, lexer->x, lexer->y);
            QDECREF(lexer->token);
            lexer->token = qstring_new();
            g_string_truncate(lexer->token, 0);
            new_state = IN_START;
            lexer->state = new_state;
            return 0;
@@ -346,10 +341,9 @@ static int json_lexer_feed_char(JSONLexer *lexer, char ch, bool flush)
    /* Do not let a single token grow to an arbitrarily large size,
     * this is a security consideration.
     */
    if (lexer->token->length > MAX_TOKEN_SIZE) {
    if (lexer->token->len > MAX_TOKEN_SIZE) {
        lexer->emit(lexer, lexer->token, lexer->state, lexer->x, lexer->y);
        QDECREF(lexer->token);
        lexer->token = qstring_new();
        g_string_truncate(lexer->token, 0);
        lexer->state = IN_START;
    }

@@ -379,5 +373,5 @@ int json_lexer_flush(JSONLexer *lexer)

void json_lexer_destroy(JSONLexer *lexer)
{
    QDECREF(lexer->token);
    g_string_free(lexer->token, true);
}
+5 −4
Original line number Diff line number Diff line
@@ -12,6 +12,7 @@
 */

#include "qapi/qmp/qlist.h"
#include "qapi/qmp/qstring.h"
#include "qapi/qmp/qint.h"
#include "qapi/qmp/qdict.h"
#include "qemu-common.h"
@@ -21,7 +22,8 @@
#define MAX_TOKEN_SIZE (64ULL << 20)
#define MAX_NESTING (1ULL << 10)

static void json_message_process_token(JSONLexer *lexer, QString *token, JSONTokenType type, int x, int y)
static void json_message_process_token(JSONLexer *lexer, GString *input,
                                       JSONTokenType type, int x, int y)
{
    JSONMessageParser *parser = container_of(lexer, JSONMessageParser, lexer);
    QDict *dict;
@@ -45,12 +47,11 @@ static void json_message_process_token(JSONLexer *lexer, QString *token, JSONTok

    dict = qdict_new();
    qdict_put(dict, "type", qint_from_int(type));
    QINCREF(token);
    qdict_put(dict, "token", token);
    qdict_put(dict, "token", qstring_from_str(input->str));
    qdict_put(dict, "x", qint_from_int(x));
    qdict_put(dict, "y", qint_from_int(y));

    parser->token_size += token->length;
    parser->token_size += input->len;

    qlist_append(parser->tokens, dict);