diff options
author | Dario Lombardo <lomato@gmail.com> | 2018-12-13 15:39:21 +0100 |
---|---|---|
committer | Peter Wu <peter@lekensteyn.nl> | 2018-12-23 21:10:47 +0000 |
commit | 71517540b7281d529ab24107ba4bb4723f916b32 (patch) | |
tree | e8bf2f052ba2bcb63b60aa7022139e755959c7ea /wsutil/json_dumper.c | |
parent | c88bef54a9f417ca14e1743ddc138934a62ac82a (diff) |
json_dumper: add base64 routines.
Change-Id: Iab9a201fe951e5557501f4e675ab74ecd9dbb930
Reviewed-on: https://code.wireshark.org/review/31034
Petri-Dish: Dario Lombardo <lomato@gmail.com>
Tested-by: Petri Dish Buildbot
Reviewed-by: Peter Wu <peter@lekensteyn.nl>
Diffstat (limited to 'wsutil/json_dumper.c')
-rw-r--r-- | wsutil/json_dumper.c | 70 |
1 files changed, 68 insertions, 2 deletions
diff --git a/wsutil/json_dumper.c b/wsutil/json_dumper.c index 195049c99d..5162b6b8c9 100644 --- a/wsutil/json_dumper.c +++ b/wsutil/json_dumper.c @@ -23,9 +23,10 @@ enum json_dumper_element_type { JSON_DUMPER_TYPE_VALUE = 1, JSON_DUMPER_TYPE_OBJECT = 2, JSON_DUMPER_TYPE_ARRAY = 3, + JSON_DUMPER_TYPE_BASE64 = 4, }; -#define JSON_DUMPER_TYPE(state) ((enum json_dumper_element_type)((state) & 3)) -#define JSON_DUMPER_HAS_NAME (1 << 2) +#define JSON_DUMPER_TYPE(state) ((enum json_dumper_element_type)((state) & 7)) +#define JSON_DUMPER_HAS_NAME (1 << 3) #define JSON_DUMPER_FLAGS_ERROR (1 << 16) /* Output flag: an error occurred. */ #define JSON_DUMPER_FLAGS_NO_DEBUG (1 << 17) /* Input flag: disable debug prints (intended for speeding up fuzzing). */ @@ -35,6 +36,7 @@ enum json_dumper_change { JSON_DUMPER_END, JSON_DUMPER_SET_NAME, JSON_DUMPER_SET_VALUE, + JSON_DUMPER_WRITE_BASE64, JSON_DUMPER_FINISH, }; @@ -137,10 +139,16 @@ json_dumper_check_state(json_dumper *dumper, enum json_dumper_change change, enu ok = (prev_state & JSON_DUMPER_HAS_NAME); } else if (prev_type == JSON_DUMPER_TYPE_ARRAY) { ok = TRUE; + } else if (prev_type == JSON_DUMPER_TYPE_BASE64) { + ok = FALSE; } else { ok = JSON_DUMPER_TYPE(dumper->state[depth]) == JSON_DUMPER_TYPE_NONE; } break; + case JSON_DUMPER_WRITE_BASE64: + ok = (prev_type == JSON_DUMPER_TYPE_BASE64) && + (type == JSON_DUMPER_TYPE_NONE || type == JSON_DUMPER_TYPE_BASE64); + break; case JSON_DUMPER_FINISH: ok = depth == 0; break; @@ -324,3 +332,61 @@ json_dumper_finish(json_dumper *dumper) dumper->state[0] = 0; return TRUE; } + +void +json_dumper_begin_base64(json_dumper *dumper) +{ + if (!json_dumper_check_state(dumper, JSON_DUMPER_BEGIN, JSON_DUMPER_TYPE_BASE64)) { + return; + } + + dumper->base64_state = 0; + dumper->base64_save = 0; + + prepare_token(dumper); + + fputc('"', dumper->output_file); + + dumper->state[dumper->current_depth] = JSON_DUMPER_TYPE_BASE64; + ++dumper->current_depth; + dumper->state[dumper->current_depth] = 0; +} + +void +json_dumper_write_base64(json_dumper* dumper, const guchar *data, size_t len) +{ + if (!json_dumper_check_state(dumper, JSON_DUMPER_WRITE_BASE64, JSON_DUMPER_TYPE_BASE64)) { + return; + } + + #define CHUNK_SIZE 1024 + gchar buf[(CHUNK_SIZE / 3 + 1) * 4 + 4]; + + while (len > 0) { + gsize chunk_size = len < CHUNK_SIZE ? len : CHUNK_SIZE; + gsize output_size = g_base64_encode_step(data, chunk_size, FALSE, buf, &dumper->base64_state, &dumper->base64_save); + fwrite(buf, 1, output_size, dumper->output_file); + data += chunk_size; + len -= chunk_size; + } + + dumper->state[dumper->current_depth] = JSON_DUMPER_TYPE_BASE64; +} + +void +json_dumper_end_base64(json_dumper *dumper) +{ + if (!json_dumper_check_state(dumper, JSON_DUMPER_END, JSON_DUMPER_TYPE_BASE64)) { + return; + } + + gchar buf[4]; + gsize wrote; + + wrote = g_base64_encode_close(FALSE, buf, &dumper->base64_state, &dumper->base64_save); + fwrite(buf, 1, wrote, dumper->output_file); + + fputc('"', dumper->output_file); + + --dumper->current_depth; +} |