root/trunk/src/manager/xml.c

Revision 3589, 3.2 kB (checked in by martin, 10 months ago)

merged the modularization branch (credentials) back to trunk

  • Property svn:keywords set to Id
Line 
1 /*
2  * Copyright (C) 2007 Martin Willi
3  * Hochschule fuer Technik Rapperswil
4  *
5  * This program is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License as published by the
7  * Free Software Foundation; either version 2 of the License, or (at your
8  * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
9  *
10  * This program is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
13  * for more details.
14  *
15  * $Id$
16  */
17
18 #include "xml.h"
19
20 #include <libxml/parser.h>
21 #include <libxml/tree.h>
22
23
24 typedef struct private_xml_t private_xml_t;
25
26 /**
27  * private data of xml
28  */
29 struct private_xml_t {
30
31     /**
32      * public functions
33      */
34     xml_t public;
35    
36     /**
37      * root node of this xml (part)
38      */
39     xmlNode *node;
40    
41     /**
42      * document, only for root xml_t
43      */
44     xmlDoc *doc;
45    
46     /**
47      * Root xml_t*
48      */
49     private_xml_t *root;
50    
51     /**
52      * number of enumerator instances
53      */
54     int enums;
55 };
56
57 /**
58  * child element enumerator
59  */
60 typedef struct {
61     /** enumerator interface */
62     enumerator_t e;
63     /** current child context (returned to enumerate() caller) */
64     private_xml_t child;
65     /** currently processing node */
66     xmlNode *node;
67 } child_enum_t;
68
69 /**
70  * Implementation of xml_t.children().enumerate().
71  */
72 static bool child_enumerate(child_enum_t *e, private_xml_t **child,
73                             char **name, char **value)
74 {
75     while (e->node && e->node->type != XML_ELEMENT_NODE)
76     {
77         e->node = e->node->next;
78     }
79     if (e->node)
80     {
81         xmlNode *text;
82        
83         text = e->node->children;
84         *value = NULL;
85        
86         while (text && text->type != XML_TEXT_NODE)
87         {
88             text = text->next;
89         }
90         if (text)
91         {
92             *value = text->content;
93         }
94         *name = (char*)e->node->name;
95         *child = &e->child;
96         e->child.node = e->node->children;
97         e->node = e->node->next;
98         return TRUE;
99     }
100     return FALSE;
101 }
102
103 /**
104  * Implementation of xml_t.get_attribute.
105  */
106 static char* get_attribute(private_xml_t *this, char *name)
107 {
108     return NULL;
109 }
110
111 /**
112  * destroy enumerator, and complete tree if this was the last enumerator
113  */
114 static void child_destroy(child_enum_t *this)
115 {
116     if (--this->child.root->enums == 0)
117     {
118         xmlFreeDoc(this->child.root->doc);
119         free(this->child.root);
120     }
121     free(this);
122 }
123
124 /**
125  * Implementation of xml_t.children.
126  */
127 static enumerator_t* children(private_xml_t *this)
128 {
129     child_enum_t *ce = malloc_thing(child_enum_t);
130     ce->e.enumerate = (void*)child_enumerate;
131     ce->e.destroy = (void*)child_destroy;
132     ce->node = this->node;
133     ce->child.public.children = (void*)children;
134     ce->child.public.get_attribute = (void*)get_attribute;
135     ce->child.node = NULL;
136     ce->child.doc = this->doc;
137     ce->child.root = this->root;
138     this->root->enums++;
139     return &ce->e;
140 }
141
142 /*
143  * see header file
144  */
145 xml_t *xml_create(char *xml)
146 {
147     private_xml_t *this = malloc_thing(private_xml_t);
148    
149     this->public.get_attribute = (char*(*)(xml_t*,char*))get_attribute;
150     this->public.children = (enumerator_t*(*)(xml_t*))children;
151    
152     this->doc = xmlReadMemory(xml, strlen(xml), NULL, NULL, 0);
153     if (this->doc == NULL)
154     {
155         free(this);
156         return NULL;
157     }
158     this->node = xmlDocGetRootElement(this->doc);
159     this->root = this;
160     this->enums = 0;
161    
162     return &this->public;
163 }
164
Note: See TracBrowser for help on using the browser.