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.
30 # include <libraries/expat_au.h>
31 # include <proto/expat_au.h>
34 # include <libraries/expat.h>
35 # include <proto/expat.h>
38 #include <proto/exec.h>
39 #include <proto/dos.h>
42 #define PREFS_BUFFER_SIZE 512
47 BOOL key_tag
, value_tag
;
51 struct Library
*expatbase
;
56 static void start_element_handler (void *user_data
, const char *name
, const char **attrs
);
57 static void end_element_handler (void *user_data
, const char *name
);
58 static void character_data_handler (void *user_data
, const char *s
, int len
);
60 BOOL
ReadPrefs (PrefsObject
*dict
, CONST_STRPTR filename
) {
61 struct Library
*ExpatBase
;
64 ExpatBase
= OpenLibrary("expat_au.library", 0);
66 ExpatBase
= OpenLibrary("expat.library", 4);
71 if (dict
&& dict
->type
== PREFS_DICTIONARY
) {
73 ClearPrefsDictionary(dict
);
74 file
= Open(filename
, MODE_OLDFILE
);
77 parser
= XML_ParserCreate(NULL
);
81 buffer
= AllocVec(PREFS_BUFFER_SIZE
, MEMF_ANY
);
82 data
= AllocVec(sizeof(parser_data
), MEMF_ANY
);
88 data
->key_tag
= FALSE
;
89 data
->value_tag
= FALSE
;
90 data
->has_key
= FALSE
;
91 data
->expatbase
= ExpatBase
;
92 data
->parser
= parser
;
94 XML_SetUserData(parser
, data
);
95 XML_SetElementHandler(parser
, start_element_handler
, end_element_handler
);
96 XML_SetCharacterDataHandler(parser
, character_data_handler
);
98 len
= Read(file
, buffer
, PREFS_BUFFER_SIZE
);
103 if (!XML_Parse(parser
, buffer
, len
, eof
)) {
117 XML_ParserFree(parser
);
122 CloseLibrary(ExpatBase
);
126 static void stop_parser (parser_data
*data
) {
127 struct Library
*ExpatBase
= data
->expatbase
;
129 XML_StopParser(data
->parser
, XML_TRUE
);
132 static void start_element_handler (void *user_data
, const char *name
, const char **attrs
) {
133 parser_data
*data
= user_data
;
137 switch (data
->state
) {
139 if (!strcmp(name
, "pobjects")) {
147 if (!strcmp(name
, "dict")) {
155 if (data
->key_tag
|| data
->value_tag
) {
159 if (!data
->has_key
&& !strcmp(name
, "key")) {
160 data
->key_tag
= TRUE
;
162 } else if (data
->has_key
&&
163 (!strcmp(name
, "dict") ||
164 !strcmp(name
, "bool") ||
165 !strcmp(name
, "integer") ||
166 !strcmp(name
, "string")))
168 if (!strcmp(name
, "dict")) {
170 obj
= AllocPrefsDictionary();
171 if (DictSetObjectForKey(data
->dict
, obj
, data
->key
)) {
173 data
->has_key
= FALSE
;
179 data
->value_tag
= TRUE
;
193 static void end_element_handler (void *user_data
, const char *name
) {
194 parser_data
*data
= user_data
;
198 switch (data
->state
) {
200 if (!data
->has_key
&& !strcmp(name
, "dict")) {
201 data
->dict
= data
->dict
->parent
;
205 } else if (data
->key_tag
&& !strcmp(name
, "key")) {
206 data
->has_key
= (data
->key
[0] != 0);
207 data
->key_tag
= FALSE
;
208 } else if (data
->has_key
&& data
->value_tag
&&
209 (!strcmp(name
, "bool") ||
210 !strcmp(name
, "integer") ||
211 !strcmp(name
, "string")))
214 if (!strcmp(name
, "bool")) {
215 obj
= AllocPrefsBoolean(!strcmp(data
->value
, "TRUE"));
216 } else if (!strcmp(name
, "integer")) {
217 obj
= AllocPrefsInteger(atol(data
->value
));
218 } else if (!strcmp(name
, "string")) {
219 obj
= AllocPrefsString(data
->value
);
223 if (DictSetObjectForKey(data
->dict
, obj
, data
->key
)) {
224 data
->has_key
= FALSE
;
225 data
->value_tag
= FALSE
;
236 if (!strcmp(name
, "pobjects")) {
249 static void append_text (char *dest
, int dest_len
, const char *src
, int src_len
) {
250 int offs
= strlen(dest
);
251 int space
= dest_len
- offs
;
253 if (space
> src_len
) {
259 memcpy(&dest
[offs
], src
, len
);
260 dest
[offs
+ len
] = 0;
264 static void character_data_handler (void *user_data
, const char *s
, int len
) {
265 parser_data
*data
= user_data
;
270 append_text(data
->key
, sizeof(data
->key
), s
, len
);
271 } else if (data
->value_tag
) {
272 append_text(data
->value
, sizeof(data
->value
), s
, len
);