Example #1
0
/**
 * json_serializable_find_property:
 * @serializable: a #JsonSerializable
 * @name: the name of the property
 *
 * Calls the #JsonSerializableIface.find_property() implementation on
 * the @serializable instance. *
 *
 * Return value: (nullable) (transfer none): the #GParamSpec for the property
 *   or %NULL if no property was found
 *
 * Since: 0.14
 */
GParamSpec *
json_serializable_find_property (JsonSerializable *serializable,
                                 const char       *name)
{
  g_return_val_if_fail (JSON_IS_SERIALIZABLE (serializable), NULL);
  g_return_val_if_fail (name != NULL, NULL);

  return JSON_SERIALIZABLE_GET_IFACE (serializable)->find_property (serializable, name);
}
static JsonObject *
json_gobject_dump (GObject *gobject)
{
  JsonSerializableIface *iface = NULL;
  JsonSerializable *serializable = NULL;
  gboolean serialize_property = FALSE;
  JsonObject *object;
  GParamSpec **pspecs;
  guint n_pspecs, i;

  if (JSON_IS_SERIALIZABLE (gobject))
    {
      serializable = JSON_SERIALIZABLE (gobject);
      iface = JSON_SERIALIZABLE_GET_IFACE (gobject);
      serialize_property = (iface->serialize_property != NULL);
    }

  object = json_object_new ();

  pspecs = g_object_class_list_properties (G_OBJECT_GET_CLASS (gobject), &n_pspecs);
  for (i = 0; i < n_pspecs; i++)
    {
      GParamSpec *pspec = pspecs[i];
      GValue value = { 0, };
      JsonNode *node = NULL;

      /* read only what we can */
      if (!(pspec->flags & G_PARAM_READABLE))
        continue;

      g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (pspec));
      g_object_get_property (gobject, pspec->name, &value);

      /* if there is a serialization vfunc, then it is completely responsible
       * for serializing the property, possibly by calling the implementation
       * of the default JsonSerializable interface through chaining up
       */
      if (serialize_property)
        {
          node = iface->serialize_property (serializable, pspec->name,
                                            &value,
                                            pspec);
        }
      else
        node = json_serialize_pspec (&value, pspec);

      if (node)
        json_object_set_member (object, pspec->name, node);

      g_value_unset (&value);
    }

  g_free (pspecs);

  return object;
}
Example #3
0
/**
 * json_serializable_get_property:
 * @serializable: a #JsonSerializable
 * @pspec: a #GParamSpec
 * @value: (out): return location for the property value
 *
 * Calls the #JsonSerializableIface.get_property() implementation
 * on the @serializable instance.
 *
 * Since: 0.14
 */
void
json_serializable_get_property (JsonSerializable *serializable,
                                GParamSpec       *pspec,
                                GValue           *value)
{
  g_return_if_fail (JSON_IS_SERIALIZABLE (serializable));
  g_return_if_fail (G_IS_PARAM_SPEC (pspec));
  g_return_if_fail (value != NULL);

  JSON_SERIALIZABLE_GET_IFACE (serializable)->get_property (serializable,
                                                            pspec,
                                                            value);
}
Example #4
0
/**
 * json_serializable_serialize_property:
 * @serializable: a #JsonSerializable object
 * @property_name: the name of the property
 * @value: the value of the property
 * @pspec: a #GParamSpec
 *
 * Asks a #JsonSerializable implementation to serialize a #GObject
 * property into a #JsonNode object.
 *
 * Return value: a #JsonNode containing the serialized property
 */
JsonNode *
json_serializable_serialize_property (JsonSerializable *serializable,
                                      const gchar      *property_name,
                                      const GValue     *value,
                                      GParamSpec       *pspec)
{
  JsonSerializableIface *iface;

  g_return_val_if_fail (JSON_IS_SERIALIZABLE (serializable), NULL);
  g_return_val_if_fail (property_name != NULL, NULL);
  g_return_val_if_fail (value != NULL, NULL);
  g_return_val_if_fail (pspec != NULL, NULL);

  iface = JSON_SERIALIZABLE_GET_IFACE (serializable);

  return iface->serialize_property (serializable, property_name, value, pspec);
}
Example #5
0
/**
 * json_serializable_deserialize_property:
 * @serializable: a #JsonSerializable
 * @property_name: the name of the property
 * @value: (out): a pointer to an uninitialized #GValue
 * @pspec: a #GParamSpec
 * @property_node: a #JsonNode containing the serialized property
 *
 * Asks a #JsonSerializable implementation to deserialize the
 * property contained inside @property_node into @value.
 *
 * Return value: %TRUE if the property was successfully deserialized.
 */
gboolean
json_serializable_deserialize_property (JsonSerializable *serializable,
                                        const gchar      *property_name,
                                        GValue           *value,
                                        GParamSpec       *pspec,
                                        JsonNode         *property_node)
{
  JsonSerializableIface *iface;

  g_return_val_if_fail (JSON_IS_SERIALIZABLE (serializable), FALSE);
  g_return_val_if_fail (property_name != NULL, FALSE);
  g_return_val_if_fail (value != NULL, FALSE);
  g_return_val_if_fail (pspec != NULL, FALSE);
  g_return_val_if_fail (property_node != NULL, FALSE);

  iface = JSON_SERIALIZABLE_GET_IFACE (serializable);

  return iface->deserialize_property (serializable,
                                      property_name,
                                      value,
                                      pspec,
                                      property_node);
}
Example #6
0
static GObject *
json_gobject_new (GType       gtype,
                  JsonObject *object)
{
  JsonSerializableIface *iface = NULL;
  JsonSerializable *serializable = NULL;
  gboolean find_property;
  gboolean deserialize_property;
  gboolean set_property;
  GList *members, *members_left, *l;
  guint n_members;
  GObjectClass *klass;
  GObject *retval;
  GArray *construct_params;
  gint i;

  klass = g_type_class_ref (gtype);

  n_members = json_object_get_size (object);
  members = json_object_get_members (object);
  members_left = NULL;

  /* first pass: construct-only properties; here we cannot use Serializable
   * because we don't have an instance yet; we use the default implementation
   * of json_deserialize_pspec() to deserialize known types
   *
   * FIXME - find a way to allow deserialization for these properties
   */
  construct_params = g_array_sized_new (FALSE, FALSE, sizeof (GParameter), n_members);

  for (l = members; l != NULL; l = l->next)
    {
      const gchar *member_name = l->data;
      GParamSpec *pspec;
      GParameter param = { NULL, };
      JsonNode *val;
      gboolean res = FALSE;

      pspec = g_object_class_find_property (klass, member_name);
      if (!pspec)
        goto next_member;

      /* we only apply construct-only properties here */
      if ((pspec->flags & G_PARAM_CONSTRUCT_ONLY) == 0)
        goto next_member;

      if (!(pspec->flags & G_PARAM_WRITABLE))
        goto next_member;

      g_value_init (&param.value, G_PARAM_SPEC_VALUE_TYPE (pspec));

      val = json_object_get_member (object, member_name);
      res = json_deserialize_pspec (&param.value, pspec, val);
      if (!res)
	{
	  g_warning ("Failed to deserialize \"%s\" property of type \"%s\" for an object of type \"%s\"",
		     pspec->name, G_VALUE_TYPE_NAME (&param.value), g_type_name (gtype));

	  g_value_unset (&param.value);
	}
      else
        {
          param.name = g_strdup (pspec->name);

          g_array_append_val (construct_params, param);

          continue;
        }

    next_member:
      members_left = g_list_prepend (members_left, l->data);
    }

  retval = g_object_newv (gtype,
                          construct_params->len,
                          (GParameter *) construct_params->data);

  /* free the contents of the GArray */
  for (i = 0; i < construct_params->len; i++)
    {
      GParameter *param = &g_array_index (construct_params, GParameter, i);

      g_free ((gchar *) param->name);
      g_value_unset (&param->value);
    }

  g_array_free (construct_params, TRUE);
  g_list_free (members);

  /* we use g_list_prepend() above, but we want to maintain
   * the ordering of json_object_get_members() here
   */
  members = g_list_reverse (members_left);

  /* do the Serializable type check once */
  if (g_type_is_a (gtype, JSON_TYPE_SERIALIZABLE))
    {
      serializable = JSON_SERIALIZABLE (retval);
      iface = JSON_SERIALIZABLE_GET_IFACE (serializable);
      find_property = (iface->find_property != NULL);
      deserialize_property = (iface->deserialize_property != NULL);
      set_property = (iface->set_property != NULL);
    }
  else
    {
      find_property = FALSE;
      deserialize_property = FALSE;
      set_property = FALSE;
    }

  g_object_freeze_notify (retval);

  for (l = members; l != NULL; l = l->next)
    {
      const gchar *member_name = l->data;
      GParamSpec *pspec;
      JsonNode *val;
      GValue value = { 0, };
      gboolean res = FALSE;

      if (find_property)
        pspec = json_serializable_find_property (serializable, member_name);
      else
        pspec = g_object_class_find_property (klass, member_name);

      if (pspec == NULL)
        continue;

      /* we should have dealt with these above */
      if (pspec->flags & G_PARAM_CONSTRUCT_ONLY)
        continue;

      if (!(pspec->flags & G_PARAM_WRITABLE))
        continue;

      g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (pspec));

      val = json_object_get_member (object, member_name);

      if (deserialize_property)
        {
          JSON_NOTE (GOBJECT, "Using JsonSerializable for property '%s'", pspec->name);
          res = json_serializable_deserialize_property (serializable,
                                                        pspec->name,
                                                        &value,
                                                        pspec,
                                                        val);
        }

      if (!res)
        {
          JSON_NOTE (GOBJECT, "Using json_deserialize_pspec for property '%s'", pspec->name);
          res = json_deserialize_pspec (&value, pspec, val);
        }

      if (res)
        {
          JSON_NOTE (GOBJECT, "Calling set_property('%s', '%s')",
                     pspec->name,
                     g_type_name (G_VALUE_TYPE (&value)));

          if (set_property)
            json_serializable_set_property (serializable, pspec, &value);
          else
            g_object_set_property (retval, pspec->name, &value);
        }
      else
	g_warning ("Failed to deserialize \"%s\" property of type \"%s\" for an object of type \"%s\"",
		   pspec->name, g_type_name (G_VALUE_TYPE (&value)), g_type_name (gtype));

      g_value_unset (&value);
    }

  g_list_free (members);

  g_object_thaw_notify (retval);

  g_type_class_unref (klass);

  return retval;
}