1 /* Copyright 2007-2012 Fredrik Wikstrom. All rights reserved.
3 ** Redistribution and use in source and binary forms, with or without
4 ** modification, are permitted provided that the following conditions
7 ** 1. Redistributions of source code must retain the above copyright
8 ** notice, this list of conditions and the following disclaimer.
10 ** 2. Redistributions in binary form must reproduce the above copyright
11 ** notice, this list of conditions and the following disclaimer in the
12 ** documentation and/or other materials provided with the distribution.
14 ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
15 ** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 ** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 ** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
18 ** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19 ** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20 ** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21 ** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22 ** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23 ** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
24 ** POSSIBILITY OF SUCH DAMAGE.
33 # include <libraries/expat.h>
34 # include <proto/expat.h>
37 #include <proto/exec.h>
38 #include <proto/dos.h>
41 #define PREFS_BUFFER_SIZE 512
46 BOOL key_tag
, value_tag
;
51 struct Library
*expatbase
;
57 static void start_element_handler (void *user_data
, const char *name
, const char **attrs
);
58 static void end_element_handler (void *user_data
, const char *name
);
59 static void character_data_handler (void *user_data
, const char *s
, int len
);
61 BOOL
ReadPrefs (PrefsObject
*dict
, CONST_STRPTR filename
) {
64 struct Library
*ExpatBase
;
65 ExpatBase
= OpenLibrary("expat.library", 4);
70 if (dict
&& dict
->type
== PREFS_DICTIONARY
) {
72 ClearPrefsDictionary(dict
);
73 file
= Open(filename
, MODE_OLDFILE
);
76 parser
= XML_ParserCreate(NULL
);
80 buffer
= AllocVec(PREFS_BUFFER_SIZE
, MEMF_ANY
);
81 data
= AllocVec(sizeof(parser_data
), MEMF_ANY
);
87 data
->key_tag
= FALSE
;
88 data
->value_tag
= FALSE
;
89 data
->has_key
= FALSE
;
91 data
->expatbase
= ExpatBase
;
93 data
->parser
= parser
;
95 XML_SetUserData(parser
, data
);
96 XML_SetElementHandler(parser
, start_element_handler
, end_element_handler
);
97 XML_SetCharacterDataHandler(parser
, character_data_handler
);
99 len
= Read(file
, buffer
, PREFS_BUFFER_SIZE
);
104 if (!XML_Parse(parser
, buffer
, len
, eof
)) {
118 XML_ParserFree(parser
);
124 CloseLibrary(ExpatBase
);
129 static void stop_parser (parser_data
*data
) {
131 struct Library
*ExpatBase
= data
->expatbase
;
134 XML_StopParser(data
->parser
, XML_TRUE
);
137 static void start_element_handler (void *user_data
, const char *name
, const char **attrs
) {
138 parser_data
*data
= user_data
;
142 switch (data
->state
) {
144 if (!strcmp(name
, "pobjects")) {
152 if (!strcmp(name
, "dict")) {
160 if (data
->key_tag
|| data
->value_tag
) {
164 if (!data
->has_key
&& !strcmp(name
, "key")) {
165 data
->key_tag
= TRUE
;
167 } else if (data
->has_key
&&
168 (!strcmp(name
, "dict") ||
169 !strcmp(name
, "bool") ||
170 !strcmp(name
, "integer") ||
171 !strcmp(name
, "string")))
173 if (!strcmp(name
, "dict")) {
175 obj
= AllocPrefsDictionary();
176 if (DictSetObjectForKey(data
->dict
, obj
, data
->key
)) {
178 data
->has_key
= FALSE
;
184 data
->value_tag
= TRUE
;
198 static void end_element_handler (void *user_data
, const char *name
) {
199 parser_data
*data
= user_data
;
203 switch (data
->state
) {
205 if (!data
->has_key
&& !strcmp(name
, "dict")) {
206 data
->dict
= data
->dict
->parent
;
210 } else if (data
->key_tag
&& !strcmp(name
, "key")) {
211 data
->has_key
= (data
->key
[0] != 0);
212 data
->key_tag
= FALSE
;
213 } else if (data
->has_key
&& data
->value_tag
&&
214 (!strcmp(name
, "bool") ||
215 !strcmp(name
, "integer") ||
216 !strcmp(name
, "string")))
219 if (!strcmp(name
, "bool")) {
220 obj
= AllocPrefsBoolean(!strcmp(data
->value
, "TRUE"));
221 } else if (!strcmp(name
, "integer")) {
222 obj
= AllocPrefsInteger(atol(data
->value
));
223 } else if (!strcmp(name
, "string")) {
224 obj
= AllocPrefsString(data
->value
);
228 if (DictSetObjectForKey(data
->dict
, obj
, data
->key
)) {
229 data
->has_key
= FALSE
;
230 data
->value_tag
= FALSE
;
241 if (!strcmp(name
, "pobjects")) {
254 static void append_text (char *dest
, int dest_len
, const char *src
, int src_len
) {
255 int offs
= strlen(dest
);
256 int space
= dest_len
- offs
;
258 if (space
> src_len
) {
264 memcpy(&dest
[offs
], src
, len
);
265 dest
[offs
+ len
] = 0;
269 static void character_data_handler (void *user_data
, const char *s
, int len
) {
270 parser_data
*data
= user_data
;
275 append_text(data
->key
, sizeof(data
->key
), s
, len
);
276 } else if (data
->value_tag
) {
277 append_text(data
->value
, sizeof(data
->value
), s
, len
);