json.c.types

C types for json1 library

Types 28

Indicates the content of a node.

Object = 0The node contains a JSON object
Array = 1The node contains a JSON array
Value = 2The node contains a fundamental type
Null = 3Special type, for nodes containing null

Error codes for JSON_PARSER_ERROR.

This enumeration can be extended at later date

Parse = 0parse error
TrailingComma = 1unexpected trailing comma
MissingComma = 2expected comma
MissingColon = 3expected colon
InvalidBareword = 4invalid bareword
EmptyMemberName = 5empty member name (Since: 0.16)
InvalidData = 6invalid data (Since: 0.18)
Unknown = 7unknown error

Error codes for JSON_PATH_ERROR.

This enumeration can be extended at later date

Query = 0Invalid query

Error codes for JSON_READER_ERROR.

This enumeration can be extended at later date

NoArray = 0No array found at the current position
InvalidIndex = 1Index out of bounds
NoObject = 2No object found at the current position
InvalidMember = 3Member not found
InvalidNode = 4No valid node found at the current position
NoValue = 5The node at the current position does not hold a value
InvalidType = 6The node at the current position does not hold a value of the desired type
structJsonArray

json.array.Array is the representation of the array type inside JSON.

A json.array.Array contains json.node.Node elements, which may contain fundamental types, other arrays or objects.

Since arrays can be arbitrarily big, copying them can be expensive; for this reason, they are reference counted. You can control the lifetime of a json.array.Array using json.array.Array.ref_ and json.array.Array.unref.

To append an element, use json.array.Array.addElement.

To extract an element at a given index, use json.array.Array.getElement.

To retrieve the entire array in list form, use json.array.Array.getElements.

To retrieve the length of the array, use json.array.Array.getLength.

json.builder.Builder provides an object for generating a JSON tree.

The root of the JSON tree can be either a json.object.ObjectWrap or a json.array.Array. Thus the first call must necessarily be either json.builder.Builder.beginObject or json.builder.Builder.beginArray.

For convenience to language bindings, most json.builder.Builder method return the instance, making it easy to chain function calls.

Using json.builder.Builder

g_autoptr(JsonBuilder) builder = json_builder_new ();

json_builder_begin_object (builder);

json_builder_set_member_name (builder, "url");
json_builder_add_string_value (builder, "http://www.gnome.org/img/flash/two-thirty.png");

json_builder_set_member_name (builder, "size");
json_builder_begin_array (builder);
json_builder_add_int_value (builder, 652);
json_builder_add_int_value (builder, 242);
json_builder_end_array (builder);

json_builder_end_object (builder);

g_autoptr(JsonNode) root = json_builder_get_root (builder);

g_autoptr(JsonGenerator) gen = json_generator_new ();
json_generator_set_root (gen, root);
g_autofree char *str = json_generator_to_data (gen, NULL);

// str now contains the following JSON data
// { "url" : "http://www.gnome.org/img/flash/two-thirty.png", "size" : [ 652, 242 ] }

Fields
GObject parentInstance
Fields
GObjectClass parentClass
void function() JsonReserved1
void function() JsonReserved2

json.generator.Generator provides an object for generating a JSON data stream from a tree of json.node.Node instances, and put it into a buffer or a file.

Fields
GObject parentInstance
Fields
GObjectClass parentClass
void function() JsonReserved1
void function() JsonReserved2
void function() JsonReserved3
void function() JsonReserved4
structJsonNode

A generic container of JSON data types.

json.node.Node can contain fundamental types (integers, booleans, floating point numbers, strings) and complex types (arrays and objects).

When parsing a JSON data stream you extract the root node and walk the node tree by retrieving the type of data contained inside the node with the JSON_NODE_TYPE macro. If the node contains a fundamental type you can retrieve a copy of the gobject.value.Value holding it with the json.node.Node.getValue function, and then use the gobject.value.Value API to extract the data; if the node contains a complex type you can retrieve the json.object.ObjectWrap or the json.array.Array using json.node.Node.getObject or json.node.Node.getArray respectively, and then retrieve the nodes they contain.

A json.node.Node may be marked as immutable using json.node.Node.seal. This marks the node and all its descendents as read-only, and means that subsequent calls to setter functions (such as json.node.Node.setArray) on them will abort as a programmer error. By marking a node tree as immutable, it may be referenced in multiple places and its hash value cached for fast lookups, without the possibility of a value deep within the tree changing and affecting hash values. Immutable nodes may be passed to functions which retain a reference to them without needing to take a copy.

A json.node.Node supports two types of memory management: malloc/free semantics, and reference counting semantics. The two may be mixed to a limited extent: nodes may be allocated (which gives them a reference count of 1), referenced one or more times, unreferenced exactly that number of times (using json.node.Node.unref), then either unreferenced exactly once more or freed (using json.node.Node.free) to destroy them. The json.node.Node.free function must not be used when a node might have a reference count not equal to 1. To this end, JSON-GLib uses json.node.Node.copy and json.node.Node.unref internally.

An iterator object used to iterate over the members of a JSON object.

json.object_iter.ObjectIter must be allocated on the stack and initialised using json.object_iter.ObjectIter.init_ or json.object_iter.ObjectIter.initOrdered.

The iterator is invalidated if the object is modified during iteration.

All the fields in the json.object_iter.ObjectIter structure are private and should never be accessed directly.

Fields
void *[6] privPointer
int[2] privInt
gboolean[1] privBoolean

json.object.ObjectWrap is the representation of the object type inside JSON.

A json.object.ObjectWrap contains json.node.Node "members", which may contain fundamental types, arrays or other objects; each member of an object is accessed using a unique string, or "name".

Since objects can be arbitrarily big, copying them can be expensive; for this reason they are reference counted. You can control the lifetime of a json.object.ObjectWrap using json.object.ObjectWrap.ref_ and json.object.ObjectWrap.unref.

To add or overwrite a member with a given name, use json.object.ObjectWrap.setMember.

To extract a member with a given name, use json.object.ObjectWrap.getMember.

To retrieve the list of members, use json.object.ObjectWrap.getMembers.

To retrieve the size of the object (that is, the number of members it has), use json.object.ObjectWrap.getSize.

json.parser.Parser provides an object for parsing a JSON data stream, either inside a file or inside a static buffer.

Using json.parser.Parser

The json.parser.Parser API is fairly simple:

gboolean
parse_json (const char *filename)
{
  g_autoptr(JsonParser) parser = json_parser_new ();
  g_autoptr(GError) error = NULL

  json_parser_load_from_file (parser, filename, &error);
  if (error != NULL)
    {
      g_critical ("Unable to parse '%s': %s", filename, error->message);
      return FALSE;
    }

  g_autoptr(JsonNode) root = json_parser_get_root (parser);

  // manipulate the object tree from the root node

  return TRUE
}

By default, the entire process of loading the data and parsing it is synchronous; the json.parser.Parser.loadFromStreamAsync API will load the data asynchronously, but parse it in the main context as the signals of the parser must be emitted in the same thread. If you do not use signals, and you wish to also parse the JSON data without blocking, you should use a gio.task.Task and the synchronous json.parser.Parser API inside the task itself.

Fields
GObject parentInstance

The class structure for the JsonParser type.

Fields
GObjectClass parentClass
void function(JsonParser * parser) parseStart
void function(JsonParser * parser) objectStart
void function(JsonParser * parser, JsonObject * object, const(char) * memberName) objectMember
void function(JsonParser * parser, JsonObject * object) objectEnd
void function(JsonParser * parser) arrayStart
void function(JsonParser * parser, JsonArray * array, int index) arrayElement
void function(JsonParser * parser, JsonArray * array) arrayEnd
void function(JsonParser * parser) parseEnd
void function(JsonParser * parser, const(GError) * error) error
void function() JsonReserved1
void function() JsonReserved2
void function() JsonReserved3
void function() JsonReserved4
void function() JsonReserved5
void function() JsonReserved6
void function() JsonReserved7
void function() JsonReserved8
structJsonPath

json.path.Path is a simple class implementing the JSONPath syntax for extracting data out of a JSON tree.

While the semantics of the JSONPath expressions are heavily borrowed by the XPath specification for XML, the syntax follows the ECMAScript origins of JSON.

Once a json.path.Path instance has been created, it has to compile a JSONPath expression using json.path.Path.compile before being able to match it to a JSON tree; the same json.path.Path instance can be used to match multiple JSON trees. It it also possible to compile a new JSONPath expression using the same json.path.Path instance; the previous expression will be discarded only if the compilation of the new expression is successful.

The simple convenience function json.path.Path.query can be used for one-off matching.

Syntax of the JSONPath expressions

A JSONPath expression is composed by path indices and operators. Each path index can either be a member name or an element index inside a JSON tree. A JSONPath expression must start with the `$` operator; each path index is separated using either the dot notation or the bracket notation, e.g.:

// dot notation
$.store.book[0].title

// bracket notation
$['store']['book'][0]['title']

The available operators are:

  • The `$` character represents the root node of the JSON tree, and matches the entire document.
  • Child nodes can either be matched using `.` or `[]`. For instance, both $.store.book and $['store']['book'] match the contents of the book member of the store object.
  • Child nodes can be reached without specifying the whole tree structure through the recursive descent operator, or `..`. For instance, $..author matches all author member in every object.
  • Child nodes can grouped through the wildcard operator, or `*`. For instance, $.store.book[*].author matches all author members of any object element contained in the book array of the store object.
  • Element nodes can be accessed using their index (starting from zero) in the subscript operator `[]`. For instance, $.store.book[0] matches the first element of the book array of the store object.
  • Subsets of element nodes can be accessed using the set notation operator [i,j,...]. For instance, $.store.book[0,2] matches the elements 0 and 2 (the first and third) of the book array of the store object.
  • Slices of element nodes can be accessed using the slice notation operation [start:end:step]. If start is omitted, the starting index of the slice is implied to be zero; if end is omitted, the ending index of the slice is implied to be the length of the array; if step is omitted, the step of the slice is implied to be 1. For instance, $.store.book[:2] matches the first two elements of the book array of the store object.

More information about JSONPath is available on Stefan Gössner's JSONPath website.

Example of JSONPath matches

The following example shows some of the results of using json.path.Path on a JSON tree. We use the following JSON description of a bookstore:

{ "store": {
    "book": [
      { "category": "reference", "author": "Nigel Rees",
        "title": "Sayings of the Century", "price": "8.95"  },
      { "category": "fiction", "author": "Evelyn Waugh",
        "title": "Sword of Honour", "price": "12.99" },
      { "category": "fiction", "author": "Herman Melville",
        "title": "Moby Dick", "isbn": "0-553-21311-3",
        "price": "8.99" },
      { "category": "fiction", "author": "J. R. R. Tolkien",
        "title": "The Lord of the Rings", "isbn": "0-395-19395-8",
        "price": "22.99" }
    ],
    "bicycle": { "color": "red", "price": "19.95" }
  }
}

We can parse the JSON using json.parser.Parser:

JsonParser *parser = json_parser_new ();
json_parser_load_from_data (parser, json_data, -1, NULL);

If we run the following code:

JsonNode *result;
JsonPath *path = json_path_new ();
json_path_compile (path, "$.store..author", NULL);
result = json_path_match (path, json_parser_get_root (parser));

The result node will contain an array with all values of the author member of the objects in the JSON tree. If we use a json.generator.Generator to convert the result node to a string and print it:

JsonGenerator *generator = json_generator_new ();
json_generator_set_root (generator, result);
char *str = json_generator_to_data (generator, NULL);
g_print ("Results: %s\n", str);

The output will be:

["Nigel Rees","Evelyn Waugh","Herman Melville","J. R. R. Tolkien"]

json.reader.Reader provides a simple, cursor-based API for parsing a JSON DOM.

It is similar, in spirit, to the XML Reader API.

Using json.reader.Reader

g_autoptr(JsonParser) parser = json_parser_new ();

// str is defined elsewhere
json_parser_load_from_data (parser, str, -1, NULL);

g_autoptr(JsonReader) reader = json_reader_new (json_parser_get_root (parser));

json_reader_read_member (reader, "url");
  const char *url = json_reader_get_string_value (reader);
  json_reader_end_member (reader);

json_reader_read_member (reader, "size");
  json_reader_read_element (reader, 0);
    int width = json_reader_get_int_value (reader);
    json_reader_end_element (reader);
  json_reader_read_element (reader, 1);
    int height = json_reader_get_int_value (reader);
    json_reader_end_element (reader);
  json_reader_end_member (reader);

Error handling

In case of error, json.reader.Reader will be set in an error state; all subsequent calls will simply be ignored until a function that resets the error state is called, e.g.:

// ask for the 7th element; if the element does not exist, the
// reader will be put in an error state
json_reader_read_element (reader, 6);

// in case of error, this will return NULL, otherwise it will
// return the value of the element
str = json_reader_get_string_value (value);

// this function resets the error state if any was set
json_reader_end_element (reader);

If you want to detect the error state as soon as possible, you can use json.reader.Reader.getError:

// like the example above, but in this case we print out the
// error immediately
if (!json_reader_read_element (reader, 6))
  {
    const GError *error = json_reader_get_error (reader);
    g_print ("Unable to read the element: %s", error->message);
  }

Fields
GObject parentInstance
Fields
GObjectClass parentClass
void function() JsonPadding0
void function() JsonPadding1
void function() JsonPadding2
void function() JsonPadding3
void function() JsonPadding4

json.serializable.Serializable is an interface for controlling the serialization and deserialization of gobject.object.ObjectWrap classes.

Implementing this interface allows controlling how the class is going to be serialized or deserialized by func@Json.construct_gobject and func@Json.serialize_gobject, respectively.

Interface that allows serializing and deserializing object instances with properties storing complex data types.

The func@Json.gobject_from_data and func@Json.gobject_to_data functions will check if the passed object type implements this interface, so it can also be used to override the default property serialization sequence.

Fields
JsonNode * function(JsonSerializable * serializable, const(char) * propertyName, const(GValue) * value, GParamSpec * pspec) serializeProperty
gboolean function(JsonSerializable * serializable, const(char) * propertyName, GValue * value, GParamSpec * pspec, JsonNode * propertyNode) deserializeProperty
GParamSpec * function(JsonSerializable * serializable, const(char) * name) findProperty
GParamSpec * * function(JsonSerializable * serializable, uint * nPspecs) listProperties
void function(JsonSerializable * serializable, GParamSpec * pspec, const(GValue) * value) setProperty
void function(JsonSerializable * serializable, GParamSpec * pspec, GValue * value) getProperty
aliasJsonArrayForeach = void function(JsonArray * array, uint index, JsonNode * elementNode, void * userData)
aliasJsonBoxedDeserializeFunc = void * function(JsonNode * node)
aliasJsonBoxedSerializeFunc = JsonNode * function(const(void) * boxed)
aliasJsonObjectForeach = void function(JsonObject * object, const(char) * memberName, JsonNode * memberNode, void * userData)