1 /* Aravis - Digital camera library
2  *
3  * Copyright © 2009-2017 Emmanuel Pacaud
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library 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 GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General
16  * Public License along with this library; if not, write to the
17  * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18  * Boston, MA 02110-1301, USA.
19  *
20  * Author: Emmanuel Pacaud <emmanuel@gnome.org>
21  */
22 
23 /**
24  * SECTION: arvgcintegernode
25  * @short_description: Class for Integer nodes
26  */
27 
28 #include <arvgcintegernode.h>
29 #include <arvgcinteger.h>
30 #include <arvgcvalueindexednode.h>
31 #include <arvgc.h>
32 #include <arvmisc.h>
33 #include <string.h>
34 #include <stdlib.h>
35 
36 static GObjectClass *parent_class = NULL;
37 
38 /* ArvDomNode implementation */
39 
40 static const char *
arv_gc_integer_node_get_node_name(ArvDomNode * node)41 arv_gc_integer_node_get_node_name (ArvDomNode *node)
42 {
43 	return "Integer";
44 }
45 
46 static void
arv_gc_integer_node_post_new_child(ArvDomNode * self,ArvDomNode * child)47 arv_gc_integer_node_post_new_child (ArvDomNode *self, ArvDomNode *child)
48 {
49 	ArvGcIntegerNode *node = ARV_GC_INTEGER_NODE (self);
50 
51 	if (ARV_IS_GC_PROPERTY_NODE (child)) {
52 		ArvGcPropertyNode *property_node = ARV_GC_PROPERTY_NODE (child);
53 
54 		switch (arv_gc_property_node_get_node_type (property_node)) {
55 			case ARV_GC_PROPERTY_NODE_TYPE_VALUE:
56 			case ARV_GC_PROPERTY_NODE_TYPE_P_VALUE:
57 				node->value = property_node;
58 				break;
59 			case ARV_GC_PROPERTY_NODE_TYPE_MINIMUM:
60 			case ARV_GC_PROPERTY_NODE_TYPE_P_MINIMUM:
61 				node->minimum = property_node;
62 				break;
63 			case ARV_GC_PROPERTY_NODE_TYPE_MAXIMUM:
64 			case ARV_GC_PROPERTY_NODE_TYPE_P_MAXIMUM:
65 				node->maximum = property_node;
66 				break;
67 			case ARV_GC_PROPERTY_NODE_TYPE_INCREMENT:
68 			case ARV_GC_PROPERTY_NODE_TYPE_P_INCREMENT:
69 				node->increment = property_node;
70 				break;
71 			case ARV_GC_PROPERTY_NODE_TYPE_UNIT:
72 				node->unit = property_node;
73 				break;
74 			case ARV_GC_PROPERTY_NODE_TYPE_P_INDEX:
75 				node->index = property_node;
76 				break;
77 			case ARV_GC_PROPERTY_NODE_TYPE_VALUE_INDEXED:
78 			case ARV_GC_PROPERTY_NODE_TYPE_P_VALUE_INDEXED:
79 				node->value_indexed_nodes = g_slist_prepend (node->value_indexed_nodes, property_node);
80 				break;
81 			case ARV_GC_PROPERTY_NODE_TYPE_VALUE_DEFAULT:
82 			case ARV_GC_PROPERTY_NODE_TYPE_P_VALUE_DEFAULT:
83 				node->value_default = property_node;
84 				break;
85 			default:
86 				ARV_DOM_NODE_CLASS (parent_class)->post_new_child (self, child);
87 				break;
88 		}
89 	}
90 }
91 
92 static void
arv_gc_integer_node_pre_remove_child(ArvDomNode * self,ArvDomNode * child)93 arv_gc_integer_node_pre_remove_child (ArvDomNode *self, ArvDomNode *child)
94 {
95 	g_assert_not_reached ();
96 }
97 
98 /* ArvGcFeatureNode implementation */
99 
100 static ArvGcPropertyNode *
_get_value_node(ArvGcIntegerNode * gc_integer_node,GError ** error)101 _get_value_node (ArvGcIntegerNode *gc_integer_node, GError **error)
102 {
103 	GError *local_error = NULL;
104 
105 	if (gc_integer_node->value != NULL)
106 		return gc_integer_node->value;
107 
108 	if (gc_integer_node->index != NULL) {
109 		gint64 index;
110 		GSList *iter;
111 
112 		index = arv_gc_property_node_get_int64 (ARV_GC_PROPERTY_NODE (gc_integer_node->index), &local_error);
113 		if (local_error != NULL) {
114 			g_propagate_error (error, local_error);
115 			return NULL;
116 		}
117 
118 		for (iter = gc_integer_node->value_indexed_nodes; iter != NULL; iter = iter->next) {
119 			if (arv_gc_value_indexed_node_get_index (iter->data) == index)
120 				return iter->data;
121 		}
122 
123 		if (gc_integer_node->value_default != NULL)
124 			return gc_integer_node->value_default;
125 	}
126 
127 	return NULL;
128 }
129 
130 static GType
arv_gc_integer_node_get_value_type(ArvGcFeatureNode * node)131 arv_gc_integer_node_get_value_type (ArvGcFeatureNode *node)
132 {
133 	return G_TYPE_INT64;
134 }
135 
136 static void
arv_gc_integer_node_set_value_from_string(ArvGcFeatureNode * node,const char * string,GError ** error)137 arv_gc_integer_node_set_value_from_string (ArvGcFeatureNode *node, const char *string, GError **error)
138 {
139 	arv_gc_integer_set_value (ARV_GC_INTEGER (node), g_ascii_strtoll (string, NULL, 0), error);
140 }
141 
142 static const char *
arv_gc_integer_node_get_value_as_string(ArvGcFeatureNode * node,GError ** error)143 arv_gc_integer_node_get_value_as_string (ArvGcFeatureNode *node, GError **error)
144 {
145 	ArvGcIntegerNode *integer_node = ARV_GC_INTEGER_NODE (node);
146 	ArvGcPropertyNode *value_node;
147 	GError *local_error = NULL;
148 	const char *string;
149 
150 	value_node = _get_value_node (integer_node, error);
151 	if (value_node == NULL)
152 		return NULL;
153 
154 	string = arv_gc_property_node_get_string (value_node, &local_error);
155 	if (local_error != NULL) {
156 		g_propagate_error (error, local_error);
157 		return NULL;
158 	}
159 
160 	return string;
161 }
162 
163 /* ArvGcIntegerNode implementation */
164 
165 ArvGcNode *
arv_gc_integer_node_new(void)166 arv_gc_integer_node_new (void)
167 {
168 	ArvGcNode *node;
169 
170 	node = g_object_new (ARV_TYPE_GC_INTEGER_NODE, NULL);
171 
172 	return node;
173 }
174 
175 static void
arv_gc_integer_node_init(ArvGcIntegerNode * gc_integer_node)176 arv_gc_integer_node_init (ArvGcIntegerNode *gc_integer_node)
177 {
178 }
179 
180 static void
arv_gc_integer_node_finalize(GObject * object)181 arv_gc_integer_node_finalize (GObject *object)
182 {
183 	ArvGcIntegerNode *gc_integer_node = ARV_GC_INTEGER_NODE (object);
184 
185 	parent_class->finalize (object);
186 
187 	g_slist_free (gc_integer_node->value_indexed_nodes);
188 }
189 
190 static void
arv_gc_integer_node_class_init(ArvGcIntegerNodeClass * this_class)191 arv_gc_integer_node_class_init (ArvGcIntegerNodeClass *this_class)
192 {
193 	GObjectClass *object_class = G_OBJECT_CLASS (this_class);
194 	ArvDomNodeClass *dom_node_class = ARV_DOM_NODE_CLASS (this_class);
195 	ArvGcFeatureNodeClass *gc_feature_node_class = ARV_GC_FEATURE_NODE_CLASS (this_class);
196 
197 	parent_class = g_type_class_peek_parent (this_class);
198 
199 	object_class->finalize = arv_gc_integer_node_finalize;
200 	dom_node_class->get_node_name = arv_gc_integer_node_get_node_name;
201 	dom_node_class->post_new_child = arv_gc_integer_node_post_new_child;
202 	dom_node_class->pre_remove_child = arv_gc_integer_node_pre_remove_child;
203 	gc_feature_node_class->get_value_type = arv_gc_integer_node_get_value_type;
204 	gc_feature_node_class->set_value_from_string = arv_gc_integer_node_set_value_from_string;
205 	gc_feature_node_class->get_value_as_string = arv_gc_integer_node_get_value_as_string;
206 }
207 
208 /* ArvGcInteger interface implementation */
209 
210 static gint64
arv_gc_integer_node_get_integer_value(ArvGcInteger * gc_integer,GError ** error)211 arv_gc_integer_node_get_integer_value (ArvGcInteger *gc_integer, GError **error)
212 {
213 	ArvGcIntegerNode *gc_integer_node = ARV_GC_INTEGER_NODE (gc_integer);
214 	ArvGcPropertyNode *value_node;
215 	GError *local_error = NULL;
216 	gint64 value;
217 
218 	value_node = _get_value_node (gc_integer_node, error);
219 	if (value_node == NULL)
220 		return 0;
221 
222 	value = arv_gc_property_node_get_int64 (ARV_GC_PROPERTY_NODE (value_node), &local_error);
223 	if (local_error != NULL) {
224 		g_propagate_error (error, local_error);
225 		return 0;
226 	}
227 
228 	return value;
229 }
230 
231 static void
arv_gc_integer_node_set_integer_value(ArvGcInteger * gc_integer,gint64 value,GError ** error)232 arv_gc_integer_node_set_integer_value (ArvGcInteger *gc_integer, gint64 value, GError **error)
233 {
234 	ArvGcIntegerNode *gc_integer_node = ARV_GC_INTEGER_NODE (gc_integer);
235 	ArvGcPropertyNode *value_node;
236 	GError *local_error = NULL;
237 
238 	value_node = _get_value_node (gc_integer_node, error);
239 	if (value_node == NULL)
240 		return;
241 
242 	arv_gc_property_node_set_int64 (ARV_GC_PROPERTY_NODE (value_node), value, &local_error);
243 	if (local_error != NULL)
244 		g_propagate_error (error, local_error);
245 }
246 
247 static gint64
arv_gc_integer_node_get_min(ArvGcInteger * gc_integer,GError ** error)248 arv_gc_integer_node_get_min (ArvGcInteger *gc_integer, GError **error)
249 {
250 	ArvGcIntegerNode *gc_integer_node = ARV_GC_INTEGER_NODE (gc_integer);
251 	GError *local_error = NULL;
252 	gint64 value;
253 
254 	if (gc_integer_node->minimum == NULL)
255 		return G_MININT64;
256 
257 	value = arv_gc_property_node_get_int64 (ARV_GC_PROPERTY_NODE (gc_integer_node->minimum), &local_error);
258 
259 	if (local_error != NULL) {
260 		g_propagate_error (error, local_error);
261 		return G_MININT64;
262 	}
263 
264 	return value;
265 }
266 
267 static gint64
arv_gc_integer_node_get_max(ArvGcInteger * gc_integer,GError ** error)268 arv_gc_integer_node_get_max (ArvGcInteger *gc_integer, GError **error)
269 {
270 	ArvGcIntegerNode *gc_integer_node = ARV_GC_INTEGER_NODE (gc_integer);
271 	GError *local_error = NULL;
272 	gint64 value;
273 
274 	if (gc_integer_node->maximum == NULL)
275 		return G_MAXINT64;
276 
277 	value = arv_gc_property_node_get_int64 (ARV_GC_PROPERTY_NODE (gc_integer_node->maximum), &local_error);
278 
279 	if (local_error != NULL) {
280 		g_propagate_error (error, local_error);
281 		return G_MAXINT64;
282 	}
283 
284 	return value;
285 }
286 
287 static gint64
arv_gc_integer_node_get_inc(ArvGcInteger * gc_integer,GError ** error)288 arv_gc_integer_node_get_inc (ArvGcInteger *gc_integer, GError **error)
289 {
290 	ArvGcIntegerNode *gc_integer_node = ARV_GC_INTEGER_NODE (gc_integer);
291 	GError *local_error = NULL;
292 	gint64 value;
293 
294 	if (gc_integer_node->increment == NULL)
295 		return 1;
296 
297 	value = arv_gc_property_node_get_int64 (ARV_GC_PROPERTY_NODE (gc_integer_node->increment), &local_error);
298 
299 	if (local_error != NULL) {
300 		g_propagate_error (error, local_error);
301 		return 1;
302 	}
303 
304 	return value;
305 }
306 
307 static const char *
arv_gc_integer_node_get_unit(ArvGcInteger * gc_integer,GError ** error)308 arv_gc_integer_node_get_unit (ArvGcInteger *gc_integer, GError **error)
309 {
310 	ArvGcIntegerNode *gc_integer_node = ARV_GC_INTEGER_NODE (gc_integer);
311 	GError *local_error = NULL;
312 	const char *string;
313 
314 	if (gc_integer_node->unit == NULL)
315 		return NULL;
316 
317 	string = arv_gc_property_node_get_string (ARV_GC_PROPERTY_NODE (gc_integer_node->unit), &local_error);
318 
319 	if (local_error != NULL) {
320 		g_propagate_error (error, local_error);
321 		return NULL;
322 	}
323 
324 	return string;
325 }
326 
327 static void
arv_gc_integer_node_impose_min(ArvGcInteger * gc_integer,gint64 minimum,GError ** error)328 arv_gc_integer_node_impose_min (ArvGcInteger *gc_integer, gint64 minimum, GError **error)
329 {
330 	ArvGcIntegerNode *gc_integer_node = ARV_GC_INTEGER_NODE (gc_integer);
331 	GError *local_error = NULL;
332 
333 	if (gc_integer_node->minimum == NULL)
334 		return;
335 
336 	arv_gc_property_node_set_int64 (ARV_GC_PROPERTY_NODE (gc_integer_node->minimum), minimum, &local_error);
337 
338 	if (local_error != NULL)
339 		g_propagate_error (error, local_error);
340 }
341 
342 static void
arv_gc_integer_node_impose_max(ArvGcInteger * gc_integer,gint64 maximum,GError ** error)343 arv_gc_integer_node_impose_max (ArvGcInteger *gc_integer, gint64 maximum, GError **error)
344 {
345 	ArvGcIntegerNode *gc_integer_node = ARV_GC_INTEGER_NODE (gc_integer);
346 	GError *local_error = NULL;
347 
348 	if (gc_integer_node->maximum == NULL)
349 		return;
350 
351 	arv_gc_property_node_set_int64 (ARV_GC_PROPERTY_NODE (gc_integer_node->maximum), maximum, &local_error);
352 
353 	if (local_error != NULL)
354 		g_propagate_error (error, local_error);
355 }
356 
357 static void
arv_gc_integer_node_integer_interface_init(ArvGcIntegerInterface * interface)358 arv_gc_integer_node_integer_interface_init (ArvGcIntegerInterface *interface)
359 {
360 	interface->get_value = arv_gc_integer_node_get_integer_value;
361 	interface->set_value = arv_gc_integer_node_set_integer_value;
362 	interface->get_min = arv_gc_integer_node_get_min;
363 	interface->get_max = arv_gc_integer_node_get_max;
364 	interface->get_inc = arv_gc_integer_node_get_inc;
365 	interface->get_unit = arv_gc_integer_node_get_unit;
366 	interface->impose_min = arv_gc_integer_node_impose_min;
367 	interface->impose_max = arv_gc_integer_node_impose_max;
368 }
369 
370 G_DEFINE_TYPE_WITH_CODE (ArvGcIntegerNode, arv_gc_integer_node, ARV_TYPE_GC_FEATURE_NODE,
371 			 G_IMPLEMENT_INTERFACE (ARV_TYPE_GC_INTEGER, arv_gc_integer_node_integer_interface_init))
372