1 /* Aravis
2 *
3 * Copyright © 2007-2010 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:
21 * Emmanuel Pacaud <emmanuel@gnome.org>
22 */
23
24 /**
25 * SECTION:arvdomnode
26 * @short_description: Base class for DOM nodes
27 */
28
29 #include <arvdomnode.h>
30 #include <arvdomnodelist.h>
31 #include <arvdomdocument.h>
32 #include <arvdebug.h>
33 #include <glib/gprintf.h>
34 #include <stdio.h>
35
36 /* ArvDomNodeChildList */
37
38
39 #define ARV_TYPE_DOM_NODE_CHILD_LIST (arv_dom_node_child_list_get_type ())
40 #define ARV_DOM_NODE_CHILD_LIST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), ARV_TYPE_DOM_NODE_CHILD_LIST, ArvDomNodeChildList))
41 #define ARV_DOM_NODE_CHILD_LIST_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), ARV_TYPE_DOM_NODE_CHILD_LIST, ArvDomNodeChildListClass))
42 #define ARV_IS_DOM_NODE_CHILD_LIST(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), ARV_TYPE_DOM_NODE_CHILD_LIST))
43 #define ARV_IS_DOM_NODE_CHILD_LIST_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), ARV_TYPE_DOM_NODE_CHILD_LIST))
44 #define ARV_DOM_NODE_CHILD_LIST_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), ARV_TYPE_DOM_NODE_CHILD_LIST, ArvDomNodeChildListClass))
45
46 typedef struct _ArvDomNodeChildListClass ArvDomNodeChildListClass;
47
48 typedef struct {
49 ArvDomNodeList base;
50
51 ArvDomNode *parent_node;
52 } ArvDomNodeChildList;
53
54 struct _ArvDomNodeChildListClass {
55 ArvDomNodeListClass parent_class;
56 };
57
58 GType arv_dom_node_child_list_get_type (void);
59
60 static GObjectClass *child_list_parent_class = NULL;
61
62 static void
arv_dom_node_child_list_weak_notify_cb(void * user_data,GObject * object)63 arv_dom_node_child_list_weak_notify_cb (void *user_data, GObject *object)
64 {
65 ArvDomNodeChildList *list = user_data;
66
67 list->parent_node = NULL;
68 }
69
70 static ArvDomNode *
arv_dom_node_child_list_get_item(ArvDomNodeList * list,unsigned int index)71 arv_dom_node_child_list_get_item (ArvDomNodeList *list, unsigned int index)
72 {
73 ArvDomNodeChildList *child_list = ARV_DOM_NODE_CHILD_LIST (list);
74 ArvDomNode *iter;
75 unsigned int i = 0;
76
77 if (child_list->parent_node == NULL)
78 return NULL;
79
80 for (iter = child_list->parent_node->first_child; iter != NULL; iter = iter->next_sibling) {
81 if (i == index)
82 return iter;
83 i++;
84 }
85
86 return NULL;
87 }
88
89 static unsigned int
arv_dom_node_child_list_get_length(ArvDomNodeList * list)90 arv_dom_node_child_list_get_length (ArvDomNodeList *list)
91 {
92 ArvDomNodeChildList *child_list = ARV_DOM_NODE_CHILD_LIST (list);
93 ArvDomNode *iter;
94 unsigned int length = 0;
95
96 if (child_list->parent_node == NULL)
97 return 0;
98
99 for (iter = child_list->parent_node->first_child; iter != NULL; iter = iter->next_sibling)
100 length++;
101
102 return length;
103 }
104
105 ArvDomNodeList *
arv_dom_node_child_list_new(ArvDomNode * parent_node)106 arv_dom_node_child_list_new (ArvDomNode *parent_node)
107 {
108 ArvDomNodeChildList *list;
109
110 g_return_val_if_fail (ARV_IS_DOM_NODE (parent_node), NULL);
111
112 list = g_object_new (ARV_TYPE_DOM_NODE_CHILD_LIST, NULL);
113 list->parent_node = parent_node;
114
115 g_object_weak_ref (G_OBJECT (parent_node), arv_dom_node_child_list_weak_notify_cb, list);
116
117 return ARV_DOM_NODE_LIST (list);
118 }
119
120 static void
arv_dom_node_child_list_init(ArvDomNodeChildList * list)121 arv_dom_node_child_list_init (ArvDomNodeChildList *list)
122 {
123 }
124
125 static void
arv_dom_node_child_list_finalize(GObject * object)126 arv_dom_node_child_list_finalize (GObject *object)
127 {
128 ArvDomNodeChildList *list = ARV_DOM_NODE_CHILD_LIST (object);
129
130 if (list->parent_node != NULL) {
131 g_object_weak_unref (G_OBJECT (list->parent_node), arv_dom_node_child_list_weak_notify_cb, list);
132 list->parent_node = NULL;
133 }
134
135 child_list_parent_class->finalize (object);
136 }
137
138 static void
arv_dom_node_child_list_class_init(ArvDomNodeChildListClass * klass)139 arv_dom_node_child_list_class_init (ArvDomNodeChildListClass *klass)
140 {
141 GObjectClass *object_class = G_OBJECT_CLASS (klass);
142 ArvDomNodeListClass *node_list_class = ARV_DOM_NODE_LIST_CLASS (klass);
143
144 child_list_parent_class = g_type_class_peek_parent (klass);
145
146 object_class->finalize = arv_dom_node_child_list_finalize;
147
148 node_list_class->get_item = arv_dom_node_child_list_get_item;
149 node_list_class->get_length = arv_dom_node_child_list_get_length;
150 }
151
152 G_DEFINE_TYPE (ArvDomNodeChildList, arv_dom_node_child_list, ARV_TYPE_DOM_NODE_LIST)
153
154 static GObjectClass *parent_class = NULL;
155
156 /* ArvDomNode implementation */
157
158
159 /**
160 * arv_dom_node_get_node_name:
161 * @self: a #ArvDomNode
162 *
163 * Gets the node name.
164 *
165 * Return value: the node name.
166 */
167
168 const char*
arv_dom_node_get_node_name(ArvDomNode * self)169 arv_dom_node_get_node_name (ArvDomNode* self)
170 {
171 ArvDomNodeClass *node_class = ARV_DOM_NODE_GET_CLASS (self);
172
173 g_return_val_if_fail (node_class != NULL, NULL);
174
175 if (node_class->get_node_name)
176 return node_class->get_node_name (self);
177
178 return NULL;
179 }
180
181 /**
182 * arv_dom_node_get_node_value:
183 * @self: a #ArvDomNode
184 *
185 * Gets the node value.
186 *
187 * Return value: the node value.
188 */
189
190 const char*
arv_dom_node_get_node_value(ArvDomNode * self)191 arv_dom_node_get_node_value (ArvDomNode* self)
192 {
193 ArvDomNodeClass *node_class = ARV_DOM_NODE_GET_CLASS (self);
194
195 g_return_val_if_fail (node_class != NULL, NULL);
196
197 if (node_class->get_node_value)
198 return node_class->get_node_value (self);
199
200 return NULL;
201 }
202
203 void
arv_dom_node_set_node_value(ArvDomNode * self,const char * new_value)204 arv_dom_node_set_node_value (ArvDomNode* self, const char* new_value)
205 {
206 ArvDomNodeClass *node_class = ARV_DOM_NODE_GET_CLASS (self);
207
208 g_return_if_fail (node_class != NULL);
209 g_return_if_fail (new_value != NULL);
210
211 if (node_class->set_node_value)
212 node_class->set_node_value (self, new_value);
213 }
214
arv_dom_node_get_node_type(ArvDomNode * self)215 ArvDomNodeType arv_dom_node_get_node_type (ArvDomNode* self)
216 {
217 ArvDomNodeClass *node_class = ARV_DOM_NODE_GET_CLASS (self);
218
219 g_return_val_if_fail (node_class != NULL, 0);
220
221 if (node_class->get_node_type)
222 return node_class->get_node_type (self);
223
224 return 0;
225 }
226
227 /**
228 * arv_dom_node_get_parent_node:
229 * @self: a #ArvDomNode
230 *
231 * Get the parent node of @self.
232 *
233 * Returns: (transfer none): @self parent.
234 */
235
236 ArvDomNode*
arv_dom_node_get_parent_node(ArvDomNode * self)237 arv_dom_node_get_parent_node (ArvDomNode* self)
238 {
239 g_return_val_if_fail (ARV_IS_DOM_NODE (self), NULL);
240
241 return self->parent_node;
242 }
243
244 /**
245 * arv_dom_node_get_child_nodes:
246 * @self: a #ArvDomNode
247 *
248 * Returns: (transfer none): a #ArvDomNodeList, NULL on error.
249 */
250
251 ArvDomNodeList*
arv_dom_node_get_child_nodes(ArvDomNode * self)252 arv_dom_node_get_child_nodes (ArvDomNode* self)
253 {
254 ArvDomNodeList *list;
255
256 g_return_val_if_fail (ARV_IS_DOM_NODE (self), NULL);
257
258 list = g_object_get_data (G_OBJECT (self), "child-nodes");
259
260 if (list == NULL) {
261 list = arv_dom_node_child_list_new (self);
262 g_object_set_data_full (G_OBJECT (self), "child-nodes", list, g_object_unref);
263 }
264
265 return list;
266 }
267
268 /**
269 * arv_dom_node_get_first_child:
270 * @self: a #ArvDomNode
271 *
272 * Returns: (transfer none): @self first child.
273 */
274
275 ArvDomNode*
arv_dom_node_get_first_child(ArvDomNode * self)276 arv_dom_node_get_first_child (ArvDomNode* self)
277 {
278 g_return_val_if_fail (ARV_IS_DOM_NODE (self), NULL);
279
280 return self->first_child;
281 }
282
283 /**
284 * arv_dom_node_get_last_child:
285 * @self: a #ArvDomNode
286 *
287 * Returns: (transfer none): @self last child.
288 */
289
290 ArvDomNode*
arv_dom_node_get_last_child(ArvDomNode * self)291 arv_dom_node_get_last_child (ArvDomNode* self)
292 {
293 g_return_val_if_fail (ARV_IS_DOM_NODE (self), NULL);
294
295 return self->last_child;
296 }
297
298 /**
299 * arv_dom_node_get_previous_sibling:
300 * @self: a #ArvDomNode
301 *
302 * Returns: (transfer none): @self previous sibling.
303 */
304
305 ArvDomNode*
arv_dom_node_get_previous_sibling(ArvDomNode * self)306 arv_dom_node_get_previous_sibling (ArvDomNode* self)
307 {
308 g_return_val_if_fail (ARV_IS_DOM_NODE (self), NULL);
309
310 return self->previous_sibling;
311 }
312
313 /**
314 * arv_dom_node_get_next_sibling:
315 * @self: a #ArvDomNode
316 *
317 * Returns: (transfer none): @self next sibling.
318 */
319
320 ArvDomNode*
arv_dom_node_get_next_sibling(ArvDomNode * self)321 arv_dom_node_get_next_sibling (ArvDomNode* self)
322 {
323 g_return_val_if_fail (ARV_IS_DOM_NODE (self), NULL);
324
325 return self->next_sibling;
326 }
327
328 /*ArvDomNamedNodeMap**/
329 /*arv_dom_node_get_attributes (ArvDomNode* self)*/
330 /*{*/
331 /* return ARV_DOM_NODE_GET_CLASS (self)->get_attributes (self);*/
332 /*}*/
333
334
335 /**
336 * arv_dom_node_get_owner_document:
337 * @self: a #ArvDomNode
338 *
339 * Returns: (transfer none): @self owner document.
340 */
341
342 ArvDomDocument*
arv_dom_node_get_owner_document(ArvDomNode * self)343 arv_dom_node_get_owner_document (ArvDomNode* self)
344 {
345 ArvDomNode *parent;
346
347 g_return_val_if_fail (ARV_IS_DOM_NODE (self), NULL);
348
349 for (parent = self;
350 parent != NULL &&
351 !ARV_IS_DOM_DOCUMENT (parent);
352 parent = parent->parent_node);
353
354 return ARV_DOM_DOCUMENT (parent);
355 }
356
357 /**
358 * arv_dom_node_insert_before:
359 * @self: a #ArvDomNode
360 * @new_child: (transfer full): node to insert
361 * @ref_child: (transfer none): reference node, i.e., the node before which the new node must be inserted.
362 *
363 * Inserts the node @new_child before the existing child node @ref_child. If
364 * @ref_child is null, insert @new_child at the end of the list of children.
365 * If the @new_child is already in the tree, it is first removed.
366 *
367 * Returns: (transfer none): the inserted node.
368 */
369
370 /* TODO:
371 * If @new_child is a #LsmDocumentFragment object, all of its children are inserted,
372 * in the same order, before @ref_child.
373 * Check if new_child is an ancestor of self.
374 */
375
376 ArvDomNode*
arv_dom_node_insert_before(ArvDomNode * self,ArvDomNode * new_child,ArvDomNode * ref_child)377 arv_dom_node_insert_before (ArvDomNode* self, ArvDomNode* new_child, ArvDomNode* ref_child)
378 {
379 ArvDomNodeClass *node_class;
380
381 if (ref_child == NULL)
382 arv_dom_node_append_child (self, new_child);
383
384 g_return_val_if_fail (ARV_IS_DOM_NODE (new_child), NULL);
385
386 if (new_child->parent_node != NULL)
387 arv_dom_node_remove_child (self, new_child);
388
389 if (!ARV_IS_DOM_NODE (self)) {
390 g_critical ("%s: self is not a ArvDomNode", G_STRFUNC);
391 g_object_unref (new_child);
392 return NULL;
393 }
394
395 if (!ARV_IS_DOM_NODE (ref_child)) {
396 g_critical ("%s: ref_child is not a ArvDomNode", G_STRFUNC);
397 g_object_unref (new_child);
398 return NULL;
399 }
400
401 if (ref_child->parent_node != self) {
402 arv_debug_dom ("[ArvDomNode::insert_before] Ref child '%s' doesn't belong to '%s'",
403 arv_dom_node_get_node_name (ref_child),
404 arv_dom_node_get_node_name (self));
405 g_object_unref (new_child);
406 return NULL;
407 }
408
409 if (!ARV_DOM_NODE_GET_CLASS (self)->can_append_child (self, new_child)) {
410 arv_log_dom ("[ArvDomNode::insert_before] Can't append '%s' to '%s'",
411 arv_dom_node_get_node_name (new_child),
412 arv_dom_node_get_node_name (self));
413 g_object_unref (new_child);
414 return NULL;
415 }
416
417 new_child->parent_node = self;
418 new_child->next_sibling = ref_child;
419 new_child->previous_sibling = ref_child->previous_sibling;
420
421 if (ref_child->previous_sibling == NULL)
422 self->first_child = new_child;
423 else
424 ref_child->previous_sibling->next_sibling = new_child;
425
426 ref_child->previous_sibling = new_child;
427
428 node_class = ARV_DOM_NODE_GET_CLASS (self);
429
430 if (node_class->post_new_child)
431 node_class->post_new_child (self, new_child);
432
433 arv_dom_node_changed (self);
434
435 return new_child;
436 }
437
438 /**
439 * arv_dom_node_replace_child:
440 * @self: a #ArvDomNode
441 * @new_child: (transfer full): a replacement node
442 * @old_child: (transfer none): node to replace
443 *
444 * Replaces the child node @old_child with @new_child in the list of children,
445 * and returns the @old_child node.
446 * If the @new_child is already in the tree, it is first removed.
447 *
448 * Returns: (transfer full): the replaced node.
449 */
450
451 /* TODO:
452 * Check if new_child is an ancestor of self.
453 */
454
455 ArvDomNode*
arv_dom_node_replace_child(ArvDomNode * self,ArvDomNode * new_child,ArvDomNode * old_child)456 arv_dom_node_replace_child (ArvDomNode* self, ArvDomNode* new_child, ArvDomNode* old_child)
457 {
458 ArvDomNode *next_sibling;
459 ArvDomNode *node;
460
461 if (new_child == NULL)
462 return arv_dom_node_remove_child (self, old_child);
463
464 if (!ARV_IS_DOM_NODE (new_child)) {
465 g_critical ("%s: new_child is not a ArvDomNode", G_STRFUNC);
466 if (ARV_IS_DOM_NODE (old_child))
467 g_object_unref (old_child);
468 return NULL;
469 }
470
471 if (new_child->parent_node != NULL)
472 arv_dom_node_remove_child (self, new_child);
473
474 if (old_child == NULL) {
475 arv_debug_dom ("[ArvDomNode::replace_child] old_child == NULL)");
476 g_object_unref (new_child);
477 return NULL;
478 }
479
480 if (!ARV_IS_DOM_NODE (old_child)) {
481 g_critical ("%s: old_child is not a ArvDomNode", G_STRFUNC);
482 g_object_unref (new_child);
483 return NULL;
484 }
485
486 if (!ARV_IS_DOM_NODE (self)) {
487 g_critical ("%s: self is not a ArvDomNode", G_STRFUNC);
488 g_object_unref (new_child);
489 g_object_unref (old_child);
490 return NULL;
491 }
492
493 if (old_child->parent_node != self) {
494 g_object_unref (new_child);
495 g_object_unref (old_child);
496 return NULL;
497 }
498
499 next_sibling = old_child->next_sibling;
500
501 node = arv_dom_node_remove_child (self, old_child);
502 if (node != old_child) {
503 g_object_unref (new_child);
504 g_object_unref (old_child);
505 return NULL;
506 }
507
508 if (next_sibling == NULL)
509 arv_dom_node_append_child (self, new_child);
510 else
511 arv_dom_node_insert_before (self, new_child, next_sibling);
512
513 return old_child;
514 }
515
516 /**
517 * arv_dom_node_remove_child:
518 * @self: a #ArvDomNode
519 * @old_child: (transfer none): node to remove.
520 *
521 * Removes the child node indicated by @old_child from the list of children, and returns it.
522 *
523 * Returns: (transfer full): the removed node.
524 */
525
526 ArvDomNode*
arv_dom_node_remove_child(ArvDomNode * self,ArvDomNode * old_child)527 arv_dom_node_remove_child (ArvDomNode* self, ArvDomNode* old_child)
528 {
529 ArvDomNode *node;
530 ArvDomNodeClass *node_class;
531
532 g_return_val_if_fail (ARV_IS_DOM_NODE (self), NULL);
533
534 if (old_child == NULL)
535 return NULL;
536
537 g_return_val_if_fail (ARV_IS_DOM_NODE (old_child), NULL);
538
539 for (node = self->first_child;
540 node != NULL && node != old_child;
541 node = node->next_sibling);
542
543 if (node == NULL)
544 return NULL;
545
546 node_class = ARV_DOM_NODE_GET_CLASS (self);
547
548 if (node_class->pre_remove_child)
549 node_class->pre_remove_child (self, old_child);
550
551 if (self->first_child == old_child)
552 self->first_child = old_child->next_sibling;
553 if (self->last_child == old_child)
554 self->last_child = old_child->previous_sibling;
555
556 if (old_child->next_sibling != NULL)
557 old_child->next_sibling->previous_sibling = old_child->previous_sibling;
558 if (old_child->previous_sibling != NULL)
559 old_child->previous_sibling->next_sibling = old_child->next_sibling;
560
561 old_child->parent_node = NULL;
562 old_child->next_sibling = NULL;
563 old_child->previous_sibling = NULL;
564
565 arv_dom_node_changed (self);
566
567 return old_child;
568 }
569
570 /**
571 * arv_dom_node_append_child:
572 * @self: a #ArvDomNode
573 * @new_child: (transfer full): node to append
574 *
575 * Adds the node @new_child to the end of the list of children of this node.
576 * If the @new_child is already in the tree, it is first removed.
577 *
578 * Returns: (transfer none): the added node.
579 */
580
581 ArvDomNode *
arv_dom_node_append_child(ArvDomNode * self,ArvDomNode * new_child)582 arv_dom_node_append_child (ArvDomNode* self, ArvDomNode* new_child)
583 {
584 ArvDomNodeClass *node_class;
585
586 if (new_child == NULL)
587 return NULL;
588
589 g_return_val_if_fail (ARV_IS_DOM_NODE (new_child), NULL);
590
591 if (!ARV_IS_DOM_NODE (self)) {
592 g_critical ("%s: self is not a ArvDomNode", G_STRFUNC);
593 g_object_unref (new_child);
594 return NULL;
595 }
596
597 if (new_child->parent_node != NULL)
598 arv_dom_node_remove_child (self, new_child);
599
600 if (!ARV_DOM_NODE_GET_CLASS (self)->can_append_child (self, new_child)) {
601 arv_log_dom ("[ArvDomNode::append_child] Can't append '%s' to '%s'",
602 arv_dom_node_get_node_name (new_child),
603 arv_dom_node_get_node_name (self));
604 g_object_unref (new_child);
605 return NULL;
606 }
607
608 if (self->first_child == NULL)
609 self->first_child = new_child;
610 if (self->last_child != NULL)
611 self->last_child->next_sibling = new_child;
612
613 new_child->parent_node = self;
614 new_child->next_sibling = NULL;
615 new_child->previous_sibling = self->last_child;
616 self->last_child = new_child;
617
618 node_class = ARV_DOM_NODE_GET_CLASS (self);
619
620 if (node_class->post_new_child)
621 node_class->post_new_child (self, new_child);
622
623 arv_dom_node_changed (self);
624
625 return new_child;
626 }
627
628 static gboolean
arv_dom_node_can_append_child_default(ArvDomNode * self,ArvDomNode * new_child)629 arv_dom_node_can_append_child_default (ArvDomNode *self, ArvDomNode* new_child)
630 {
631 return FALSE;
632 }
633
634 void
arv_dom_node_changed(ArvDomNode * self)635 arv_dom_node_changed (ArvDomNode *self)
636 {
637 ArvDomNode *parent_node;
638 ArvDomNode *child_node;
639 ArvDomNodeClass *node_class;
640
641 g_return_if_fail (ARV_IS_DOM_NODE (self));
642
643 node_class = ARV_DOM_NODE_GET_CLASS (self);
644
645 if (node_class->changed)
646 node_class->changed (self);
647
648 child_node = self;
649 for (parent_node = self->parent_node;
650 parent_node != NULL;
651 parent_node = parent_node->parent_node) {
652 node_class = ARV_DOM_NODE_GET_CLASS (parent_node);
653 if (node_class->child_changed == NULL ||
654 !node_class->child_changed (parent_node, child_node))
655 break;
656 child_node = parent_node;
657 }
658 }
659
660 gboolean
arv_dom_node_has_child_nodes(ArvDomNode * self)661 arv_dom_node_has_child_nodes (ArvDomNode* self)
662 {
663 g_return_val_if_fail (ARV_IS_DOM_NODE (self), FALSE);
664
665 return self->first_child != NULL;
666 }
667
668 static void
arv_dom_node_write_to_stream_default(ArvDomNode * self,GOutputStream * stream,GError ** error)669 arv_dom_node_write_to_stream_default (ArvDomNode *self, GOutputStream *stream, GError **error)
670 {
671 ArvDomNode *child;
672
673 for (child = self->first_child; child != NULL; child = child->next_sibling)
674 arv_dom_node_write_to_stream (child, stream, error);
675 }
676
677 void
arv_dom_node_write_to_stream(ArvDomNode * self,GOutputStream * stream,GError ** error)678 arv_dom_node_write_to_stream (ArvDomNode *self, GOutputStream *stream, GError **error)
679 {
680 ArvDomNodeClass *node_class;
681
682 g_return_if_fail (ARV_IS_DOM_NODE (self));
683 g_return_if_fail (G_IS_OUTPUT_STREAM (stream));
684
685 node_class = ARV_DOM_NODE_GET_CLASS (self);
686 if (node_class->write_to_stream != NULL)
687 node_class->write_to_stream (self, stream, error);
688 }
689
690 static void
arv_dom_node_init(ArvDomNode * node)691 arv_dom_node_init (ArvDomNode *node)
692 {
693 }
694
695 static void
arv_dom_node_finalize(GObject * object)696 arv_dom_node_finalize (GObject *object)
697 {
698 ArvDomNode *node = ARV_DOM_NODE (object);
699 ArvDomNode *child, *next_child;
700
701 child = node->first_child;
702 while (child != NULL) {
703 next_child = child->next_sibling;
704 g_object_unref (child);
705 child = next_child;
706 }
707
708 parent_class->finalize (object);
709 }
710
711 /* ArvDomNode class */
712
713 static void
arv_dom_node_class_init(ArvDomNodeClass * node_class)714 arv_dom_node_class_init (ArvDomNodeClass *node_class)
715 {
716 GObjectClass *object_class = G_OBJECT_CLASS (node_class);
717
718 parent_class = g_type_class_peek_parent (node_class);
719
720 object_class->finalize = arv_dom_node_finalize;
721
722 node_class->can_append_child = arv_dom_node_can_append_child_default;
723 node_class->write_to_stream = arv_dom_node_write_to_stream_default;
724 }
725
726 G_DEFINE_ABSTRACT_TYPE (ArvDomNode, arv_dom_node, G_TYPE_OBJECT)
727