[pango/newer-json-parser: 1/3] Update to a newer json parser




commit 5ab710c2c576309f62c4ae3741fb6dd5f98a84f2
Author: Matthias Clasen <mclasen redhat com>
Date:   Wed Dec 8 08:47:15 2021 -0500

    Update to a newer json parser

 pango/json/gtkjsonparser.c        | 144 ++++++++++++++++++++++++++++++++------
 pango/json/gtkjsonparserprivate.h |   2 +
 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);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]