summaryrefslogtreecommitdiff
path: root/pango/json
diff options
context:
space:
mode:
Diffstat (limited to 'pango/json')
-rw-r--r--pango/json/gtkjsonparser.c144
-rw-r--r--pango/json/gtkjsonparserprivate.h2
2 files changed, 124 insertions, 22 deletions
diff --git a/pango/json/gtkjsonparser.c b/pango/json/gtkjsonparser.c
index 5433d535..633251ca 100644
--- a/pango/json/gtkjsonparser.c
+++ b/pango/json/gtkjsonparser.c
@@ -895,7 +895,7 @@ gtk_json_parser_parse_value (GtkJsonParser *self)
(self->block->value[0] == '.' || self->block->value[0] == '+') &&
g_ascii_isdigit (self->block->value[1]))
{
- const guchar *end = self->block->value + 3;
+ const guchar *end = self->block->value + 2;
while (end < self->end && g_ascii_isalnum (*end))
end++;
gtk_json_parser_syntax_error_at (self, self->block->value, end, "Numbers may not start with '%c'", *self->block->value);
@@ -996,7 +996,8 @@ gtk_json_parser_free (GtkJsonParser *self)
if (self->blocks != self->blocks_preallocated)
g_free (self->blocks);
- g_clear_error (&self->error);
+ if (self->error)
+ g_error_free (self->error);
g_slice_free (GtkJsonParser, self);
}
@@ -1375,24 +1376,21 @@ gtk_json_parser_find_member (GtkJsonParser *self,
return FALSE;
}
-gssize
-gtk_json_parser_select_member (GtkJsonParser *self,
- const char * const *options)
+static gssize
+json_string_iter_run_select (const guchar *string_data,
+ const char * const *options)
{
JsonStringIter iter;
gssize i, j;
gsize found, len;
- if (!gtk_json_parser_supports_member (self))
- return -1;
-
- if (options[0] == NULL)
+ if (options == NULL || options[0] == NULL)
return -1;
found = 0;
i = 0;
- for (len = json_string_iter_init (&iter, self->block->member_name);
+ for (len = json_string_iter_init (&iter, string_data);
len > 0;
len = json_string_iter_next (&iter))
{
@@ -1428,6 +1426,16 @@ gtk_json_parser_select_member (GtkJsonParser *self,
return -1;
}
+
+gssize
+gtk_json_parser_select_member (GtkJsonParser *self,
+ const char * const *options)
+{
+ if (!gtk_json_parser_supports_member (self))
+ return -1;
+
+ return json_string_iter_run_select (self->block->member_name, options);
+}
gboolean
gtk_json_parser_get_boolean (GtkJsonParser *self)
@@ -1465,35 +1473,108 @@ gtk_json_parser_get_number (GtkJsonParser *self)
}
errno = 0;
- if (gtk_json_parser_remaining (self) == 0)
+ result = g_ascii_strtod ((const char *) self->block->value, NULL);
+
+ if (errno)
+ {
+ if (errno == ERANGE)
+ gtk_json_parser_value_error (self, "Number out of range");
+ else
+ gtk_json_parser_value_error (self, "%s", g_strerror (errno));
+
+ return 0;
+ }
+
+ return result;
+}
+
+int
+gtk_json_parser_get_int (GtkJsonParser *self)
+{
+ long result;
+ char *end;
+
+ if (self->error)
+ return 0;
+
+ if (self->block->value == NULL)
+ return 0;
+
+ if (!strchr ("-0123456789", *self->block->value))
{
- /* need terminated string here */
- char *s = g_strndup ((const char *) self->block->value, self->reader - self->block->value);
- result = g_ascii_strtod (s, NULL);
- g_free (s);
+ gtk_json_parser_type_error (self, "Expected an intereger");
+ return 0;
}
- else
+
+ errno = 0;
+ result = strtol ((const char *) self->block->value, &end, 10);
+ if (*end == '.' || *end == 'e' || *end == 'E')
{
- result = g_ascii_strtod ((const char *) self->block->value, NULL);
+ gtk_json_parser_type_error (self, "Expected an intereger");
+ return 0;
}
if (errno)
{
if (errno == ERANGE)
- gtk_json_parser_value_error (self, "Number out of range");
+ gtk_json_parser_value_error (self, "Number out of integer range");
else
gtk_json_parser_value_error (self, "%s", g_strerror (errno));
return 0;
}
+ else if (result > G_MAXINT || result < G_MININT)
+ {
+ gtk_json_parser_value_error (self, "Number out of integer range");
+ return 0;
+ }
return result;
}
-#if 0
-int gtk_json_parser_get_int (GtkJsonParser *self);
-guint gtk_json_parser_get_uint (GtkJsonParser *self);
-#endif
+guint
+gtk_json_parser_get_uint (GtkJsonParser *self)
+{
+ gulong result;
+ char *end;
+
+ if (self->error)
+ return 0;
+
+ if (self->block->value == NULL)
+ return 0;
+
+ if (!strchr ("0123456789", *self->block->value))
+ {
+ gtk_json_parser_type_error (self, "Expected an unsigned intereger");
+ return 0;
+ }
+
+ errno = 0;
+ result = strtoul ((const char *) self->block->value, &end, 10);
+ if (*end == '.' || *end == 'e' || *end == 'E')
+ {
+ gtk_json_parser_type_error (self, "Expected an unsigned intereger");
+ return 0;
+ }
+
+ if (errno)
+ {
+ if (errno == ERANGE)
+ gtk_json_parser_value_error (self, "Number out of unsignedinteger range");
+ else
+ gtk_json_parser_value_error (self, "%s", g_strerror (errno));
+
+ return 0;
+ }
+ else if (result > G_MAXUINT)
+ {
+ gtk_json_parser_value_error (self, "Number out of unsigned integer range");
+ return 0;
+ }
+
+ return result;
+}
char *
gtk_json_parser_get_string (GtkJsonParser *self)
@@ -1513,6 +1594,25 @@ gtk_json_parser_get_string (GtkJsonParser *self)
return gtk_json_unescape_string (self->block->value);
}
+gssize
+gtk_json_parser_select_string (GtkJsonParser *self,
+ const char * const *options)
+{
+ if (self->error)
+ return -1;
+
+ if (self->block->value == NULL)
+ return -1;
+
+ if (*self->block->value != '"')
+ {
+ gtk_json_parser_type_error (self, "Expected a string");
+ return -1;
+ }
+
+ return json_string_iter_run_select (self->block->member_name, options);
+}
+
gboolean
gtk_json_parser_start_object (GtkJsonParser *self)
{
diff --git a/pango/json/gtkjsonparserprivate.h b/pango/json/gtkjsonparserprivate.h
index 38f508ab..83f72374 100644
--- a/pango/json/gtkjsonparserprivate.h
+++ b/pango/json/gtkjsonparserprivate.h
@@ -71,6 +71,8 @@ double gtk_json_parser_get_number (GtkJsonParser
int gtk_json_parser_get_int (GtkJsonParser *self);
guint gtk_json_parser_get_uint (GtkJsonParser *self);
char * gtk_json_parser_get_string (GtkJsonParser *self);
+gssize gtk_json_parser_select_string (GtkJsonParser *self,
+ const char * const *options);
gboolean gtk_json_parser_start_object (GtkJsonParser *self);
gboolean gtk_json_parser_start_array (GtkJsonParser *self);