示例#1
0
/**
 * json_node_copy:
 * @node: a #JsonNode
 *
 * Copies @node. If the node contains complex data types then the reference
 * count of the objects is increased.
 *
 * Return value: (transfer full): the copied #JsonNode
 */
JsonNode *
json_node_copy (JsonNode *node)
{
  JsonNode *copy;

  g_return_val_if_fail (node != NULL, NULL);

  copy = g_slice_new0 (JsonNode);
  copy->type = node->type;

  switch (copy->type)
    {
    case JSON_NODE_OBJECT:
      copy->data.object = json_node_dup_object (node);
      break;

    case JSON_NODE_ARRAY:
      copy->data.array = json_node_dup_array (node);
      break;

    case JSON_NODE_VALUE:
      if (node->data.value)
        copy->data.value = json_value_ref (node->data.value);
      break;

    case JSON_NODE_NULL:
      break;

    default:
      g_assert_not_reached ();
    }

  return copy;
}
示例#2
0
/**
 * json_node_copy:
 * @node: a #JsonNode
 *
 * Copies @node. If the node contains complex data types, their reference
 * counts are increased, regardless of whether the node is mutable or
 * immutable.
 *
 * The copy will be immutable if, and only if, @node is immutable. However,
 * there should be no need to copy an immutable node.
 *
 * Return value: (transfer full): the copied #JsonNode
 */
JsonNode *
json_node_copy (JsonNode *node)
{
  JsonNode *copy;

  g_return_val_if_fail (JSON_NODE_IS_VALID (node), NULL);

  copy = json_node_alloc ();
  copy->type = node->type;
  copy->immutable = node->immutable;

  if (node->immutable)
    g_debug ("Copying immutable JsonNode %p", node);

  switch (copy->type)
    {
    case JSON_NODE_OBJECT:
      copy->data.object = json_node_dup_object (node);
      break;

    case JSON_NODE_ARRAY:
      copy->data.array = json_node_dup_array (node);
      break;

    case JSON_NODE_VALUE:
      if (node->data.value)
        copy->data.value = json_value_ref (node->data.value);
      break;

    case JSON_NODE_NULL:
      break;

    default:
      g_assert_not_reached ();
    }

  return copy;
}
示例#3
0
/* Params utils */
static gboolean
melo_jsonrpc_add_node (JsonNode *node, JsonObject *schema,
                       JsonObject *obj, JsonArray *array)
{
  GType vtype = G_TYPE_INVALID;
  const gchar *s_name;
  const gchar *s_type;
  JsonNodeType type;

  /* Get name and type from schema */
  s_name = json_object_get_string_member (schema, "name");
  s_type = json_object_get_string_member (schema, "type");
  if (!s_name || !s_type)
    return FALSE;

  /* Get type */
  type = json_node_get_node_type (node);
  if (type == JSON_NODE_VALUE)
    vtype = json_node_get_value_type (node);

  /* Check type:
   * We check only first letter of the type string.
   */
  switch (s_type[0]) {
    case 'b':
      /* Boolean: check type */
      if (vtype != G_TYPE_BOOLEAN)
        return FALSE;

      /* Add to object / array */
      if (obj || array) {
        gboolean v;
        v = json_node_get_boolean (node);
        if (obj)
          json_object_set_boolean_member (obj, s_name, v);
        else
          json_array_add_boolean_element (array, v);
        break;
      }
      break;
    case 'i':
      /* Integer: check type */
      if (vtype != G_TYPE_INT64)
        return FALSE;

      /* Add to object / array */
      if (obj || array) {
        gint64 v;
        v = json_node_get_int (node);
        if (obj)
          json_object_set_int_member (obj, s_name, v);
        else
          json_array_add_int_element (array, v);
      }
      break;
    case 'd':
      /* Double: check type */
      if (vtype != G_TYPE_DOUBLE)
        return FALSE;

      /* Add to object / array */
      if (obj || array) {
        gdouble v;
        v = json_node_get_double (node);
        if (obj)
          json_object_set_double_member (obj, s_name, v);
        else
          json_array_add_double_element (array, v);
      }
      break;
    case 's':
      /* String: check type */
      if (vtype != G_TYPE_STRING)
        return FALSE;

      /* Add to object / array */
      if (obj || array) {
        const gchar *v;
        v = json_node_get_string (node);
        if (obj)
          json_object_set_string_member (obj, s_name, v);
        else
          json_array_add_string_element (array, v);
      }
      break;
    case 'o':
      /* Object: check type */
      if (type != JSON_NODE_OBJECT)
        return FALSE;

      /* Add to object / array */
      if (obj || array) {
        JsonObject *v;
        v = json_node_dup_object (node);
        if (obj)
          json_object_set_object_member (obj, s_name, v);
        else
          json_array_add_object_element (array, v);
      }
      break;
    case 'a':
      /* Array: check type */
      if (type != JSON_NODE_ARRAY)
        return FALSE;

      /* Add to object / array */
      if (obj || array) {
        JsonArray *v;
        v = json_node_dup_array (node);
        if (obj)
          json_object_set_array_member (obj, s_name, v);
        else
          json_array_add_array_element (array, v);
      }
      break;
    default:
      return FALSE;
  }
  return TRUE;
}
示例#4
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;
}