Ejemplo n.º 1
0
static void
json_node_unset (JsonNode *node)
{
  /* Note: Don't use JSON_NODE_IS_VALID here because this may legitimately be
   * called with (node->ref_count == 0) from json_node_unref(). */
  g_assert (node != NULL);

  switch (node->type)
    {
    case JSON_NODE_OBJECT:
      if (node->data.object)
        json_object_unref (node->data.object);
      break;

    case JSON_NODE_ARRAY:
      if (node->data.array)
        json_array_unref (node->data.array);
      break;

    case JSON_NODE_VALUE:
      if (node->data.value)
        json_value_unref (node->data.value);
      break;

    case JSON_NODE_NULL:
      break;
    }
}
Ejemplo n.º 2
0
static void
json_builder_state_free (JsonBuilderState *state)
{
  if (G_LIKELY (state))
    {
      switch (state->mode)
        {
        case JSON_BUILDER_MODE_OBJECT:
        case JSON_BUILDER_MODE_MEMBER:
          json_object_unref (state->data.object);
          g_free (state->member_name);
          state->data.object = NULL;
          state->member_name = NULL;
          break;

        case JSON_BUILDER_MODE_ARRAY:
          json_array_unref (state->data.array);
          state->data.array = NULL;
          break;

        default:
          g_assert_not_reached ();
        }

      g_slice_free (JsonBuilderState, state);
    }
}
Ejemplo n.º 3
0
static void
json_node_unset (JsonNode *node)
{
  g_assert (node != NULL);

  switch (node->type)
    {
    case JSON_NODE_OBJECT:
      if (node->data.object)
        json_object_unref (node->data.object);
      break;

    case JSON_NODE_ARRAY:
      if (node->data.array)
        json_array_unref (node->data.array);
      break;

    case JSON_NODE_VALUE:
      if (node->data.value)
        json_value_unref (node->data.value);
      break;

    case JSON_NODE_NULL:
      break;
    }
}
Ejemplo n.º 4
0
static JsonGenerator *
_model_to_generator (MexQueueModel *model)
{
  gint i;
  JsonArray *json_array;
  JsonNode *root;
  JsonGenerator *generator;

  json_array = json_array_sized_new (mex_model_get_length (MEX_MODEL (model)));

  for (i = 0; i < mex_model_get_length (MEX_MODEL (model)); i++)
    {
      MexContent *content;
      JsonNode *content_node;

      content = mex_model_get_content (MEX_MODEL (model), i);

      content_node = json_gobject_serialize (G_OBJECT (content));
      json_array_add_element (json_array, content_node);
    }

  generator = json_generator_new ();
  root = json_node_new (JSON_NODE_ARRAY);
  json_node_set_array (root, json_array);

  json_generator_set_root (generator, root);

  json_array_unref (json_array);
  json_node_free (root);

  return generator;
}
Ejemplo n.º 5
0
/* Register a JSON-RPC method */
static void
melo_jsonrpc_free_method (gpointer data)
{
  MeloJSONRPCInternalMethod *m = data;

  /* Free nodes */
  if (m->params)
    json_array_unref (m->params);
  if (m->result)
    json_object_unref (m->result);

  /* Free method */
  g_slice_free (MeloJSONRPCInternalMethod, m);
}
Ejemplo n.º 6
0
/**
 * json_node_set_array:
 * @node: a #JsonNode initialized to %JSON_NODE_ARRAY
 * @array: a #JsonArray
 *
 * Sets @array inside @node and increases the #JsonArray reference count
 */
void
json_node_set_array (JsonNode  *node,
                     JsonArray *array)
{
  g_return_if_fail (node != NULL);
  g_return_if_fail (JSON_NODE_TYPE (node) == JSON_NODE_ARRAY);

  if (node->data.array)
    json_array_unref (node->data.array);

  if (array)
    node->data.array = json_array_ref (array);
  else
    node->data.array = NULL;
}
Ejemplo n.º 7
0
static void
consume_array_member (JsonBuilder *bob, const char* elm, JsonArray *arr)
{
	JsonNode *node;

	if (!arr)
		return; /* nothing to do */

	node = json_node_new (JSON_NODE_ARRAY);
	json_node_init_array (node, arr);
	json_array_unref (arr);

	bob = json_builder_set_member_name (bob, elm);
	bob = json_builder_add_value (bob, node); /* consumes */
}
Ejemplo n.º 8
0
/**
 * json_node_take_array:
 * @node: a #JsonNode initialized to %JSON_NODE_ARRAY
 * @array: (transfer full): a #JsonArray
 *
 * Sets @array into @node without increasing the #JsonArray reference count.
 */
void
json_node_take_array (JsonNode  *node,
                      JsonArray *array)
{
  g_return_if_fail (node != NULL);
  g_return_if_fail (JSON_NODE_TYPE (node) == JSON_NODE_ARRAY);

  if (node->data.array)
    {
      json_array_unref (node->data.array);
      node->data.array = NULL;
    }

  if (array)
    node->data.array = array;
}
Ejemplo n.º 9
0
static void
postal_http_reply_devices (PostalHttp  *http,
                           SoupMessage *message,
                           guint        status,
                           GPtrArray   *devices)
{
   JsonGenerator *g;
   PostalDevice *device;
   JsonArray *ar;
   JsonNode *node;
   JsonNode *child;
   gchar *json_buf;
   gsize length;
   guint i;

   g_assert(SOUP_IS_MESSAGE(message));
   g_assert(devices);

   ar = json_array_new();
   node = json_node_new(JSON_NODE_ARRAY);

   for (i = 0; i < devices->len; i++) {
      device = g_ptr_array_index(devices, i);
      if ((child = postal_device_save_to_json(device, NULL))) {
         json_array_add_element(ar, child);
      }
   }

   json_node_set_array(node, ar);
   json_array_unref(ar);

   g = json_generator_new();
   json_generator_set_root(g, node);
   json_node_free(node);
   json_generator_set_indent(g, 2);
   json_generator_set_pretty(g, TRUE);
   json_buf = json_generator_to_data(g, &length);
   g_object_unref(g);

   soup_message_set_response(message,
                             "application/json",
                             SOUP_MEMORY_TAKE,
                             json_buf,
                             length);
   soup_message_set_status(message, status ?: SOUP_STATUS_OK);
   soup_server_unpause_message(http->priv->server, message);
}
Ejemplo n.º 10
0
static JsonNode *
gvariant_to_json_array (GVariant *variant)
{
  JsonArray *array;
  JsonNode *json_node;

  array = json_array_new ();
  json_node = json_node_new (JSON_NODE_ARRAY);
  json_node_set_array (json_node, array);
  json_array_unref (array);

  gvariant_foreach (variant,
                    gvariant_to_json_array_foreach,
                    array);

  return json_node;
}
Ejemplo n.º 11
0
/**
 * json_array_add_array_element:
 * @array: a #JsonArray
 * @value: (allow-none) (transfer full): a #JsonArray
 *
 * Conveniently adds an array into @array. The @array takes ownership
 * of the newly added #JsonArray
 *
 * See also: json_array_add_element(), json_node_take_array()
 *
 * Since: 0.8
 */
void
json_array_add_array_element (JsonArray *array,
                              JsonArray *value)
{
  JsonNode *node;

  g_return_if_fail (array != NULL);

  node = json_node_alloc ();

  if (value != NULL)
    {
      json_node_init_array (node, value);
      json_array_unref (value);
    }
  else
    json_node_init_null (node);

  g_ptr_array_add (array->elements, node);
}
Ejemplo n.º 12
0
/**
 * melo_jsonrpc_get_array:
 * @schema_params: the schema to use for parameters conversion (see
 *    #MeloJSONRPCMethod for more details)
 * @params: the parameters to convert
 * @error: a pointer to a #JsonNode which is set with a valid JSON-RPC error if
 *    an error has occurred
 *
 * Convert the #JsonNode containing the parameters into a #JsonArray with all
 * items sorted as the provided schema.
 *
 * Returns: (transfer full): a new #JsonArray containing all parameters sorted
 * as provided schema, or %NULL if an error occurred. Use json_array_unref()
 * after usage.
 */
JsonArray *
melo_jsonrpc_get_array (JsonArray *schema_params, JsonNode *params,
                        JsonNode **error)
{
  JsonArray *array;
  guint count;

  /* Get array length */
  count = json_array_get_length (schema_params);

  /* Allocate new array */
  array = json_array_sized_new (count);

  /* Get array */
  if (!melo_jsonrpc_get_json_node (schema_params, params, NULL, array, error)) {
    json_array_unref (array);
    return NULL;
  }

  return array;
}
Ejemplo n.º 13
0
/**
 * json_object_set_array_member:
 * @object: a #JsonObject
 * @member_name: the name of the member
 * @value: (transfer full): the value of the member
 *
 * Convenience function for setting an array @value of
 * @member_name inside @object.
 *
 * The @object will take ownership of the passed #JsonArray
 *
 * See also: json_object_set_member()
 *
 * Since: 0.8
 */
void
json_object_set_array_member (JsonObject  *object,
                              const gchar *member_name,
                              JsonArray   *value)
{
  JsonNode *node;

  g_return_if_fail (object != NULL);
  g_return_if_fail (member_name != NULL);

  node = json_node_alloc ();

  if (value != NULL)
    {
      json_node_init_array (node, value);
      json_array_unref (value);
    }
  else
    json_node_init_null (node);

  object_set_member_internal (object, member_name, node);
}
static void
trg_torrent_move_response_cb(GtkDialog * dlg, gint res_id, gpointer data)
{
    TrgTorrentMoveDialogPrivate *priv =
        TRG_TORRENT_MOVE_DIALOG_GET_PRIVATE(dlg);

    if (res_id == GTK_RESPONSE_ACCEPT) {
        gchar *location =
            trg_destination_combo_get_dir(TRG_DESTINATION_COMBO
                                          (priv->location_combo));
        JsonNode *request = torrent_set_location(priv->ids, location,
                                                 gtk_toggle_button_get_active
                                                 (GTK_TOGGLE_BUTTON
                                                  (priv->move_check)));
        g_free(location);
        trg_destination_combo_save_selection(TRG_DESTINATION_COMBO
                                             (priv->location_combo));
        dispatch_async(priv->client, request,
                       on_generic_interactive_action_response, data);
    } else {
        json_array_unref(priv->ids);
    }
    gtk_widget_destroy(GTK_WIDGET(dlg));
}
Ejemplo n.º 15
0
JsonNode *
json_serialize_pspec (const GValue *real_value,
                      GParamSpec   *pspec)
{
  JsonNode *retval = NULL;
  JsonNodeType node_type;

  switch (G_TYPE_FUNDAMENTAL (G_VALUE_TYPE (real_value)))
    {
    /* JSON native types */
    case G_TYPE_INT64:
      retval = json_node_init_int (json_node_alloc (), g_value_get_int64 (real_value));
      break;

    case G_TYPE_BOOLEAN:
      retval = json_node_init_boolean (json_node_alloc (), g_value_get_boolean (real_value));
      break;

    case G_TYPE_DOUBLE:
      retval = json_node_init_double (json_node_alloc (), g_value_get_double (real_value));
      break;

    case G_TYPE_STRING:
      retval = json_node_init_string (json_node_alloc (), g_value_get_string (real_value));
      break;

    /* auto-promoted types */
    case G_TYPE_INT:
      retval = json_node_init_int (json_node_alloc (), g_value_get_int (real_value));
      break;

    case G_TYPE_UINT:
      retval = json_node_init_int (json_node_alloc (), g_value_get_uint (real_value));
      break;

    case G_TYPE_LONG:
      retval = json_node_init_int (json_node_alloc (), g_value_get_long (real_value));
      break;

    case G_TYPE_ULONG:
      retval = json_node_init_int (json_node_alloc (), g_value_get_ulong (real_value));
      break;

    case G_TYPE_UINT64:
      retval = json_node_init_int (json_node_alloc (), g_value_get_uint64 (real_value));
      break;

    case G_TYPE_FLOAT:
      retval = json_node_init_double (json_node_alloc (), g_value_get_float (real_value));
      break;

    case G_TYPE_CHAR:
      retval = json_node_alloc ();
      json_node_init_int (retval, g_value_get_schar (real_value));
      break;

    case G_TYPE_UCHAR:
      retval = json_node_init_int (json_node_alloc (), g_value_get_uchar (real_value));
      break;

    case G_TYPE_ENUM:
      retval = json_node_init_int (json_node_alloc (), g_value_get_enum (real_value));
      break;

    case G_TYPE_FLAGS:
      retval = json_node_init_int (json_node_alloc (), g_value_get_flags (real_value));
      break;

    /* complex types */
    case G_TYPE_BOXED:
      if (G_VALUE_HOLDS (real_value, G_TYPE_STRV))
        {
          gchar **strv = g_value_get_boxed (real_value);
          gint i, strv_len;
          JsonArray *array;

          strv_len = g_strv_length (strv);
          array = json_array_sized_new (strv_len);

          for (i = 0; i < strv_len; i++)
            {
              JsonNode *str = json_node_new (JSON_NODE_VALUE);

              json_node_set_string (str, strv[i]);
              json_array_add_element (array, str);
            }

          retval = json_node_init_array (json_node_alloc (), array);
          json_array_unref (array);
        }
      else if (json_boxed_can_serialize (G_VALUE_TYPE (real_value), &node_type))
        {
          gpointer boxed = g_value_get_boxed (real_value);

          retval = json_boxed_serialize (G_VALUE_TYPE (real_value), boxed);
        }
      else
        g_warning ("Boxed type '%s' is not handled by JSON-GLib",
                   g_type_name (G_VALUE_TYPE (real_value)));
      break;

    case G_TYPE_OBJECT:
      {
        GObject *object = g_value_get_object (real_value);

        retval = json_node_alloc ();

        if (object != NULL)
          {
            json_node_init (retval, JSON_NODE_OBJECT);
            json_node_take_object (retval, json_gobject_dump (object));
          }
        else
          json_node_init_null (retval);
      }
      break;

    case G_TYPE_NONE:
      retval = json_node_new (JSON_NODE_NULL);
      break;

    default:
      g_warning ("Unsupported type `%s'", g_type_name (G_VALUE_TYPE (real_value)));
      break;
    }

  return retval;
}
Ejemplo n.º 16
0
Archivo: util.c Proyecto: hean01/castio
JsonNode *
js_util_tojsonnode(js_State *state, int idx)
{
  const char *s;
  JsonNode *node;
  JsonNode *tmp;
  JsonObject *object;
  JsonArray *array;
  unsigned int i, length;

  node = json_node_alloc();

  if (js_isstring(state, idx))
  {
    json_node_init_string(node, js_tostring(state, idx));
  }

  else if (js_isnumber(state, idx))
  {
    json_node_init_int(node, js_tointeger(state, idx));
  }

  else if (js_isboolean(state, idx))
  {
    json_node_init_boolean(node, js_toboolean(state, idx));
  }

  else if (js_isarray(state, idx))
  {
    length = js_getlength(state, idx);

    array = json_array_new();
    json_node_init_array(node, array);

    for (i = 0; i < length; i++)
    {
      js_getindex(state, idx, i);
      tmp = js_util_tojsonnode(state, -1);

      if (tmp)
	json_array_add_element(array, tmp);

      js_pop(state, 1);
    }

    json_array_unref(array);
  }

  else if (js_isobject(state, idx))
  {
    object = json_object_new();
    json_node_init_object(node, object);

    js_pushiterator(state, idx, 1);
    while((s = js_nextiterator(state, -1)) != NULL)
    {
      if (idx > 0) js_getproperty(state, idx, s);
      else js_getproperty(state, idx - 1, s);

      tmp = js_util_tojsonnode(state, -1);
      if (tmp)
	json_object_set_member(object, s, tmp);

      js_pop(state, 1);
    }

    js_pop(state, 1);

    json_object_unref(object);
  }

  else
  {
    json_node_free(node);
    return NULL;
  }

  return node;
}
Ejemplo n.º 17
0
static guint
json_parse_array (JsonParser   *parser,
                  JsonScanner  *scanner,
                  JsonNode    **node)
{
  JsonParserPrivate *priv = parser->priv;
  JsonNode *old_current;
  JsonArray *array;
  guint token;
  gint idx;

  old_current = priv->current_node;
  priv->current_node = json_node_new (JSON_NODE_ARRAY);

  array = json_array_new ();

  token = json_scanner_get_next_token (scanner);
  g_assert (token == G_TOKEN_LEFT_BRACE);

  g_signal_emit (parser, parser_signals[ARRAY_START], 0);

  idx = 0;
  while (token != G_TOKEN_RIGHT_BRACE)
    {
      guint next_token = json_scanner_peek_next_token (scanner);
      JsonNode *element = NULL;

      /* parse the element */
      switch (next_token)
        {
        case G_TOKEN_LEFT_BRACE:
          token = json_parse_array (parser, scanner, &element);
          break;

        case G_TOKEN_LEFT_CURLY:
          token = json_parse_object (parser, scanner, &element);
          break;

        case G_TOKEN_INT:
        case G_TOKEN_FLOAT:
        case G_TOKEN_STRING:
        case '-':
        case JSON_TOKEN_TRUE:
        case JSON_TOKEN_FALSE:
        case JSON_TOKEN_NULL:
          token = json_scanner_get_next_token (scanner);
          token = json_parse_value (parser, scanner, token, &element);
          break;

        case G_TOKEN_RIGHT_BRACE:
          goto array_done;

        default:
          if (next_token != G_TOKEN_RIGHT_BRACE)
            token = G_TOKEN_RIGHT_BRACE;
          break;
        }

      if (token != G_TOKEN_NONE || element == NULL)
        {
          /* the json_parse_* functions will have set the error code */
          json_array_unref (array);
          json_node_free (priv->current_node);
          priv->current_node = old_current;

          return token;
        }

      next_token = json_scanner_peek_next_token (scanner);

      if (next_token == G_TOKEN_COMMA)
        {
          token = json_scanner_get_next_token (scanner);
          next_token = json_scanner_peek_next_token (scanner);

          /* look for trailing commas */
          if (next_token == G_TOKEN_RIGHT_BRACE)
            {
              json_array_unref (array);
              json_node_free (priv->current_node);
              json_node_free (element);
              priv->current_node = old_current;

              return G_TOKEN_RIGHT_BRACE;
            }
        }

      json_node_set_parent (element, priv->current_node);
      json_array_add_element (array, element);

      g_signal_emit (parser, parser_signals[ARRAY_ELEMENT], 0,
                     array,
                     idx);

      token = next_token;
    }

array_done:
  json_scanner_get_next_token (scanner);

  json_node_take_array (priv->current_node, array);
  json_node_set_parent (priv->current_node, old_current);

  g_signal_emit (parser, parser_signals[ARRAY_END], 0, array);

  if (node != NULL && *node == NULL)
    *node = priv->current_node;

  priv->current_node = old_current;

  return G_TOKEN_NONE;
}
Ejemplo n.º 18
0
/**
 * melo_jsonrpc_register_methods:
 * @group: prefix of the method
 * @methods: an array of #MeloJSONRPCMethod
 * @count: the number of methods in @methods
 *
 * Register multiple JSON-RPC method named with the same prefix @group. All
 * final methods will be as "@group.NAME".
 *
 * Returns: 0 if all methods have been registered or the number of methods which
 * has not been registered.
 */
guint
melo_jsonrpc_register_methods (const gchar *group, MeloJSONRPCMethod *methods,
                               guint count)
{
  JsonParser *parser;
  JsonObject *result;
  JsonArray *params;
  JsonNode *node;
  guint errors = 0, i;
  gboolean ret;

  /* Create a parser */
  parser = json_parser_new ();

  /* Register all methods */
  for (i = 0; i < count; i++) {
    /* Generate params schema */
    if (json_parser_load_from_data (parser, methods[i].params, -1, NULL)) {
      /* Convert string to node */
      node = json_parser_get_root (parser);

      /* Node params type must be an array */
      if (json_node_get_node_type (node) != JSON_NODE_ARRAY)
        continue;

      /* Get array */
      params = json_node_dup_array (node);
    } else
      params = NULL;

    /* Generate result schema */
    if (json_parser_load_from_data (parser, methods[i].result, -1, NULL)) {
      /* Convert string to node */
      node = json_parser_get_root (parser);

      /* Node result type must be an object */
      if (json_node_get_node_type (node) != JSON_NODE_OBJECT)
        continue;

      /* Get array */
      result = json_node_dup_object (node);
    } else
      result = NULL;

    /* Register method */
    ret = melo_jsonrpc_register_method (group, methods[i].method, params,
                                        result, methods[i].callback,
                                        methods[i].user_data);

    /* Failed to register method */
    if (!ret) {
      if (params)
        json_array_unref (params);
      if (result)
        json_object_unref (result);
      errors++;
    }
  }

  /* Release parser */
  g_object_unref (parser);

  return errors;
}
Ejemplo n.º 19
0
/* Parse JSON-RPC request */
static JsonNode *
melo_jsonrpc_parse_node (JsonNode *node)
{
  MeloJSONRPCInternalMethod *m;
  MeloJSONRPCCallback callback = NULL;
  gpointer user_data = NULL;
  JsonArray *s_params = NULL;
  JsonNode *result = NULL;
  JsonNode *error = NULL;
  JsonNode *params;
  JsonObject *obj;
  const char *version;
  const char *method;
  const char *id = NULL;
  gint64 nid = -1;

  /* Not an object */
  if (JSON_NODE_TYPE (node) != JSON_NODE_OBJECT)
    goto invalid;

  /* Get object from nide */
  obj = json_node_get_object (node);
  if (!obj)
    goto internal;

  /* Check if jsonrpc is present */
  if (!json_object_has_member (obj, "jsonrpc"))
    goto invalid;

  /* Check JSON-RPC version */
  version = json_object_get_string_member (obj, "jsonrpc");
  if (!version || strcmp (version, "2.0"))
    goto invalid;

  /* Check if method is present */
  if (!json_object_has_member (obj, "method"))
    goto invalid;

  /* Get method */
  method = json_object_get_string_member (obj, "method");
  if (!method)
    goto invalid;

  /* Get params */
  params = json_object_get_member (obj, "params");
  if (params) {
    JsonNodeType type;

    /* Check params type: only object or array allowed */
    type = json_node_get_node_type (params);
    if (type != JSON_NODE_ARRAY && type != JSON_NODE_OBJECT)
      goto invalid;
  }

  /* Get registered method */
  G_LOCK (melo_jsonrpc_mutex);
  if (melo_jsonrpc_methods) {
    m = g_hash_table_lookup (melo_jsonrpc_methods, method);
    if (m) {
      callback = m->callback;
      user_data = m->user_data;
      if (m->params)
        s_params = json_array_ref (m->params);
    }
  }
  G_UNLOCK (melo_jsonrpc_mutex);

  /* Check if id is present */
  if (!json_object_has_member (obj, "id")) {
    /* This is a notification: try to call callback */
    if (callback) {
      callback (method, s_params, params, &result, &error, user_data);
      if (s_params)
        json_array_unref (s_params);
      if (error)
        json_node_free (error);
      if (result)
        json_node_free (result);
    }
    return NULL;
  }

  /* Get id */
  nid = json_object_get_int_member (obj, "id");
  id = json_object_get_string_member (obj, "id");

  /* No callback provided */
  if (!callback)
    goto not_found;

  /* Call user callback */
  callback (method, s_params, params, &result, &error, user_data);
  if (s_params)
    json_array_unref (s_params);

  /* No error or result */
  if (!error && !result)
    goto not_found;

  /* Build response */
  return melo_jsonrpc_build_response_node (result, error, id, nid);

invalid:
  return melo_jsonrpc_build_error (NULL, -1,
                                        MELO_JSONRPC_ERROR_INVALID_REQUEST,
                                        "Invalid request");
not_found:
  return melo_jsonrpc_build_error (id, nid,
                                        MELO_JSONRPC_ERROR_METHOD_NOT_FOUND,
                                        "Method not found");
internal:
  return melo_jsonrpc_build_error (id, -1,
                                        MELO_JSONRPC_ERROR_INTERNAL_ERROR,
                                        "Internal error");
}
Ejemplo n.º 20
0
static guint
json_parse_array (JsonParser   *parser,
                  JsonScanner  *scanner,
                  JsonNode    **node)
{
  JsonParserPrivate *priv = parser->priv;
  JsonNode *old_current;
  JsonArray *array;
  guint token;
  gint idx;

  old_current = priv->current_node;
  priv->current_node = json_node_init_array (json_node_alloc (), NULL);

  array = json_array_new ();

  token = json_scanner_get_next_token (scanner);
  g_assert (token == G_TOKEN_LEFT_BRACE);

  g_signal_emit (parser, parser_signals[ARRAY_START], 0);

  idx = 0;
  while (token != G_TOKEN_RIGHT_BRACE)
    {
      guint next_token = json_scanner_peek_next_token (scanner);
      JsonNode *element = NULL;

      /* parse the element */
      switch (next_token)
        {
        case G_TOKEN_LEFT_BRACE:
          JSON_NOTE (PARSER, "Nested array at index %d", idx);
          token = json_parse_array (parser, scanner, &element);
          break;

        case G_TOKEN_LEFT_CURLY:
          JSON_NOTE (PARSER, "Nested object at index %d", idx);
          token = json_parse_object (parser, scanner, &element);
          break;

        case G_TOKEN_RIGHT_BRACE:
          goto array_done;

        default:
          token = json_scanner_get_next_token (scanner);
          token = json_parse_value (parser, scanner, token, &element);
          break;
        }

      if (token != G_TOKEN_NONE || element == NULL)
        {
          /* the json_parse_* functions will have set the error code */
          json_array_unref (array);
          json_node_free (priv->current_node);
          priv->current_node = old_current;

          return token;
        }

      next_token = json_scanner_peek_next_token (scanner);

      if (next_token == G_TOKEN_COMMA)
        {
          token = json_scanner_get_next_token (scanner);
          next_token = json_scanner_peek_next_token (scanner);

          /* look for trailing commas */
          if (next_token == G_TOKEN_RIGHT_BRACE)
            {
              priv->error_code = JSON_PARSER_ERROR_TRAILING_COMMA;

              json_array_unref (array);
              json_node_free (priv->current_node);
              json_node_free (element);
              priv->current_node = old_current;

              return G_TOKEN_RIGHT_BRACE;
            }
        }

      JSON_NOTE (PARSER, "Array element %d completed", idx + 1);
      json_node_set_parent (element, priv->current_node);
      json_array_add_element (array, element);

      g_signal_emit (parser, parser_signals[ARRAY_ELEMENT], 0,
                     array,
                     idx);

      token = next_token;
    }

array_done:
  json_scanner_get_next_token (scanner);

  json_node_take_array (priv->current_node, array);
  json_node_set_parent (priv->current_node, old_current);

  g_signal_emit (parser, parser_signals[ARRAY_END], 0, array);

  if (node != NULL && *node == NULL)
    *node = priv->current_node;

  priv->current_node = old_current;

  return G_TOKEN_NONE;
}
Ejemplo n.º 21
0
} END_TEST

/* FIXME: more tests required for:
 *
 * - array containing an array (of various types).
 * - array containing an object (containing various types).
 */
START_TEST(test_cc_oci_json_arr_to_string) {
	gchar *str;
	JsonArray *array;
	gboolean ret;

	ck_assert (! cc_oci_json_arr_to_string (NULL, false));
	ck_assert (! cc_oci_json_arr_to_string (NULL, true));

	array = json_array_new ();

	/* empty array, non-pretty */
	str = cc_oci_json_arr_to_string (array, false);
	ck_assert (str);
	ck_assert (! g_strcmp0 (str, "[]"));
	g_free (str);

	/* empty array, pretty */
	str = cc_oci_json_arr_to_string (array, true);
	ck_assert (str);

	ret = g_regex_match_simple (
			/* pair of braces containing optional
			 * whitespace.
			 */
			"[\\s*]",
			str, 0, 0);
	ck_assert (ret);

	g_free (str);

	json_array_add_null_element (array);
	json_array_add_null_element (array);
	json_array_add_boolean_element (array, false);
	json_array_add_boolean_element (array, true);
	json_array_add_int_element (array, 123);
	json_array_add_double_element (array, 3.1412);
	json_array_add_string_element (array, "foo bar");

	str = cc_oci_json_arr_to_string (array, false);
	ck_assert (str);

	ret = g_regex_match_simple (
			"[\\s*"                  /* opening bracket */
			"\\s*null\\s*,"          /* null */
			"\\s*null\\s*,"          /* null */
			"\\s*false\\s*,"         /* false */
			"\\s*true\\s*,"          /* true */
			"\\s*123\\s*,"           /* int */
			"\\s*3\\.1412\\s*,"      /* double */
			"\\s*\"foo\\ bar\"\\s*," /* string */
			"\\s*]",                 /* closing bracket */
			str, 0, 0);
	ck_assert (ret);
	g_free (str);

	/* clean up */
	json_array_unref (array);

} END_TEST