Compare commits
24 Commits
css-render
...
wip/otte/j
Author | SHA1 | Date | |
---|---|---|---|
|
167b19edfc | ||
|
7f43ff0fe8 | ||
|
0dc5caf6b9 | ||
|
fa1d01b2b7 | ||
|
8161c84f76 | ||
|
a147da1120 | ||
|
f953673edb | ||
|
670286eb9e | ||
|
a7a3ec8a16 | ||
|
506b009925 | ||
|
1459810b43 | ||
|
798c35f506 | ||
|
424e5eaf4e | ||
|
9bc458fa8b | ||
|
353a841ec7 | ||
|
0c3e5fdcfb | ||
|
eb84b58ee9 | ||
|
37ccc972bf | ||
|
0265714708 | ||
|
04348ebf87 | ||
|
489d9398df | ||
|
901a9edeb8 | ||
|
7ce2d70e0e | ||
|
8d0e09c086 |
@@ -192,6 +192,9 @@
|
||||
<file>listview_minesweeper.ui</file>
|
||||
<file>listview_minesweeper_cell.ui</file>
|
||||
</gresource>
|
||||
<gresource prefix="/listview_releases">
|
||||
<file>listview_releases.ui</file>
|
||||
</gresource>
|
||||
<gresource prefix="/listview_settings">
|
||||
<file>listview_settings.ui</file>
|
||||
</gresource>
|
||||
@@ -311,6 +314,7 @@
|
||||
<file>listview_filebrowser.c</file>
|
||||
<file>listview_minesweeper.c</file>
|
||||
<file>listview_selections.c</file>
|
||||
<file>listview_releases.c</file>
|
||||
<file>listview_settings.c</file>
|
||||
<file>listview_ucd.c</file>
|
||||
<file>listview_weather.c</file>
|
||||
|
256
demos/gtk-demo/listview_releases.c
Normal file
256
demos/gtk-demo/listview_releases.c
Normal file
@@ -0,0 +1,256 @@
|
||||
/* Lists/Releases
|
||||
* #Keywords: GtkListItemFactory, GListModel,JSON
|
||||
*
|
||||
* This demo downloads GTK's latest release and displays them in a list.
|
||||
*
|
||||
* It shows how hard it still is to get JSON into lists.
|
||||
*/
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include "gtk/json/gtkjsonparserprivate.h"
|
||||
|
||||
#define GTK_TYPE_RELEASE (gtk_release_get_type ())
|
||||
|
||||
G_DECLARE_FINAL_TYPE (GtkRelease, gtk_release, GTK, RELEASE, GObject)
|
||||
|
||||
struct _GtkRelease
|
||||
{
|
||||
GObject parent_instance;
|
||||
|
||||
char *name;
|
||||
GDateTime *timestamp;
|
||||
};
|
||||
|
||||
struct _GtkReleaseClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
};
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
PROP_NAME,
|
||||
PROP_TIMESTAMP,
|
||||
|
||||
N_PROPS
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (GtkRelease, gtk_release, G_TYPE_OBJECT)
|
||||
static GParamSpec *properties[N_PROPS] = { NULL, };
|
||||
|
||||
static void
|
||||
gtk_release_finalize (GObject *object)
|
||||
{
|
||||
GtkRelease *self = GTK_RELEASE (object);
|
||||
|
||||
g_free (self->name);
|
||||
g_clear_pointer (&self->timestamp, g_date_time_unref);
|
||||
|
||||
G_OBJECT_CLASS (gtk_release_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_release_get_property (GObject *object,
|
||||
guint property_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GtkRelease *self = GTK_RELEASE (object);
|
||||
|
||||
switch (property_id)
|
||||
{
|
||||
case PROP_NAME:
|
||||
g_value_set_string (value, self->name);
|
||||
break;
|
||||
|
||||
case PROP_TIMESTAMP:
|
||||
{
|
||||
if (self->timestamp)
|
||||
g_value_take_string (value, g_date_time_format (self->timestamp, "%x"));
|
||||
else
|
||||
g_value_set_string (value, "---");
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_release_class_init (GtkReleaseClass *klass)
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
gobject_class->finalize = gtk_release_finalize;
|
||||
gobject_class->get_property = gtk_release_get_property;
|
||||
|
||||
properties[PROP_NAME] =
|
||||
g_param_spec_string ("name", NULL, NULL, NULL, G_PARAM_READABLE);
|
||||
properties[PROP_TIMESTAMP] =
|
||||
g_param_spec_string ("timestamp", NULL, NULL, NULL, G_PARAM_READABLE);
|
||||
|
||||
g_object_class_install_properties (gobject_class, N_PROPS, properties);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_release_init (GtkRelease *self)
|
||||
{
|
||||
}
|
||||
|
||||
static GtkRelease *
|
||||
gtk_release_new (const char *name,
|
||||
GDateTime *timestamp)
|
||||
{
|
||||
GtkRelease *result;
|
||||
|
||||
result = g_object_new (GTK_TYPE_RELEASE, NULL);
|
||||
|
||||
result->name = g_strdup (name);
|
||||
if (timestamp)
|
||||
result->timestamp = g_date_time_ref (timestamp);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void
|
||||
loaded_some_releases_cb (GObject *file,
|
||||
GAsyncResult *res,
|
||||
gpointer userdata)
|
||||
{
|
||||
GListStore *store = userdata;
|
||||
GBytes *bytes;
|
||||
GtkJsonParser *parser;
|
||||
GError *error = NULL;
|
||||
|
||||
bytes = g_file_load_bytes_finish (G_FILE (file), res, NULL, &error);
|
||||
if (bytes == NULL)
|
||||
{
|
||||
g_printerr ("Error loading: %s\n", error->message);
|
||||
g_clear_error (&error);
|
||||
return;
|
||||
}
|
||||
|
||||
parser = gtk_json_parser_new_for_bytes (bytes);
|
||||
g_bytes_unref (bytes);
|
||||
|
||||
gtk_json_parser_start_array (parser);
|
||||
do
|
||||
{
|
||||
enum { NAME, COMMIT };
|
||||
static const char *options[] = { "name", "commit", NULL };
|
||||
GDateTime *created = NULL;
|
||||
char *name = NULL;
|
||||
|
||||
gtk_json_parser_start_object (parser);
|
||||
do
|
||||
{
|
||||
switch (gtk_json_parser_select_member (parser, options))
|
||||
{
|
||||
case NAME:
|
||||
g_clear_pointer (&name, g_free);
|
||||
name = gtk_json_parser_get_string (parser);
|
||||
break;
|
||||
case COMMIT:
|
||||
g_clear_pointer (&created, g_date_time_unref);
|
||||
gtk_json_parser_start_object (parser);
|
||||
if (gtk_json_parser_find_member (parser, "created_at"))
|
||||
{
|
||||
char *created_string = gtk_json_parser_get_string (parser);
|
||||
created = g_date_time_new_from_iso8601 (created_string, NULL);
|
||||
g_free (created_string);
|
||||
}
|
||||
gtk_json_parser_end (parser);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
while (gtk_json_parser_next (parser));
|
||||
gtk_json_parser_end (parser);
|
||||
|
||||
if (name)
|
||||
{
|
||||
GtkRelease *release = gtk_release_new (name, created);
|
||||
g_list_store_append (store, release);
|
||||
g_object_unref (release);
|
||||
}
|
||||
g_clear_pointer (&name, g_free);
|
||||
g_clear_pointer (&created, g_date_time_unref);
|
||||
}
|
||||
while (gtk_json_parser_next (parser));
|
||||
gtk_json_parser_end (parser);
|
||||
|
||||
if (gtk_json_parser_get_error (parser))
|
||||
{
|
||||
const GError *json_error = gtk_json_parser_get_error (parser);
|
||||
|
||||
g_printerr ("Error parsing: %s\n", json_error->message);
|
||||
}
|
||||
gtk_json_parser_free (parser);
|
||||
|
||||
gtk_toggle_button_set_active (g_object_get_data (G_OBJECT (store), "togglebutton"), FALSE);
|
||||
}
|
||||
|
||||
static void
|
||||
load_some_releases (GListStore *store)
|
||||
{
|
||||
GFile *file;
|
||||
guint n_items;
|
||||
char *url;
|
||||
|
||||
n_items = g_list_model_get_n_items (G_LIST_MODEL (store));
|
||||
if (n_items == 0)
|
||||
url = g_strdup ("https://gitlab.gnome.org/api/v4/projects/665/repository/tags");
|
||||
else
|
||||
url = g_strdup_printf ("https://gitlab.gnome.org/api/v4/projects/665/repository/tags?page=%u", (n_items + 39) / 20);
|
||||
file = g_file_new_for_uri (url);
|
||||
|
||||
g_file_load_bytes_async (file, NULL, loaded_some_releases_cb, store);
|
||||
g_object_unref (file);
|
||||
g_free (url);
|
||||
}
|
||||
|
||||
static GtkWidget *window = NULL;
|
||||
|
||||
GtkWidget *
|
||||
do_listview_releases (GtkWidget *do_widget)
|
||||
{
|
||||
if (window == NULL)
|
||||
{
|
||||
GtkBuilderScope *scope;
|
||||
GtkBuilder *builder;
|
||||
GListStore *list;
|
||||
GtkWidget *more_button;
|
||||
|
||||
g_type_ensure (GTK_TYPE_RELEASE);
|
||||
|
||||
scope = gtk_builder_cscope_new ();
|
||||
gtk_builder_cscope_add_callback_symbol (GTK_BUILDER_CSCOPE (scope), "load_some_releases", (GCallback)load_some_releases);
|
||||
|
||||
builder = gtk_builder_new ();
|
||||
gtk_builder_set_scope (builder, scope);
|
||||
g_object_unref (scope);
|
||||
|
||||
gtk_builder_add_from_resource (builder, "/listview_releases/listview_releases.ui", NULL);
|
||||
|
||||
window = GTK_WIDGET (gtk_builder_get_object (builder, "window"));
|
||||
gtk_window_set_display (GTK_WINDOW (window),
|
||||
gtk_widget_get_display (do_widget));
|
||||
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *) &window);
|
||||
|
||||
more_button = GTK_WIDGET (gtk_builder_get_object (builder, "more_button"));
|
||||
list = G_LIST_STORE (gtk_builder_get_object (builder, "list"));
|
||||
g_object_set_data (G_OBJECT (list), "togglebutton", more_button);
|
||||
load_some_releases (list);
|
||||
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (more_button), TRUE);
|
||||
}
|
||||
|
||||
if (!gtk_widget_get_visible (window))
|
||||
gtk_widget_set_visible (window, TRUE);
|
||||
else
|
||||
gtk_window_destroy (GTK_WINDOW (window));
|
||||
|
||||
return window;
|
||||
}
|
95
demos/gtk-demo/listview_releases.ui
Normal file
95
demos/gtk-demo/listview_releases.ui
Normal file
@@ -0,0 +1,95 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<object class="GListStore" id="list">
|
||||
<property name="item-type">GtkRelease</property>
|
||||
</object>
|
||||
<object class="GtkWindow" id="window">
|
||||
<property name="title" translatable="yes">Releases</property>
|
||||
<property name="default-width">640</property>
|
||||
<property name="default-height">480</property>
|
||||
<child type="titlebar">
|
||||
<object class="GtkHeaderBar">
|
||||
<child type="start">
|
||||
<object class="GtkToggleButton" id="more_button">
|
||||
<property name="label">More…</property>
|
||||
<property name="sensitive" bind-source="more_button" bind-property="active" bind-flags="invert-boolean" />
|
||||
<signal name="clicked" handler="load_some_releases" object="list" swapped="yes"/>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkScrolledWindow">
|
||||
<property name="hexpand">1</property>
|
||||
<property name="vexpand">1</property>
|
||||
<child>
|
||||
<object class="GtkColumnView" id="columnview">
|
||||
<property name="model">
|
||||
<object class="GtkSingleSelection">
|
||||
<property name="model">list</property>
|
||||
</object>
|
||||
</property>
|
||||
<style>
|
||||
<class name="data-table"/>
|
||||
</style>
|
||||
<child>
|
||||
<object class="GtkColumnViewColumn" id="name_column">
|
||||
<property name="title">Name</property>
|
||||
<property name="resizable">1</property>
|
||||
<property name="factory">
|
||||
<object class="GtkBuilderListItemFactory">
|
||||
<property name="bytes"><![CDATA[
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<template class="GtkListItem">
|
||||
<property name="child">
|
||||
<object class="GtkLabel">
|
||||
<property name="xalign">0</property>
|
||||
<binding name="label">
|
||||
<lookup name="name" type="GtkRelease">
|
||||
<lookup name="item">GtkListItem</lookup>
|
||||
</lookup>
|
||||
</binding>
|
||||
</object>
|
||||
</property>
|
||||
</template>
|
||||
</interface>
|
||||
]]></property>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkColumnViewColumn">
|
||||
<property name="title">Date</property>
|
||||
<property name="resizable">1</property>
|
||||
<property name="expand">1</property>
|
||||
<property name="factory">
|
||||
<object class="GtkBuilderListItemFactory">
|
||||
<property name="bytes"><![CDATA[
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<template class="GtkListItem">
|
||||
<property name="child">
|
||||
<object class="GtkLabel">
|
||||
<property name="xalign">0</property>
|
||||
<binding name="label">
|
||||
<lookup name="timestamp" type="GtkRelease">
|
||||
<lookup name="item">GtkListItem</lookup>
|
||||
</lookup>
|
||||
</binding>
|
||||
</object>
|
||||
</property>
|
||||
</template>
|
||||
</interface>
|
||||
]]></property>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</interface>
|
@@ -56,6 +56,7 @@ demos = files([
|
||||
'listview_filebrowser.c',
|
||||
'listview_minesweeper.c',
|
||||
'listview_selections.c',
|
||||
'listview_releases.c',
|
||||
'listview_settings.c',
|
||||
'listview_ucd.c',
|
||||
'listview_weather.c',
|
||||
@@ -103,7 +104,7 @@ demos = files([
|
||||
'font_features.c',
|
||||
])
|
||||
|
||||
gtkdemo_deps = [ libgtk_dep, ]
|
||||
gtkdemo_deps = [ libgtk_dep, libgtk_json_dep ]
|
||||
|
||||
extra_demo_sources = files([
|
||||
'main.c',
|
||||
@@ -248,6 +249,7 @@ executable('gtk4-demo',
|
||||
include_directories: confinc,
|
||||
win_subsystem: 'windows',
|
||||
link_args: extra_demo_ldflags,
|
||||
link_with: [ libgtk_json, ],
|
||||
install: true,
|
||||
)
|
||||
|
||||
|
1735
gtk/json/gtkjsonparser.c
Normal file
1735
gtk/json/gtkjsonparser.c
Normal file
File diff suppressed because it is too large
Load Diff
99
gtk/json/gtkjsonparserprivate.h
Normal file
99
gtk/json/gtkjsonparserprivate.h
Normal file
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
* Copyright © 2021 Benjamin Otte
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: Benjamin Otte <otte@gnome.org>
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __GTK_JSON_PARSER_H__
|
||||
#define __GTK_JSON_PARSER_H__
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef enum {
|
||||
GTK_JSON_NONE,
|
||||
GTK_JSON_NULL,
|
||||
GTK_JSON_BOOLEAN,
|
||||
GTK_JSON_NUMBER,
|
||||
GTK_JSON_STRING,
|
||||
GTK_JSON_OBJECT,
|
||||
GTK_JSON_ARRAY
|
||||
} GtkJsonNode;
|
||||
|
||||
typedef enum {
|
||||
GTK_JSON_ERROR_FAILED,
|
||||
GTK_JSON_ERROR_SYNTAX,
|
||||
GTK_JSON_ERROR_TYPE,
|
||||
GTK_JSON_ERROR_VALUE,
|
||||
GTK_JSON_ERROR_SCHEMA,
|
||||
} GtkJsonError;
|
||||
|
||||
typedef struct _GtkJsonParser GtkJsonParser;
|
||||
|
||||
#define GTK_JSON_ERROR (gtk_json_error_quark ())
|
||||
GQuark gtk_json_error_quark (void);
|
||||
|
||||
GtkJsonParser * gtk_json_parser_new_for_bytes (GBytes *bytes);
|
||||
GtkJsonParser * gtk_json_parser_new_for_string (const char *string,
|
||||
gssize size);
|
||||
|
||||
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);
|
||||
|
||||
gboolean gtk_json_parser_get_boolean (GtkJsonParser *self);
|
||||
double gtk_json_parser_get_number (GtkJsonParser *self);
|
||||
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);
|
||||
gboolean gtk_json_parser_end (GtkJsonParser *self);
|
||||
|
||||
const GError * gtk_json_parser_get_error (GtkJsonParser *self) G_GNUC_PURE;
|
||||
void gtk_json_parser_get_error_offset (GtkJsonParser *self,
|
||||
gsize *start,
|
||||
gsize *end);
|
||||
void gtk_json_parser_get_error_location (GtkJsonParser *self,
|
||||
gsize *start_line,
|
||||
gsize *start_line_bytes,
|
||||
gsize *end_line,
|
||||
gsize *end_line_bytes);
|
||||
void gtk_json_parser_value_error (GtkJsonParser *self,
|
||||
const char *format,
|
||||
...) G_GNUC_PRINTF(2, 3);
|
||||
void gtk_json_parser_schema_error (GtkJsonParser *self,
|
||||
const char *format,
|
||||
...) G_GNUC_PRINTF(2, 3);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GTK_JSON_PARSER_H__ */
|
390
gtk/json/gtkjsonprinter.c
Normal file
390
gtk/json/gtkjsonprinter.c
Normal file
@@ -0,0 +1,390 @@
|
||||
/*
|
||||
* Copyright © 2021 Benjamin Otte
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: Benjamin Otte <otte@gnome.org>
|
||||
*/
|
||||
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "gtkjsonprinterprivate.h"
|
||||
|
||||
typedef struct _GtkJsonBlock GtkJsonBlock;
|
||||
|
||||
typedef enum {
|
||||
GTK_JSON_BLOCK_TOPLEVEL,
|
||||
GTK_JSON_BLOCK_OBJECT,
|
||||
GTK_JSON_BLOCK_ARRAY,
|
||||
} GtkJsonBlockType;
|
||||
|
||||
struct _GtkJsonBlock
|
||||
{
|
||||
GtkJsonBlockType type;
|
||||
gsize n_elements; /* number of elements already written */
|
||||
};
|
||||
|
||||
struct _GtkJsonPrinter
|
||||
{
|
||||
GtkJsonPrinterFlags flags;
|
||||
char *indentation;
|
||||
|
||||
GtkJsonPrinterWriteFunc write_func;
|
||||
gpointer user_data;
|
||||
GDestroyNotify user_destroy;
|
||||
|
||||
GtkJsonBlock *block; /* current block */
|
||||
GtkJsonBlock *blocks; /* blocks array */
|
||||
GtkJsonBlock *blocks_end; /* blocks array */
|
||||
GtkJsonBlock blocks_preallocated[128]; /* preallocated */
|
||||
};
|
||||
|
||||
static void
|
||||
gtk_json_printer_push_block (GtkJsonPrinter *self,
|
||||
GtkJsonBlockType type)
|
||||
{
|
||||
self->block++;
|
||||
if (self->block == self->blocks_end)
|
||||
{
|
||||
gsize old_size = self->blocks_end - self->blocks;
|
||||
gsize new_size = old_size + 128;
|
||||
|
||||
if (self->blocks == self->blocks_preallocated)
|
||||
{
|
||||
self->blocks = g_new (GtkJsonBlock, new_size);
|
||||
memcpy (self->blocks, self->blocks_preallocated, sizeof (GtkJsonBlock) * G_N_ELEMENTS (self->blocks_preallocated));
|
||||
}
|
||||
else
|
||||
{
|
||||
self->blocks = g_renew (GtkJsonBlock, self->blocks, new_size);
|
||||
}
|
||||
self->blocks_end = self->blocks + new_size;
|
||||
self->block = self->blocks + old_size;
|
||||
}
|
||||
|
||||
self->block->type = type;
|
||||
self->block->n_elements = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_json_printer_pop_block (GtkJsonPrinter *self)
|
||||
{
|
||||
g_assert (self->block > self->blocks);
|
||||
self->block--;
|
||||
}
|
||||
|
||||
GtkJsonPrinter *
|
||||
gtk_json_printer_new (GtkJsonPrinterWriteFunc write_func,
|
||||
gpointer data,
|
||||
GDestroyNotify destroy)
|
||||
{
|
||||
GtkJsonPrinter *self;
|
||||
|
||||
g_return_val_if_fail (write_func, NULL);
|
||||
|
||||
self = g_slice_new0 (GtkJsonPrinter);
|
||||
|
||||
self->flags = 0;
|
||||
self->indentation = g_strdup (" ");
|
||||
|
||||
self->write_func = write_func;
|
||||
self->user_data = data;
|
||||
self->user_destroy = destroy;
|
||||
|
||||
self->blocks = self->blocks_preallocated;
|
||||
self->blocks_end = self->blocks + G_N_ELEMENTS (self->blocks_preallocated);
|
||||
self->block = self->blocks;
|
||||
self->block->type = GTK_JSON_BLOCK_TOPLEVEL;
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
void
|
||||
gtk_json_printer_free (GtkJsonPrinter *self)
|
||||
{
|
||||
g_return_if_fail (self != NULL);
|
||||
|
||||
g_free (self->indentation);
|
||||
|
||||
if (self->user_destroy)
|
||||
self->user_destroy (self->user_data);
|
||||
|
||||
if (self->blocks != self->blocks_preallocated)
|
||||
g_free (self->blocks);
|
||||
|
||||
g_slice_free (GtkJsonPrinter, self);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_json_printer_has_flag (GtkJsonPrinter *self,
|
||||
GtkJsonPrinterFlags flag)
|
||||
{
|
||||
return (self->flags & flag) ? TRUE : FALSE;
|
||||
}
|
||||
|
||||
gsize
|
||||
gtk_json_printer_get_depth (GtkJsonPrinter *self)
|
||||
{
|
||||
return self->block - self->blocks;
|
||||
}
|
||||
|
||||
gsize
|
||||
gtk_json_printer_get_n_elements (GtkJsonPrinter *self)
|
||||
{
|
||||
return self->block->n_elements;
|
||||
}
|
||||
|
||||
void
|
||||
gtk_json_printer_set_flags (GtkJsonPrinter *self,
|
||||
GtkJsonPrinterFlags flags)
|
||||
{
|
||||
g_return_if_fail (self != NULL);
|
||||
|
||||
self->flags = flags;
|
||||
}
|
||||
|
||||
GtkJsonPrinterFlags
|
||||
gtk_json_printer_get_flags (GtkJsonPrinter *self)
|
||||
{
|
||||
g_return_val_if_fail (self != NULL, 0);
|
||||
|
||||
return self->flags;
|
||||
}
|
||||
|
||||
void
|
||||
gtk_json_printer_set_indentation (GtkJsonPrinter *self,
|
||||
gsize amount)
|
||||
{
|
||||
g_return_if_fail (self != NULL);
|
||||
|
||||
g_free (self->indentation);
|
||||
|
||||
self->indentation = g_malloc (amount + 1);
|
||||
memset (self->indentation, ' ', amount);
|
||||
self->indentation[amount] = 0;
|
||||
}
|
||||
|
||||
gsize
|
||||
gtk_json_printer_get_indentation (GtkJsonPrinter *self)
|
||||
{
|
||||
g_return_val_if_fail (self != NULL, 2);
|
||||
|
||||
return strlen (self->indentation);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_json_printer_write (GtkJsonPrinter *self,
|
||||
const char *s)
|
||||
{
|
||||
self->write_func (self, s, self->user_data);
|
||||
}
|
||||
|
||||
static char *
|
||||
gtk_json_printer_escape_string (GtkJsonPrinter *self,
|
||||
const char *str)
|
||||
{
|
||||
GString *string;
|
||||
|
||||
string = g_string_new (NULL);
|
||||
string = g_string_append_c (string, '"');
|
||||
|
||||
for (; *str != '\0'; str = g_utf8_next_char (str))
|
||||
{
|
||||
switch (*str)
|
||||
{
|
||||
case '"':
|
||||
g_string_append (string, "\\\"");
|
||||
break;
|
||||
case '\\':
|
||||
g_string_append (string, "\\\\");
|
||||
break;
|
||||
case '\b':
|
||||
g_string_append (string, "\\b");
|
||||
break;
|
||||
case '\f':
|
||||
g_string_append (string, "\\f");
|
||||
break;
|
||||
case '\n':
|
||||
g_string_append (string, "\\n");
|
||||
break;
|
||||
case '\r':
|
||||
g_string_append (string, "\\r");
|
||||
break;
|
||||
case '\t':
|
||||
g_string_append (string, "\\t");
|
||||
break;
|
||||
default:
|
||||
if ((int) *str < 0x20)
|
||||
{
|
||||
if ((guint) *str < 0x20 || gtk_json_printer_has_flag (self, GTK_JSON_PRINTER_ASCII))
|
||||
g_string_append_printf (string, "\\u%04x", g_utf8_get_char (str));
|
||||
else
|
||||
g_string_append_unichar (string, g_utf8_get_char (str));
|
||||
}
|
||||
else
|
||||
g_string_append_c (string, *str);
|
||||
}
|
||||
}
|
||||
|
||||
string = g_string_append_c (string, '"');
|
||||
return g_string_free (string, FALSE);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_json_printer_newline (GtkJsonPrinter *self)
|
||||
{
|
||||
gsize depth;
|
||||
|
||||
if (!gtk_json_printer_has_flag (self, GTK_JSON_PRINTER_PRETTY))
|
||||
return;
|
||||
|
||||
gtk_json_printer_write (self, "\n");
|
||||
for (depth = gtk_json_printer_get_depth (self); depth-->0;)
|
||||
gtk_json_printer_write (self, self->indentation);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_json_printer_begin_member (GtkJsonPrinter *self,
|
||||
const char *name)
|
||||
{
|
||||
if (gtk_json_printer_get_n_elements (self) > 0)
|
||||
gtk_json_printer_write (self, ",");
|
||||
if (self->block->type != GTK_JSON_BLOCK_TOPLEVEL || gtk_json_printer_get_n_elements (self) > 0)
|
||||
gtk_json_printer_newline (self);
|
||||
|
||||
self->block->n_elements++;
|
||||
|
||||
if (name)
|
||||
{
|
||||
char *escaped = gtk_json_printer_escape_string (self, name);
|
||||
gtk_json_printer_write (self, escaped);
|
||||
g_free (escaped);
|
||||
if (gtk_json_printer_has_flag (self, GTK_JSON_PRINTER_PRETTY))
|
||||
gtk_json_printer_write (self, " : ");
|
||||
else
|
||||
gtk_json_printer_write (self, ":");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
gtk_json_printer_add_boolean (GtkJsonPrinter *self,
|
||||
const char *name,
|
||||
gboolean value)
|
||||
{
|
||||
g_return_if_fail (self != NULL);
|
||||
g_return_if_fail ((self->block->type == GTK_JSON_BLOCK_OBJECT) == (name != NULL));
|
||||
|
||||
gtk_json_printer_begin_member (self, name);
|
||||
gtk_json_printer_write (self, value ? "true" : "false");
|
||||
}
|
||||
|
||||
void
|
||||
gtk_json_printer_add_number (GtkJsonPrinter *self,
|
||||
const char *name,
|
||||
double value)
|
||||
{
|
||||
char buf[G_ASCII_DTOSTR_BUF_SIZE];
|
||||
|
||||
g_return_if_fail (self != NULL);
|
||||
g_return_if_fail ((self->block->type == GTK_JSON_BLOCK_OBJECT) == (name != NULL));
|
||||
|
||||
gtk_json_printer_begin_member (self, name);
|
||||
g_ascii_dtostr (buf, G_ASCII_DTOSTR_BUF_SIZE, value);
|
||||
gtk_json_printer_write (self, buf);
|
||||
}
|
||||
|
||||
void
|
||||
gtk_json_printer_add_string (GtkJsonPrinter *self,
|
||||
const char *name,
|
||||
const char *s)
|
||||
{
|
||||
char *escaped;
|
||||
|
||||
g_return_if_fail (self != NULL);
|
||||
g_return_if_fail ((self->block->type == GTK_JSON_BLOCK_OBJECT) == (name != NULL));
|
||||
g_return_if_fail (s != NULL);
|
||||
|
||||
gtk_json_printer_begin_member (self, name);
|
||||
escaped = gtk_json_printer_escape_string (self, s);
|
||||
gtk_json_printer_write (self, escaped);
|
||||
g_free (escaped);
|
||||
}
|
||||
|
||||
void
|
||||
gtk_json_printer_add_null (GtkJsonPrinter *self,
|
||||
const char *name)
|
||||
{
|
||||
g_return_if_fail (self != NULL);
|
||||
g_return_if_fail ((self->block->type == GTK_JSON_BLOCK_OBJECT) == (name != NULL));
|
||||
|
||||
gtk_json_printer_begin_member (self, name);
|
||||
gtk_json_printer_write (self, "null");
|
||||
}
|
||||
|
||||
void
|
||||
gtk_json_printer_start_object (GtkJsonPrinter *self,
|
||||
const char *name)
|
||||
{
|
||||
g_return_if_fail (self != NULL);
|
||||
g_return_if_fail ((self->block->type == GTK_JSON_BLOCK_OBJECT) == (name != NULL));
|
||||
|
||||
gtk_json_printer_begin_member (self, name);
|
||||
gtk_json_printer_write (self, "{");
|
||||
gtk_json_printer_push_block (self, GTK_JSON_BLOCK_OBJECT);
|
||||
}
|
||||
|
||||
void
|
||||
gtk_json_printer_start_array (GtkJsonPrinter *self,
|
||||
const char *name)
|
||||
{
|
||||
g_return_if_fail (self != NULL);
|
||||
g_return_if_fail ((self->block->type == GTK_JSON_BLOCK_OBJECT) == (name != NULL));
|
||||
|
||||
gtk_json_printer_begin_member (self, name);
|
||||
gtk_json_printer_write (self, "[");
|
||||
gtk_json_printer_push_block (self, GTK_JSON_BLOCK_ARRAY);
|
||||
}
|
||||
|
||||
void
|
||||
gtk_json_printer_end (GtkJsonPrinter *self)
|
||||
{
|
||||
const char *bracket;
|
||||
gboolean empty;
|
||||
|
||||
g_return_if_fail (self != NULL);
|
||||
|
||||
switch (self->block->type)
|
||||
{
|
||||
case GTK_JSON_BLOCK_OBJECT:
|
||||
bracket = "}";
|
||||
break;
|
||||
case GTK_JSON_BLOCK_ARRAY:
|
||||
bracket = "]";
|
||||
break;
|
||||
case GTK_JSON_BLOCK_TOPLEVEL:
|
||||
default:
|
||||
g_return_if_reached ();
|
||||
}
|
||||
|
||||
empty = gtk_json_printer_get_n_elements (self) == 0;
|
||||
gtk_json_printer_pop_block (self);
|
||||
|
||||
if (!empty)
|
||||
{
|
||||
gtk_json_printer_newline (self);
|
||||
}
|
||||
gtk_json_printer_write (self, bracket);
|
||||
}
|
||||
|
76
gtk/json/gtkjsonprinterprivate.h
Normal file
76
gtk/json/gtkjsonprinterprivate.h
Normal file
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* Copyright © 2021 Benjamin Otte
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: Benjamin Otte <otte@gnome.org>
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __GTK_JSON_PRINTER_H__
|
||||
#define __GTK_JSON_PRINTER_H__
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef struct _GtkJsonPrinter GtkJsonPrinter;
|
||||
|
||||
typedef enum {
|
||||
GTK_JSON_PRINTER_PRETTY = (1 << 0),
|
||||
GTK_JSON_PRINTER_ASCII = (1 << 1),
|
||||
} GtkJsonPrinterFlags;
|
||||
|
||||
typedef void (* GtkJsonPrinterWriteFunc) (GtkJsonPrinter *printer,
|
||||
const char *s,
|
||||
gpointer user_data);
|
||||
|
||||
|
||||
GtkJsonPrinter * gtk_json_printer_new (GtkJsonPrinterWriteFunc write_func,
|
||||
gpointer data,
|
||||
GDestroyNotify destroy);
|
||||
void gtk_json_printer_free (GtkJsonPrinter *self);
|
||||
|
||||
void gtk_json_printer_set_flags (GtkJsonPrinter *self,
|
||||
GtkJsonPrinterFlags flags);
|
||||
GtkJsonPrinterFlags gtk_json_printer_get_flags (GtkJsonPrinter *self);
|
||||
void gtk_json_printer_set_indentation (GtkJsonPrinter *self,
|
||||
gsize amount);
|
||||
gsize gtk_json_printer_get_indentation (GtkJsonPrinter *self);
|
||||
|
||||
gsize gtk_json_printer_get_depth (GtkJsonPrinter *self);
|
||||
gsize gtk_json_printer_get_n_elements (GtkJsonPrinter *self);
|
||||
|
||||
void gtk_json_printer_add_boolean (GtkJsonPrinter *self,
|
||||
const char *name,
|
||||
gboolean value);
|
||||
void gtk_json_printer_add_number (GtkJsonPrinter *self,
|
||||
const char *name,
|
||||
double value);
|
||||
void gtk_json_printer_add_string (GtkJsonPrinter *self,
|
||||
const char *name,
|
||||
const char *s);
|
||||
void gtk_json_printer_add_null (GtkJsonPrinter *self,
|
||||
const char *name);
|
||||
|
||||
void gtk_json_printer_start_object (GtkJsonPrinter *self,
|
||||
const char *name);
|
||||
void gtk_json_printer_start_array (GtkJsonPrinter *self,
|
||||
const char *name);
|
||||
void gtk_json_printer_end (GtkJsonPrinter *self);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GTK_JSON_PRINTER_H__ */
|
30
gtk/json/meson.build
Normal file
30
gtk/json/meson.build
Normal file
@@ -0,0 +1,30 @@
|
||||
gtk_json_sources = files([
|
||||
'gtkjsonparser.c',
|
||||
'gtkjsonprinter.c',
|
||||
])
|
||||
|
||||
gtk_json_deps = [
|
||||
libm,
|
||||
glib_dep,
|
||||
gobject_dep,
|
||||
platform_gio_dep,
|
||||
]
|
||||
|
||||
libgtk_json = static_library('gtk_json',
|
||||
sources: gtk_json_sources,
|
||||
dependencies: gtk_json_deps,
|
||||
include_directories: [ confinc, ],
|
||||
c_args: [
|
||||
'-DGTK_COMPILATION',
|
||||
'-DG_LOG_DOMAIN="Gtk"',
|
||||
] + common_cflags,
|
||||
)
|
||||
|
||||
# We don't have link_with: to internal static libs here on purpose, just
|
||||
# list the dependencies and generated headers and such, for use in the
|
||||
# "public" libgtk_dep used by internal executables.
|
||||
libgtk_json_dep = declare_dependency(include_directories: [ confinc, ],
|
||||
sources: [ ],
|
||||
link_with: [ libgtk_json ],
|
||||
dependencies: gtk_json_deps,
|
||||
)
|
@@ -747,6 +747,7 @@ build_gir = gir.found() and (get_option('introspection').enabled() or
|
||||
project_build_root = meson.current_build_dir()
|
||||
|
||||
subdir('gtk/css')
|
||||
subdir('gtk/json')
|
||||
subdir('gdk')
|
||||
subdir('gsk')
|
||||
subdir('gtk')
|
||||
|
@@ -0,0 +1 @@
|
||||
[123.456e-789]
|
1
testsuite/json/JSONTestSuite/i_number_huge_exp.json
Normal file
1
testsuite/json/JSONTestSuite/i_number_huge_exp.json
Normal file
@@ -0,0 +1 @@
|
||||
[0.4e00669999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999969999999006]
|
1
testsuite/json/JSONTestSuite/i_number_neg_int_huge_exp.json
Executable file
1
testsuite/json/JSONTestSuite/i_number_neg_int_huge_exp.json
Executable file
@@ -0,0 +1 @@
|
||||
[-1e+9999]
|
1
testsuite/json/JSONTestSuite/i_number_pos_double_huge_exp.json
Executable file
1
testsuite/json/JSONTestSuite/i_number_pos_double_huge_exp.json
Executable file
@@ -0,0 +1 @@
|
||||
[1.5e+9999]
|
@@ -0,0 +1 @@
|
||||
[-123123e100000]
|
@@ -0,0 +1 @@
|
||||
[123123e100000]
|
@@ -0,0 +1 @@
|
||||
[123e-10000000]
|
@@ -0,0 +1 @@
|
||||
[-123123123123123123123123123123]
|
@@ -0,0 +1 @@
|
||||
[100000000000000000000]
|
1
testsuite/json/JSONTestSuite/i_number_very_big_negative_int.json
Executable file
1
testsuite/json/JSONTestSuite/i_number_very_big_negative_int.json
Executable file
@@ -0,0 +1 @@
|
||||
[-237462374673276894279832749832423479823246327846]
|
@@ -0,0 +1 @@
|
||||
1:3-9: syntax error: Invalid UTF-16 surrogate pair
|
@@ -0,0 +1 @@
|
||||
{"\uDFAA":0}
|
@@ -0,0 +1 @@
|
||||
1:3-9: syntax error: Invalid UTF-16 surrogate pair
|
@@ -0,0 +1 @@
|
||||
["\uDADA"]
|
@@ -0,0 +1 @@
|
||||
1:3-15: syntax error: Invalid UTF-16 surrogate pair
|
@@ -0,0 +1 @@
|
||||
["\uD888\u1234"]
|
@@ -0,0 +1 @@
|
||||
1:1: syntax error: Expected a value
|
BIN
testsuite/json/JSONTestSuite/i_string_UTF-16LE_with_BOM.json
Normal file
BIN
testsuite/json/JSONTestSuite/i_string_UTF-16LE_with_BOM.json
Normal file
Binary file not shown.
@@ -0,0 +1 @@
|
||||
1:5: syntax error: Invalid UTF-8
|
1
testsuite/json/JSONTestSuite/i_string_UTF-8_invalid_sequence.json
Executable file
1
testsuite/json/JSONTestSuite/i_string_UTF-8_invalid_sequence.json
Executable file
@@ -0,0 +1 @@
|
||||
["日ш<E697A5>"]
|
@@ -0,0 +1 @@
|
||||
1:3: syntax error: Invalid UTF-8
|
@@ -0,0 +1 @@
|
||||
["<22><><EFBFBD>"]
|
@@ -0,0 +1 @@
|
||||
1:3-9: syntax error: Invalid UTF-16 surrogate pair
|
@@ -0,0 +1 @@
|
||||
["\uD800\n"]
|
@@ -0,0 +1 @@
|
||||
1:3-9: syntax error: Invalid UTF-16 surrogate pair
|
1
testsuite/json/JSONTestSuite/i_string_incomplete_surrogate_pair.json
Executable file
1
testsuite/json/JSONTestSuite/i_string_incomplete_surrogate_pair.json
Executable file
@@ -0,0 +1 @@
|
||||
["\uDd1ea"]
|
@@ -0,0 +1 @@
|
||||
1:3-15: syntax error: Invalid UTF-16 surrogate pair
|
@@ -0,0 +1 @@
|
||||
["\uD800\uD800\n"]
|
@@ -0,0 +1 @@
|
||||
1:3-9: syntax error: Invalid UTF-16 surrogate pair
|
1
testsuite/json/JSONTestSuite/i_string_invalid_lonely_surrogate.json
Executable file
1
testsuite/json/JSONTestSuite/i_string_invalid_lonely_surrogate.json
Executable file
@@ -0,0 +1 @@
|
||||
["\ud800"]
|
@@ -0,0 +1 @@
|
||||
1:3-9: syntax error: Invalid UTF-16 surrogate pair
|
1
testsuite/json/JSONTestSuite/i_string_invalid_surrogate.json
Executable file
1
testsuite/json/JSONTestSuite/i_string_invalid_surrogate.json
Executable file
@@ -0,0 +1 @@
|
||||
["\ud800abc"]
|
@@ -0,0 +1 @@
|
||||
1:3: syntax error: Invalid UTF-8
|
1
testsuite/json/JSONTestSuite/i_string_invalid_utf-8.json
Normal file
1
testsuite/json/JSONTestSuite/i_string_invalid_utf-8.json
Normal file
@@ -0,0 +1 @@
|
||||
["<22>"]
|
@@ -0,0 +1 @@
|
||||
1:3-15: syntax error: Invalid UTF-16 surrogate pair
|
1
testsuite/json/JSONTestSuite/i_string_inverted_surrogates_U+1D11E.json
Executable file
1
testsuite/json/JSONTestSuite/i_string_inverted_surrogates_U+1D11E.json
Executable file
@@ -0,0 +1 @@
|
||||
["\uDd1e\uD834"]
|
1
testsuite/json/JSONTestSuite/i_string_iso_latin_1.error
Normal file
1
testsuite/json/JSONTestSuite/i_string_iso_latin_1.error
Normal file
@@ -0,0 +1 @@
|
||||
1:3: syntax error: Invalid UTF-8
|
1
testsuite/json/JSONTestSuite/i_string_iso_latin_1.json
Normal file
1
testsuite/json/JSONTestSuite/i_string_iso_latin_1.json
Normal file
@@ -0,0 +1 @@
|
||||
["<22>"]
|
@@ -0,0 +1 @@
|
||||
1:3-9: syntax error: Invalid UTF-16 surrogate pair
|
@@ -0,0 +1 @@
|
||||
["\uDFAA"]
|
@@ -0,0 +1 @@
|
||||
1:3: syntax error: Invalid UTF-8
|
@@ -0,0 +1 @@
|
||||
["<22>"]
|
@@ -0,0 +1 @@
|
||||
1:3: syntax error: Invalid UTF-8
|
@@ -0,0 +1 @@
|
||||
["<22><><EFBFBD><EFBFBD>"]
|
@@ -0,0 +1 @@
|
||||
1:3: syntax error: Invalid UTF-8
|
@@ -0,0 +1 @@
|
||||
["<22><>"]
|
@@ -0,0 +1 @@
|
||||
1:3: syntax error: Invalid UTF-8
|
1
testsuite/json/JSONTestSuite/i_string_overlong_sequence_6_bytes.json
Executable file
1
testsuite/json/JSONTestSuite/i_string_overlong_sequence_6_bytes.json
Executable file
@@ -0,0 +1 @@
|
||||
["<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>"]
|
@@ -0,0 +1 @@
|
||||
1:3: syntax error: Invalid UTF-8
|
@@ -0,0 +1 @@
|
||||
["<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>"]
|
@@ -0,0 +1 @@
|
||||
1:3: syntax error: Invalid UTF-8
|
@@ -0,0 +1 @@
|
||||
["<22><>"]
|
@@ -0,0 +1 @@
|
||||
1:1: syntax error: Unexpected nul byte in document
|
BIN
testsuite/json/JSONTestSuite/i_string_utf16BE_no_BOM.json
Normal file
BIN
testsuite/json/JSONTestSuite/i_string_utf16BE_no_BOM.json
Normal file
Binary file not shown.
@@ -0,0 +1 @@
|
||||
1:2: syntax error: Unexpected nul byte in document
|
BIN
testsuite/json/JSONTestSuite/i_string_utf16LE_no_BOM.json
Normal file
BIN
testsuite/json/JSONTestSuite/i_string_utf16LE_no_BOM.json
Normal file
Binary file not shown.
@@ -0,0 +1 @@
|
||||
[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]
|
1
testsuite/json/JSONTestSuite/i_structure_UTF-8_BOM_empty_object.json
Executable file
1
testsuite/json/JSONTestSuite/i_structure_UTF-8_BOM_empty_object.json
Executable file
@@ -0,0 +1 @@
|
||||
{}
|
@@ -0,0 +1 @@
|
||||
1:4-8: syntax error: Expected a ',' to separate array members
|
@@ -0,0 +1 @@
|
||||
[1 true]
|
@@ -0,0 +1 @@
|
||||
1:2-3: syntax error: Expected a value
|
1
testsuite/json/JSONTestSuite/n_array_a_invalid_utf8.json
Normal file
1
testsuite/json/JSONTestSuite/n_array_a_invalid_utf8.json
Normal file
@@ -0,0 +1 @@
|
||||
[a<EFBFBD>]
|
@@ -0,0 +1 @@
|
||||
1:4-5: syntax error: Expected a ',' to separate array members
|
@@ -0,0 +1 @@
|
||||
["": 1]
|
@@ -0,0 +1 @@
|
||||
1:5-6: syntax error: Data at end of document
|
@@ -0,0 +1 @@
|
||||
[""],
|
@@ -0,0 +1 @@
|
||||
1:2-3: syntax error: Expected a value
|
1
testsuite/json/JSONTestSuite/n_array_comma_and_number.json
Executable file
1
testsuite/json/JSONTestSuite/n_array_comma_and_number.json
Executable file
@@ -0,0 +1 @@
|
||||
[,1]
|
1
testsuite/json/JSONTestSuite/n_array_double_comma.error
Normal file
1
testsuite/json/JSONTestSuite/n_array_double_comma.error
Normal file
@@ -0,0 +1 @@
|
||||
1:4-5: syntax error: Expected a value
|
1
testsuite/json/JSONTestSuite/n_array_double_comma.json
Executable file
1
testsuite/json/JSONTestSuite/n_array_double_comma.json
Executable file
@@ -0,0 +1 @@
|
||||
[1,,2]
|
@@ -0,0 +1 @@
|
||||
1:6-7: syntax error: Expected a value
|
@@ -0,0 +1 @@
|
||||
["x",,]
|
1
testsuite/json/JSONTestSuite/n_array_extra_close.error
Normal file
1
testsuite/json/JSONTestSuite/n_array_extra_close.error
Normal file
@@ -0,0 +1 @@
|
||||
1:6-7: syntax error: Data at end of document
|
1
testsuite/json/JSONTestSuite/n_array_extra_close.json
Normal file
1
testsuite/json/JSONTestSuite/n_array_extra_close.json
Normal file
@@ -0,0 +1 @@
|
||||
["x"]]
|
1
testsuite/json/JSONTestSuite/n_array_extra_comma.error
Normal file
1
testsuite/json/JSONTestSuite/n_array_extra_comma.error
Normal file
@@ -0,0 +1 @@
|
||||
1:5-6: syntax error: Expected a value
|
1
testsuite/json/JSONTestSuite/n_array_extra_comma.json
Normal file
1
testsuite/json/JSONTestSuite/n_array_extra_comma.json
Normal file
@@ -0,0 +1 @@
|
||||
["",]
|
1
testsuite/json/JSONTestSuite/n_array_incomplete.error
Normal file
1
testsuite/json/JSONTestSuite/n_array_incomplete.error
Normal file
@@ -0,0 +1 @@
|
||||
1:1-5: syntax error: Unterminated array
|
1
testsuite/json/JSONTestSuite/n_array_incomplete.json
Normal file
1
testsuite/json/JSONTestSuite/n_array_incomplete.json
Normal file
@@ -0,0 +1 @@
|
||||
["x"
|
@@ -0,0 +1 @@
|
||||
1:2-3: syntax error: Expected a value
|
@@ -0,0 +1 @@
|
||||
[x
|
@@ -0,0 +1 @@
|
||||
1:3-4: syntax error: Expected a ',' to separate array members
|
@@ -0,0 +1 @@
|
||||
[3[4]]
|
1
testsuite/json/JSONTestSuite/n_array_invalid_utf8.error
Normal file
1
testsuite/json/JSONTestSuite/n_array_invalid_utf8.error
Normal file
@@ -0,0 +1 @@
|
||||
1:2: syntax error: Expected a value
|
1
testsuite/json/JSONTestSuite/n_array_invalid_utf8.json
Normal file
1
testsuite/json/JSONTestSuite/n_array_invalid_utf8.json
Normal file
@@ -0,0 +1 @@
|
||||
[<EFBFBD>]
|
@@ -0,0 +1 @@
|
||||
1:3-4: syntax error: Expected a ',' to separate array members
|
1
testsuite/json/JSONTestSuite/n_array_items_separated_by_semicolon.json
Executable file
1
testsuite/json/JSONTestSuite/n_array_items_separated_by_semicolon.json
Executable file
@@ -0,0 +1 @@
|
||||
[1:2]
|
1
testsuite/json/JSONTestSuite/n_array_just_comma.error
Normal file
1
testsuite/json/JSONTestSuite/n_array_just_comma.error
Normal file
@@ -0,0 +1 @@
|
||||
1:2-3: syntax error: Expected a value
|
1
testsuite/json/JSONTestSuite/n_array_just_comma.json
Executable file
1
testsuite/json/JSONTestSuite/n_array_just_comma.json
Executable file
@@ -0,0 +1 @@
|
||||
[,]
|
1
testsuite/json/JSONTestSuite/n_array_just_minus.error
Normal file
1
testsuite/json/JSONTestSuite/n_array_just_minus.error
Normal file
@@ -0,0 +1 @@
|
||||
1:2-3: syntax error: Expected a number after '-' character
|
1
testsuite/json/JSONTestSuite/n_array_just_minus.json
Executable file
1
testsuite/json/JSONTestSuite/n_array_just_minus.json
Executable file
@@ -0,0 +1 @@
|
||||
[-]
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user