aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/llxml/llxmlparser.cpp
diff options
context:
space:
mode:
authorJacek Antonelli2008-08-15 23:44:46 -0500
committerJacek Antonelli2008-08-15 23:44:46 -0500
commit38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4 (patch)
treeadca584755d22ca041a2dbfc35d4eca01f70b32c /linden/indra/llxml/llxmlparser.cpp
parentREADME.txt (diff)
downloadmeta-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.cpp417
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
39LLXmlParser::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
64LLXmlParser::~LLXmlParser()
65{
66 XML_ParserFree( mParser );
67}
68
69
70BOOL 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
112exit_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).
135S32 LLXmlParser::parse( const char* buf, int len, int isFinal )
136{
137 return XML_Parse(mParser, buf, len, isFinal);
138}
139
140const 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
150S32 LLXmlParser::getCurrentLineNumber()
151{
152 return XML_GetCurrentLineNumber( mParser );
153}
154
155S32 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
164void 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
175void 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
186void 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
197void 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
208void LLXmlParser::commentHandler(void *userData, const XML_Char *data)
209{
210 LLXmlParser* self = (LLXmlParser*) userData;
211 self->comment( data );
212}
213
214// static
215void LLXmlParser::startCdataSectionHandler(void *userData)
216{
217 LLXmlParser* self = (LLXmlParser*) userData;
218 self->mDepth++;
219 self->startCdataSection();
220}
221
222// static
223void 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
244void 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
258void 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/*
277class LLXmlDOMParser : public LLXmlParser
278{
279public:
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
388int 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