1 /* font-manager-json-proxy.c
2 *
3 * Copyright (C) 2009 - 2021 Jerry Casiano
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program.
17 *
18 * If not, see <http://www.gnu.org/licenses/gpl-3.0.txt>.
19 */
20
21 #include "font-manager-json-proxy.h"
22
23 /**
24 * SECTION: font-manager-json-proxy
25 * @short_description: Wrapper class for JsonObjects
26 * @title: JSON Proxy
27 * @include: font-manager-json-proxy.h
28 *
29 * Simple wrapper around a #JsonObject which maps object members to gobject properties.
30 */
31
32 typedef struct
33 {
34 JsonObject *source_object;
35 }
36 FontManagerJsonProxyPrivate;
37
G_DEFINE_TYPE_WITH_PRIVATE(FontManagerJsonProxy,font_manager_json_proxy,G_TYPE_OBJECT)38 G_DEFINE_TYPE_WITH_PRIVATE(FontManagerJsonProxy, font_manager_json_proxy, G_TYPE_OBJECT)
39
40 static void
41 font_manager_json_proxy_dispose (GObject *gobject)
42 {
43 g_return_if_fail(gobject != NULL);
44 FontManagerJsonProxy *self = FONT_MANAGER_JSON_PROXY(gobject);
45 FontManagerJsonProxyPrivate *priv = font_manager_json_proxy_get_instance_private(self);
46 g_clear_pointer(&priv->source_object, json_object_unref);
47 G_OBJECT_CLASS(font_manager_json_proxy_parent_class)->dispose(gobject);
48 return;
49 }
50
51 static void
font_manager_json_proxy_set_property(GObject * gobject,guint property_id,const GValue * value,GParamSpec * pspec)52 font_manager_json_proxy_set_property (GObject *gobject,
53 guint property_id,
54 const GValue *value,
55 GParamSpec *pspec)
56 {
57 g_return_if_fail(gobject != NULL);
58 FontManagerJsonProxy *self = FONT_MANAGER_JSON_PROXY(gobject);
59 FontManagerJsonProxyPrivate *priv = font_manager_json_proxy_get_instance_private(self);
60
61 GType val_type = G_PARAM_SPEC_VALUE_TYPE(pspec);
62
63 if (val_type == JSON_TYPE_OBJECT) {
64 JsonObject *json_obj = g_value_get_boxed(value);
65 if (priv->source_object == json_obj)
66 return;
67 if (priv->source_object != NULL)
68 json_object_unref(priv->source_object);
69 priv->source_object = json_obj ? json_object_ref(json_obj) : NULL;
70 return;
71 }
72
73 if (priv->source_object == NULL)
74 return;
75
76 if (val_type == G_TYPE_STRING) {
77 json_object_set_string_member(priv->source_object, pspec->name, g_value_get_string(value));
78 } else if (val_type == G_TYPE_INT) {
79 json_object_set_int_member(priv->source_object, pspec->name, g_value_get_int(value));
80 } else if (val_type == G_TYPE_DOUBLE) {
81 json_object_set_double_member(priv->source_object, pspec->name, g_value_get_double(value));
82 } else if (val_type == G_TYPE_BOOLEAN) {
83 json_object_set_boolean_member(priv->source_object, pspec->name, g_value_get_boolean(value));
84 } else if (val_type == JSON_TYPE_ARRAY) {
85 json_object_set_array_member(priv->source_object, pspec->name, g_value_get_boxed(value));
86 } else {
87 G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, property_id, pspec);
88 }
89
90 return;
91 }
92
93 static void
font_manager_json_proxy_get_property(GObject * gobject,guint property_id,GValue * value,GParamSpec * pspec)94 font_manager_json_proxy_get_property (GObject *gobject,
95 guint property_id,
96 GValue *value,
97 GParamSpec *pspec)
98 {
99 g_return_if_fail(gobject != NULL);
100 FontManagerJsonProxy *self = FONT_MANAGER_JSON_PROXY(gobject);
101 FontManagerJsonProxyPrivate *priv = font_manager_json_proxy_get_instance_private(self);
102
103 if (priv->source_object == NULL)
104 return;
105
106 GType val_type = G_PARAM_SPEC_VALUE_TYPE(pspec);
107
108 if (!json_object_get_member(priv->source_object, pspec->name) && val_type != JSON_TYPE_OBJECT)
109 return;
110
111 if (val_type == G_TYPE_STRING) {
112 g_value_set_string(value, json_object_get_string_member(priv->source_object, pspec->name));
113 } else if (val_type == G_TYPE_INT) {
114 g_value_set_int(value, json_object_get_int_member(priv->source_object, pspec->name));
115 } else if (val_type == G_TYPE_DOUBLE) {
116 g_value_set_double(value, json_object_get_double_member(priv->source_object, pspec->name));
117 } else if (val_type == G_TYPE_BOOLEAN) {
118 g_value_set_boolean(value, json_object_get_boolean_member(priv->source_object, pspec->name));
119 } else if (val_type == JSON_TYPE_ARRAY) {
120 g_value_set_boxed(value, json_object_get_array_member(priv->source_object, pspec->name));
121 } else if (val_type == JSON_TYPE_OBJECT) {
122 g_value_set_boxed(value, priv->source_object);
123 } else {
124 G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, property_id, pspec);
125 }
126
127 return;
128 }
129
130 gboolean
font_manager_json_proxy_default_is_valid(FontManagerJsonProxy * self)131 font_manager_json_proxy_default_is_valid (FontManagerJsonProxy *self)
132 {
133 g_return_val_if_fail(self != NULL, FALSE);
134 FontManagerJsonProxyPrivate *priv = font_manager_json_proxy_get_instance_private(self);
135 return (priv->source_object != NULL);
136 }
137
138
139 static void
font_manager_json_proxy_class_init(FontManagerJsonProxyClass * klass)140 font_manager_json_proxy_class_init (FontManagerJsonProxyClass *klass)
141 {
142 GObjectClass *object_class = G_OBJECT_CLASS(klass);
143 object_class->dispose = font_manager_json_proxy_dispose;
144 object_class->get_property = font_manager_json_proxy_get_property;
145 object_class->set_property = font_manager_json_proxy_set_property;
146 klass->is_valid = font_manager_json_proxy_default_is_valid;
147 return;
148 }
149
150 static void
font_manager_json_proxy_init(FontManagerJsonProxy * self)151 font_manager_json_proxy_init (FontManagerJsonProxy *self)
152 {
153 g_return_if_fail(self != NULL);
154 }
155
156 /**
157 * font_manager_json_proxy_generate_properties:
158 * @pspec: (out caller-allocates) :empty array of #GParamSpec to store results
159 * @properties: array of #FontManagerJsonProxyProperties
160 * @num_properties: number of entries in properties
161 *
162 * Automatically generate class properties from an array of #FontManagerJsonProxyProperties.
163 *
164 * A property with type G_TYPE_BOXED is assumed to be a #JsonArray.
165 * A property with type JSON_TYPE_OBJECT is assumed to be the @source-object.
166 */
167 void
font_manager_json_proxy_generate_properties(GParamSpec * pspec[],const FontManagerJsonProxyProperties * properties,gint num_properties)168 font_manager_json_proxy_generate_properties (GParamSpec *pspec[],
169 const FontManagerJsonProxyProperties *properties,
170 gint num_properties)
171 {
172 GParamFlags OBJECT_PARAM_FLAGS = (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
173
174 for (gint i = 0; i < num_properties; i++) {
175 const gchar *prop_name = properties[i].name;
176 switch (properties[i].type) {
177 case G_TYPE_INT:
178 pspec[i] = g_param_spec_int(prop_name,
179 NULL,
180 properties[i].desc,
181 G_MININT, G_MAXINT, 0,
182 OBJECT_PARAM_FLAGS);
183 break;
184 case G_TYPE_DOUBLE:
185 pspec[i] = g_param_spec_double(prop_name,
186 NULL,
187 properties[i].desc,
188 -G_MAXDOUBLE, G_MAXDOUBLE, 0.0,
189 OBJECT_PARAM_FLAGS);
190 break;
191 case G_TYPE_BOOLEAN:
192 pspec[i] = g_param_spec_boolean(prop_name,
193 NULL,
194 properties[i].desc,
195 FALSE,
196 OBJECT_PARAM_FLAGS);
197 break;
198 case G_TYPE_STRING:
199 pspec[i] = g_param_spec_string(prop_name,
200 NULL,
201 properties[i].desc,
202 NULL,
203 OBJECT_PARAM_FLAGS);
204 break;
205 case G_TYPE_BOXED:
206 pspec[i] = g_param_spec_boxed(prop_name,
207 NULL,
208 properties[i].desc,
209 JSON_TYPE_ARRAY,
210 OBJECT_PARAM_FLAGS);
211 break;
212 case G_TYPE_RESERVED_USER_FIRST:
213 pspec[i] = g_param_spec_boxed(prop_name,
214 NULL,
215 properties[i].desc,
216 JSON_TYPE_OBJECT,
217 OBJECT_PARAM_FLAGS);
218 break;
219 case G_TYPE_RESERVED_GLIB_FIRST:
220 pspec[i] = NULL;
221 break;
222 default:
223 break;
224 }
225 }
226 return;
227 }
228
229 /**
230 * font_manager_json_proxy_is_valid:
231 * @self: (nullable): #FontManagerJsonProxy
232 *
233 * The default method returns %TRUE if source-object is not #NULL.
234 *
235 * Returns: %TRUE if proxy is valid
236 */
237 gboolean
font_manager_json_proxy_is_valid(FontManagerJsonProxy * self)238 font_manager_json_proxy_is_valid (FontManagerJsonProxy *self)
239 {
240 if (self == NULL)
241 return FALSE;
242 FontManagerJsonProxyClass *klass = FONT_MANAGER_JSON_PROXY_GET_CLASS(self);
243 g_return_val_if_fail(klass->is_valid != NULL, FALSE);
244 return klass->is_valid(self);
245 }
246
247 /**
248 * font_manager_json_proxy_new:
249 *
250 * Returns: (transfer full): A newly created #FontManagerJsonProxy.
251 * Free the returned object using #g_object_unref().
252 **/
253 FontManagerJsonProxy *
font_manager_json_proxy_new(void)254 font_manager_json_proxy_new (void)
255 {
256 return g_object_new(FONT_MANAGER_TYPE_JSON_PROXY, NULL);
257 }
258