diff options
author | Benjamin Otte <otte@redhat.com> | 2021-12-05 22:07:38 +0100 |
---|---|---|
committer | Benjamin Otte <otte@redhat.com> | 2023-04-15 06:11:54 +0200 |
commit | 8161c84f76430c1ceeca5f261019d04bceac54b7 (patch) | |
tree | 8d1b3561ef9133db2e4a917749e17599db20c5a0 | |
parent | a147da11204b58e05c3bd58e91a2e37e71b3795a (diff) | |
download | gtk+-8161c84f76430c1ceeca5f261019d04bceac54b7.tar.gz |
jsonparser: Add some convenience API
gtk_json_parser_rewind()
Allows to reread the current object/array.
gtk_json_parser_has_member()
Checks the name of the current member.
gtk_json_parser_find_member()
Finds the member with the given name (or forwards to end of document and
returns FALSE);
-rw-r--r-- | gtk/json/gtkjsonparser.c | 106 | ||||
-rw-r--r-- | gtk/json/gtkjsonparserprivate.h | 5 |
2 files changed, 98 insertions, 13 deletions
diff --git a/gtk/json/gtkjsonparser.c b/gtk/json/gtkjsonparser.c index 748e2073f0..1b27ddb3c7 100644 --- a/gtk/json/gtkjsonparser.c +++ b/gtk/json/gtkjsonparser.c @@ -980,16 +980,7 @@ gtk_json_parser_new_for_bytes (GBytes *bytes) gtk_json_parser_skip_bom (self); self->start = self->reader; - gtk_json_parser_skip_whitespace (self); - if (gtk_json_parser_is_eof (self)) - { - gtk_json_parser_syntax_error_at (self, self->start, self->reader, "Empty document"); - } - else - { - self->block->value = self->reader; - gtk_json_parser_parse_value (self); - } + gtk_json_parser_rewind (self); return self; } @@ -1165,6 +1156,46 @@ gtk_json_parser_next (GtkJsonParser *self) return TRUE; } +void +gtk_json_parser_rewind (GtkJsonParser *self) +{ + if (self->error) + return; + + switch (self->block->type) + { + case GTK_JSON_BLOCK_OBJECT: + gtk_json_parser_pop_block (self); + self->reader = self->block->value; + gtk_json_parser_start_object (self); + break; + + case GTK_JSON_BLOCK_ARRAY: + gtk_json_parser_pop_block (self); + self->reader = self->block->value; + gtk_json_parser_start_array (self); + break; + + case GTK_JSON_BLOCK_TOPLEVEL: + self->reader = self->start; + gtk_json_parser_skip_whitespace (self); + if (gtk_json_parser_is_eof (self)) + { + gtk_json_parser_syntax_error_at (self, self->start, self->reader, "Empty document"); + } + else + { + self->block->value = self->reader; + gtk_json_parser_parse_value (self); + } + break; + + default: + g_assert_not_reached (); + return; + } +} + gsize gtk_json_parser_get_depth (GtkJsonParser *self) { @@ -1273,7 +1304,7 @@ gtk_json_parser_get_error_location (GtkJsonParser *self, } static gboolean -gtk_json_parser_has_member (GtkJsonParser *self) +gtk_json_parser_supports_member (GtkJsonParser *self) { if (self->error) return FALSE; @@ -1290,12 +1321,61 @@ gtk_json_parser_has_member (GtkJsonParser *self) char * gtk_json_parser_get_member_name (GtkJsonParser *self) { - if (!gtk_json_parser_has_member (self)) + if (!gtk_json_parser_supports_member (self)) return NULL; return gtk_json_unescape_string (self->block->member_name); } +gboolean +gtk_json_parser_has_member (GtkJsonParser *self, + const char *name) +{ + JsonStringIter iter; + gsize found, len; + + if (!gtk_json_parser_supports_member (self)) + return FALSE; + + found = 0; + + for (len = json_string_iter_init (&iter, self->block->member_name); + len > 0; + len = json_string_iter_next (&iter)) + { + const char *s = json_string_iter_get (&iter); + + if (strncmp (name + found, s, len) != 0) + return FALSE; + + found += len; + } + + return TRUE; +} + +gboolean +gtk_json_parser_find_member (GtkJsonParser *self, + const char *name) +{ + if (!gtk_json_parser_supports_member (self)) + { + while (gtk_json_parser_next (self)); + return FALSE; + } + + gtk_json_parser_rewind (self); + + do + { + if (gtk_json_parser_has_member (self, name)) + return TRUE; + } + while (gtk_json_parser_next (self)); + + return FALSE; +} + gssize gtk_json_parser_select_member (GtkJsonParser *self, const char * const *options) @@ -1304,7 +1384,7 @@ gtk_json_parser_select_member (GtkJsonParser *self, gssize i, j; gsize found, len; - if (!gtk_json_parser_has_member (self)) + if (!gtk_json_parser_supports_member (self)) return -1; if (options[0] == NULL) diff --git a/gtk/json/gtkjsonparserprivate.h b/gtk/json/gtkjsonparserprivate.h index 155a5b7603..38f508ab9f 100644 --- a/gtk/json/gtkjsonparserprivate.h +++ b/gtk/json/gtkjsonparserprivate.h @@ -55,9 +55,14 @@ GtkJsonParser * gtk_json_parser_new_for_string (const char void gtk_json_parser_free (GtkJsonParser *self); gboolean gtk_json_parser_next (GtkJsonParser *self); +void gtk_json_parser_rewind (GtkJsonParser *self); gsize gtk_json_parser_get_depth (GtkJsonParser *self); GtkJsonNode gtk_json_parser_get_node (GtkJsonParser *self); char * gtk_json_parser_get_member_name (GtkJsonParser *self); +gboolean gtk_json_parser_has_member (GtkJsonParser *self, + const char *name); +gboolean gtk_json_parser_find_member (GtkJsonParser *self, + const char *name); gssize gtk_json_parser_select_member (GtkJsonParser *self, const char * const *options); |