json: Have lexer call streamer directly

json_lexer_init() takes the function to process a token as an
argument.  It's always json_message_process_token().  Makes the code
harder to understand for no actual gain.  Drop the indirection.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Message-Id: <20180823164025.12553-34-armbru@redhat.com>
This commit is contained in:
Markus Armbruster 2018-08-23 18:40:00 +02:00
parent e8b19d7d73
commit 037f244088
4 changed files with 17 additions and 18 deletions

View File

@ -32,20 +32,13 @@ typedef enum json_token_type {
JSON_ERROR,
} JSONTokenType;
typedef struct JSONLexer JSONLexer;
typedef void (JSONLexerEmitter)(JSONLexer *, GString *,
JSONTokenType, int x, int y);
struct JSONLexer
{
JSONLexerEmitter *emit;
typedef struct JSONLexer {
int state;
GString *token;
int x, y;
};
} JSONLexer;
void json_lexer_init(JSONLexer *lexer, JSONLexerEmitter func);
void json_lexer_init(JSONLexer *lexer);
void json_lexer_feed(JSONLexer *lexer, const char *buffer, size_t size);

View File

@ -33,6 +33,9 @@ typedef struct JSONMessageParser
uint64_t token_size;
} JSONMessageParser;
void json_message_process_token(JSONLexer *lexer, GString *input,
JSONTokenType type, int x, int y);
void json_message_parser_init(JSONMessageParser *parser,
void (*func)(JSONMessageParser *, GQueue *));

View File

@ -14,6 +14,7 @@
#include "qemu/osdep.h"
#include "qemu-common.h"
#include "qapi/qmp/json-lexer.h"
#include "qapi/qmp/json-streamer.h"
#define MAX_TOKEN_SIZE (64ULL << 20)
@ -278,9 +279,8 @@ static const uint8_t json_lexer[][256] = {
},
};
void json_lexer_init(JSONLexer *lexer, JSONLexerEmitter func)
void json_lexer_init(JSONLexer *lexer)
{
lexer->emit = func;
lexer->state = IN_START;
lexer->token = g_string_sized_new(3);
lexer->x = lexer->y = 0;
@ -316,7 +316,8 @@ static void json_lexer_feed_char(JSONLexer *lexer, char ch, bool flush)
case JSON_FLOAT:
case JSON_KEYWORD:
case JSON_STRING:
lexer->emit(lexer, lexer->token, new_state, lexer->x, lexer->y);
json_message_process_token(lexer, lexer->token, new_state,
lexer->x, lexer->y);
/* fall through */
case JSON_SKIP:
g_string_truncate(lexer->token, 0);
@ -336,7 +337,8 @@ static void json_lexer_feed_char(JSONLexer *lexer, char ch, bool flush)
* never a valid ASCII/UTF-8 sequence, so this should reliably
* induce an error/flush state.
*/
lexer->emit(lexer, lexer->token, JSON_ERROR, lexer->x, lexer->y);
json_message_process_token(lexer, lexer->token, JSON_ERROR,
lexer->x, lexer->y);
g_string_truncate(lexer->token, 0);
new_state = IN_START;
lexer->state = new_state;
@ -351,7 +353,8 @@ static void json_lexer_feed_char(JSONLexer *lexer, char ch, bool flush)
* this is a security consideration.
*/
if (lexer->token->len > MAX_TOKEN_SIZE) {
lexer->emit(lexer, lexer->token, lexer->state, lexer->x, lexer->y);
json_message_process_token(lexer, lexer->token, lexer->state,
lexer->x, lexer->y);
g_string_truncate(lexer->token, 0);
lexer->state = IN_START;
}

View File

@ -34,8 +34,8 @@ static void json_message_free_tokens(JSONMessageParser *parser)
}
}
static void json_message_process_token(JSONLexer *lexer, GString *input,
JSONTokenType type, int x, int y)
void json_message_process_token(JSONLexer *lexer, GString *input,
JSONTokenType type, int x, int y)
{
JSONMessageParser *parser = container_of(lexer, JSONMessageParser, lexer);
JSONToken *token;
@ -115,7 +115,7 @@ void json_message_parser_init(JSONMessageParser *parser,
parser->tokens = g_queue_new();
parser->token_size = 0;
json_lexer_init(&parser->lexer, json_message_process_token);
json_lexer_init(&parser->lexer);
}
void json_message_parser_feed(JSONMessageParser *parser,