diff options
author | Jacek Antonelli | 2008-08-15 23:44:46 -0500 |
---|---|---|
committer | Jacek Antonelli | 2008-08-15 23:44:46 -0500 |
commit | 38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4 (patch) | |
tree | adca584755d22ca041a2dbfc35d4eca01f70b32c /linden/indra/llxml/llxmlparser.cpp | |
parent | README.txt (diff) | |
download | meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.zip meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.gz meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.bz2 meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.xz |
Second Life viewer sources 1.13.2.12
Diffstat (limited to 'linden/indra/llxml/llxmlparser.cpp')
-rw-r--r-- | linden/indra/llxml/llxmlparser.cpp | 417 |
1 files changed, 417 insertions, 0 deletions
diff --git a/linden/indra/llxml/llxmlparser.cpp b/linden/indra/llxml/llxmlparser.cpp new file mode 100644 index 0000000..57e6a30 --- /dev/null +++ b/linden/indra/llxml/llxmlparser.cpp | |||
@@ -0,0 +1,417 @@ | |||
1 | /** | ||
2 | * @file llxmlparser.cpp | ||
3 | * @brief LLXmlParser implementation | ||
4 | * | ||
5 | * Copyright (c) 2002-2007`, Linden Research, Inc. | ||
6 | * | ||
7 | * The source code in this file ("Source Code") is provided by Linden Lab | ||
8 | * to you under the terms of the GNU General Public License, version 2.0 | ||
9 | * ("GPL"), unless you have obtained a separate licensing agreement | ||
10 | * ("Other License"), formally executed by you and Linden Lab. Terms of | ||
11 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | ||
12 | * online at http://secondlife.com/developers/opensource/gplv2 | ||
13 | * | ||
14 | * There are special exceptions to the terms and conditions of the GPL as | ||
15 | * it is applied to this Source Code. View the full text of the exception | ||
16 | * in the file doc/FLOSS-exception.txt in this software distribution, or | ||
17 | * online at http://secondlife.com/developers/opensource/flossexception | ||
18 | * | ||
19 | * By copying, modifying or distributing this software, you acknowledge | ||
20 | * that you have read and understood your obligations described above, | ||
21 | * and agree to abide by those obligations. | ||
22 | * | ||
23 | * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO | ||
24 | * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, | ||
25 | * COMPLETENESS OR PERFORMANCE. | ||
26 | */ | ||
27 | |||
28 | // llxmlparser.cpp | ||
29 | // | ||
30 | // copyright 2002, linden research inc | ||
31 | |||
32 | |||
33 | #include "linden_common.h" | ||
34 | |||
35 | #include "llxmlparser.h" | ||
36 | #include "llerror.h" | ||
37 | |||
38 | |||
39 | LLXmlParser::LLXmlParser() | ||
40 | : | ||
41 | mParser( NULL ), | ||
42 | mDepth( 0 ) | ||
43 | { | ||
44 | strcpy( mAuxErrorString, "no error" ); | ||
45 | |||
46 | // Override the document's declared encoding. | ||
47 | mParser = XML_ParserCreate(NULL); | ||
48 | |||
49 | XML_SetUserData(mParser, this); | ||
50 | XML_SetElementHandler( mParser, startElementHandler, endElementHandler); | ||
51 | XML_SetCharacterDataHandler( mParser, characterDataHandler); | ||
52 | XML_SetProcessingInstructionHandler( mParser, processingInstructionHandler); | ||
53 | XML_SetCommentHandler( mParser, commentHandler); | ||
54 | |||
55 | XML_SetCdataSectionHandler( mParser, startCdataSectionHandler, endCdataSectionHandler); | ||
56 | |||
57 | // This sets the default handler but does not inhibit expansion of internal entities. | ||
58 | // The entity reference will not be passed to the default handler. | ||
59 | XML_SetDefaultHandlerExpand( mParser, defaultDataHandler); | ||
60 | |||
61 | XML_SetUnparsedEntityDeclHandler( mParser, unparsedEntityDeclHandler); | ||
62 | } | ||
63 | |||
64 | LLXmlParser::~LLXmlParser() | ||
65 | { | ||
66 | XML_ParserFree( mParser ); | ||
67 | } | ||
68 | |||
69 | |||
70 | BOOL LLXmlParser::parseFile(const std::string &path) | ||
71 | { | ||
72 | llassert( !mDepth ); | ||
73 | |||
74 | BOOL success = TRUE; | ||
75 | |||
76 | FILE *file = LLFile::fopen(path.c_str(), "rb"); | ||
77 | if( !file ) | ||
78 | { | ||
79 | sprintf( mAuxErrorString, "Couldn't open file %s", path.c_str()); | ||
80 | success = FALSE; | ||
81 | } | ||
82 | else | ||
83 | { | ||
84 | S32 bytes_read = 0; | ||
85 | |||
86 | fseek(file, 0L, SEEK_END); | ||
87 | S32 buffer_size = ftell(file); | ||
88 | fseek(file, 0L, SEEK_SET); | ||
89 | |||
90 | void* buffer = XML_GetBuffer(mParser, buffer_size); | ||
91 | if( !buffer ) | ||
92 | { | ||
93 | sprintf( mAuxErrorString, "Unable to allocate XML buffer while reading file %s", path.c_str() ); | ||
94 | success = FALSE; | ||
95 | goto exit_label; | ||
96 | } | ||
97 | |||
98 | bytes_read = (S32)fread(buffer, 1, buffer_size, file); | ||
99 | if( bytes_read <= 0 ) | ||
100 | { | ||
101 | sprintf( mAuxErrorString, "Error while reading file %s", path.c_str() ); | ||
102 | success = FALSE; | ||
103 | goto exit_label; | ||
104 | } | ||
105 | |||
106 | if( !XML_ParseBuffer(mParser, bytes_read, TRUE ) ) | ||
107 | { | ||
108 | sprintf( mAuxErrorString, "Error while parsing file %s", path.c_str() ); | ||
109 | success = FALSE; | ||
110 | } | ||
111 | |||
112 | exit_label: | ||
113 | fclose( file ); | ||
114 | } | ||
115 | |||
116 | |||
117 | if( success ) | ||
118 | { | ||
119 | llassert( !mDepth ); | ||
120 | } | ||
121 | mDepth = 0; | ||
122 | |||
123 | if( !success ) | ||
124 | { | ||
125 | llwarns << mAuxErrorString << llendl; | ||
126 | } | ||
127 | |||
128 | return success; | ||
129 | } | ||
130 | |||
131 | |||
132 | // Parses some input. Returns 0 if a fatal error is detected. | ||
133 | // The last call must have isFinal true; | ||
134 | // len may be zero for this call (or any other). | ||
135 | S32 LLXmlParser::parse( const char* buf, int len, int isFinal ) | ||
136 | { | ||
137 | return XML_Parse(mParser, buf, len, isFinal); | ||
138 | } | ||
139 | |||
140 | const char* LLXmlParser::getErrorString() | ||
141 | { | ||
142 | const char* error_string = XML_ErrorString(XML_GetErrorCode( mParser )); | ||
143 | if( !error_string ) | ||
144 | { | ||
145 | error_string = mAuxErrorString; | ||
146 | } | ||
147 | return error_string; | ||
148 | } | ||
149 | |||
150 | S32 LLXmlParser::getCurrentLineNumber() | ||
151 | { | ||
152 | return XML_GetCurrentLineNumber( mParser ); | ||
153 | } | ||
154 | |||
155 | S32 LLXmlParser::getCurrentColumnNumber() | ||
156 | { | ||
157 | return XML_GetCurrentColumnNumber(mParser); | ||
158 | } | ||
159 | |||
160 | /////////////////////////////////////////////////////////////////////////////// | ||
161 | // Pseudo-private methods. These are only used by internal callbacks. | ||
162 | |||
163 | // static | ||
164 | void LLXmlParser::startElementHandler( | ||
165 | void *userData, | ||
166 | const XML_Char *name, | ||
167 | const XML_Char **atts) | ||
168 | { | ||
169 | LLXmlParser* self = (LLXmlParser*) userData; | ||
170 | self->startElement( name, atts ); | ||
171 | self->mDepth++; | ||
172 | } | ||
173 | |||
174 | // static | ||
175 | void LLXmlParser::endElementHandler( | ||
176 | void *userData, | ||
177 | const XML_Char *name) | ||
178 | { | ||
179 | LLXmlParser* self = (LLXmlParser*) userData; | ||
180 | self->mDepth--; | ||
181 | self->endElement( name ); | ||
182 | } | ||
183 | |||
184 | // s is not 0 terminated. | ||
185 | // static | ||
186 | void LLXmlParser::characterDataHandler( | ||
187 | void *userData, | ||
188 | const XML_Char *s, | ||
189 | int len) | ||
190 | { | ||
191 | LLXmlParser* self = (LLXmlParser*) userData; | ||
192 | self->characterData( s, len ); | ||
193 | } | ||
194 | |||
195 | // target and data are 0 terminated | ||
196 | // static | ||
197 | void LLXmlParser::processingInstructionHandler( | ||
198 | void *userData, | ||
199 | const XML_Char *target, | ||
200 | const XML_Char *data) | ||
201 | { | ||
202 | LLXmlParser* self = (LLXmlParser*) userData; | ||
203 | self->processingInstruction( target, data ); | ||
204 | } | ||
205 | |||
206 | // data is 0 terminated | ||
207 | // static | ||
208 | void LLXmlParser::commentHandler(void *userData, const XML_Char *data) | ||
209 | { | ||
210 | LLXmlParser* self = (LLXmlParser*) userData; | ||
211 | self->comment( data ); | ||
212 | } | ||
213 | |||
214 | // static | ||
215 | void LLXmlParser::startCdataSectionHandler(void *userData) | ||
216 | { | ||
217 | LLXmlParser* self = (LLXmlParser*) userData; | ||
218 | self->mDepth++; | ||
219 | self->startCdataSection(); | ||
220 | } | ||
221 | |||
222 | // static | ||
223 | void LLXmlParser::endCdataSectionHandler(void *userData) | ||
224 | { | ||
225 | LLXmlParser* self = (LLXmlParser*) userData; | ||
226 | self->endCdataSection(); | ||
227 | self->mDepth++; | ||
228 | } | ||
229 | |||
230 | // This is called for any characters in the XML document for | ||
231 | // which there is no applicable handler. This includes both | ||
232 | // characters that are part of markup which is of a kind that is | ||
233 | // not reported (comments, markup declarations), or characters | ||
234 | // that are part of a construct which could be reported but | ||
235 | // for which no handler has been supplied. The characters are passed | ||
236 | // exactly as they were in the XML document except that | ||
237 | // they will be encoded in UTF-8. Line boundaries are not normalized. | ||
238 | // Note that a byte order mark character is not passed to the default handler. | ||
239 | // There are no guarantees about how characters are divided between calls | ||
240 | // to the default handler: for example, a comment might be split between | ||
241 | // multiple calls. | ||
242 | |||
243 | // static | ||
244 | void LLXmlParser::defaultDataHandler( | ||
245 | void *userData, | ||
246 | const XML_Char *s, | ||
247 | int len) | ||
248 | { | ||
249 | LLXmlParser* self = (LLXmlParser*) userData; | ||
250 | self->defaultData( s, len ); | ||
251 | } | ||
252 | |||
253 | // This is called for a declaration of an unparsed (NDATA) | ||
254 | // entity. The base argument is whatever was set by XML_SetBase. | ||
255 | // The entityName, systemId and notationName arguments will never be null. | ||
256 | // The other arguments may be. | ||
257 | // static | ||
258 | void LLXmlParser::unparsedEntityDeclHandler( | ||
259 | void *userData, | ||
260 | const XML_Char *entityName, | ||
261 | const XML_Char *base, | ||
262 | const XML_Char *systemId, | ||
263 | const XML_Char *publicId, | ||
264 | const XML_Char *notationName) | ||
265 | { | ||
266 | LLXmlParser* self = (LLXmlParser*) userData; | ||
267 | self->unparsedEntityDecl( entityName, base, systemId, publicId, notationName ); | ||
268 | } | ||
269 | |||
270 | |||
271 | |||
272 | |||
273 | //////////////////////////////////////////////////////////////////// | ||
274 | // Test code. | ||
275 | |||
276 | /* | ||
277 | class LLXmlDOMParser : public LLXmlParser | ||
278 | { | ||
279 | public: | ||
280 | |||
281 | LLXmlDOMParser() {} | ||
282 | virtual ~LLXmlDOMParser() {} | ||
283 | |||
284 | void tabs() | ||
285 | { | ||
286 | for ( int i = 0; i < getDepth(); i++) | ||
287 | { | ||
288 | putchar(' '); | ||
289 | } | ||
290 | } | ||
291 | |||
292 | virtual void startElement(const char *name, const char **atts) | ||
293 | { | ||
294 | tabs(); | ||
295 | printf("startElement %s\n", name); | ||
296 | |||
297 | S32 i = 0; | ||
298 | while( atts[i] && atts[i+1] ) | ||
299 | { | ||
300 | tabs(); | ||
301 | printf( "\t%s=%s\n", atts[i], atts[i+1] ); | ||
302 | i += 2; | ||
303 | } | ||
304 | |||
305 | if( atts[i] ) | ||
306 | { | ||
307 | tabs(); | ||
308 | printf( "\ttrailing attribute: %s\n", atts[i] ); | ||
309 | } | ||
310 | } | ||
311 | |||
312 | virtual void endElement(const char *name) | ||
313 | { | ||
314 | tabs(); | ||
315 | printf("endElement %s\n", name); | ||
316 | } | ||
317 | |||
318 | virtual void characterData(const char *s, int len) | ||
319 | { | ||
320 | tabs(); | ||
321 | |||
322 | char* str = new char[len+1]; | ||
323 | strncpy( str, s, len ); | ||
324 | str[len] = '\0'; | ||
325 | printf("CharacterData %s\n", str); | ||
326 | delete str; | ||
327 | } | ||
328 | |||
329 | virtual void processingInstruction(const char *target, const char *data) | ||
330 | { | ||
331 | tabs(); | ||
332 | printf("processingInstruction %s\n", data); | ||
333 | } | ||
334 | virtual void comment(const char *data) | ||
335 | { | ||
336 | tabs(); | ||
337 | printf("comment %s\n", data); | ||
338 | } | ||
339 | |||
340 | virtual void startCdataSection() | ||
341 | { | ||
342 | tabs(); | ||
343 | printf("startCdataSection\n"); | ||
344 | } | ||
345 | |||
346 | virtual void endCdataSection() | ||
347 | { | ||
348 | tabs(); | ||
349 | printf("endCdataSection\n"); | ||
350 | } | ||
351 | |||
352 | virtual void defaultData(const char *s, int len) | ||
353 | { | ||
354 | tabs(); | ||
355 | |||
356 | char* str = new char[len+1]; | ||
357 | strncpy( str, s, len ); | ||
358 | str[len] = '\0'; | ||
359 | printf("defaultData %s\n", str); | ||
360 | delete str; | ||
361 | } | ||
362 | |||
363 | virtual void unparsedEntityDecl( | ||
364 | const char *entityName, | ||
365 | const char *base, | ||
366 | const char *systemId, | ||
367 | const char *publicId, | ||
368 | const char *notationName) | ||
369 | { | ||
370 | tabs(); | ||
371 | |||
372 | printf( | ||
373 | "unparsed entity:\n" | ||
374 | "\tentityName %s\n" | ||
375 | "\tbase %s\n" | ||
376 | "\tsystemId %s\n" | ||
377 | "\tpublicId %s\n" | ||
378 | "\tnotationName %s\n", | ||
379 | entityName, | ||
380 | base, | ||
381 | systemId, | ||
382 | publicId, | ||
383 | notationName ); | ||
384 | } | ||
385 | }; | ||
386 | |||
387 | |||
388 | int main() | ||
389 | { | ||
390 | char buf[1024]; | ||
391 | |||
392 | FILE* file = LLFile::fopen("test.xml", "rb"); | ||
393 | if( !file ) | ||
394 | { | ||
395 | return 1; | ||
396 | } | ||
397 | |||
398 | LLXmlDOMParser parser; | ||
399 | int done; | ||
400 | do { | ||
401 | size_t len = fread(buf, 1, sizeof(buf), file); | ||
402 | done = len < sizeof(buf); | ||
403 | if( 0 == parser.parse( buf, len, done) ) | ||
404 | { | ||
405 | fprintf(stderr, | ||
406 | "%s at line %d\n", | ||
407 | parser.getErrorString(), | ||
408 | parser.getCurrentLineNumber() ); | ||
409 | return 1; | ||
410 | } | ||
411 | } while (!done); | ||
412 | |||
413 | fclose( file ); | ||
414 | return 0; | ||
415 | } | ||
416 | */ | ||
417 | |||