aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/llcommon/llsdserialize_xml.cpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--linden/indra/llcommon/llsdserialize_xml.cpp137
1 files changed, 110 insertions, 27 deletions
diff --git a/linden/indra/llcommon/llsdserialize_xml.cpp b/linden/indra/llcommon/llsdserialize_xml.cpp
index 7de0c35..690ab67 100644
--- a/linden/indra/llcommon/llsdserialize_xml.cpp
+++ b/linden/indra/llcommon/llsdserialize_xml.cpp
@@ -35,7 +35,7 @@
35#include <iostream> 35#include <iostream>
36#include <deque> 36#include <deque>
37 37
38#include "apr-1/apr_base64.h" 38#include "apr_base64.h"
39 39
40extern "C" 40extern "C"
41{ 41{
@@ -63,7 +63,7 @@ S32 LLSDXMLFormatter::format(const LLSD& data, std::ostream& ostr, U32 options)
63{ 63{
64 std::streamsize old_precision = ostr.precision(25); 64 std::streamsize old_precision = ostr.precision(25);
65 65
66 LLString post = ""; 66 std::string post;
67 if (options & LLSDFormatter::OPTIONS_PRETTY) 67 if (options & LLSDFormatter::OPTIONS_PRETTY)
68 { 68 {
69 post = "\n"; 69 post = "\n";
@@ -79,8 +79,8 @@ S32 LLSDXMLFormatter::format(const LLSD& data, std::ostream& ostr, U32 options)
79S32 LLSDXMLFormatter::format_impl(const LLSD& data, std::ostream& ostr, U32 options, U32 level) const 79S32 LLSDXMLFormatter::format_impl(const LLSD& data, std::ostream& ostr, U32 options, U32 level) const
80{ 80{
81 S32 format_count = 1; 81 S32 format_count = 1;
82 LLString pre = ""; 82 std::string pre;
83 LLString post = ""; 83 std::string post;
84 84
85 if (options & LLSDFormatter::OPTIONS_PRETTY) 85 if (options & LLSDFormatter::OPTIONS_PRETTY)
86 { 86 {
@@ -262,12 +262,13 @@ public:
262 ~Impl(); 262 ~Impl();
263 263
264 S32 parse(std::istream& input, LLSD& data); 264 S32 parse(std::istream& input, LLSD& data);
265 S32 parseLines(std::istream& input, LLSD& data);
265 266
266 void parsePart(const char *buf, int len); 267 void parsePart(const char *buf, int len);
267 268
268private:
269 void reset(); 269 void reset();
270 270
271private:
271 void startElementHandler(const XML_Char* name, const XML_Char** attributes); 272 void startElementHandler(const XML_Char* name, const XML_Char** attributes);
272 void endElementHandler(const XML_Char* name); 273 void endElementHandler(const XML_Char* name);
273 void characterDataHandler(const XML_Char* data, int length); 274 void characterDataHandler(const XML_Char* data, int length);
@@ -307,8 +308,8 @@ private:
307 LLSD mResult; 308 LLSD mResult;
308 S32 mParseCount; 309 S32 mParseCount;
309 310
310 bool mInLLSDElement; 311 bool mInLLSDElement; // true if we're on LLSD
311 bool mGracefullStop; 312 bool mGracefullStop; // true if we found the </llsd
312 313
313 typedef std::deque<LLSD*> LLSDRefStack; 314 typedef std::deque<LLSD*> LLSDRefStack;
314 LLSDRefStack mStack; 315 LLSDRefStack mStack;
@@ -319,15 +320,12 @@ private:
319 320
320 std::string mCurrentKey; 321 std::string mCurrentKey;
321 std::ostringstream mCurrentContent; 322 std::ostringstream mCurrentContent;
322
323 bool mPreStaged;
324}; 323};
325 324
326 325
327LLSDXMLParser::Impl::Impl() 326LLSDXMLParser::Impl::Impl()
328{ 327{
329 mParser = XML_ParserCreate(NULL); 328 mParser = XML_ParserCreate(NULL);
330 mPreStaged = false;
331 reset(); 329 reset();
332} 330}
333 331
@@ -336,7 +334,7 @@ LLSDXMLParser::Impl::~Impl()
336 XML_ParserFree(mParser); 334 XML_ParserFree(mParser);
337} 335}
338 336
339bool is_eol(char c) 337inline bool is_eol(char c)
340{ 338{
341 return (c == '\n' || c == '\r'); 339 return (c == '\n' || c == '\r');
342} 340}
@@ -356,9 +354,9 @@ static unsigned get_till_eol(std::istream& input, char *buf, unsigned bufsize)
356 unsigned count = 0; 354 unsigned count = 0;
357 while (count < bufsize && input.good()) 355 while (count < bufsize && input.good())
358 { 356 {
359 input.get(buf[count]); 357 char c = input.get();
360 count++; 358 buf[count++] = c;
361 if (is_eol(buf[count - 1])) 359 if (is_eol(c))
362 break; 360 break;
363 } 361 }
364 return count; 362 return count;
@@ -366,7 +364,6 @@ static unsigned get_till_eol(std::istream& input, char *buf, unsigned bufsize)
366 364
367S32 LLSDXMLParser::Impl::parse(std::istream& input, LLSD& data) 365S32 LLSDXMLParser::Impl::parse(std::istream& input, LLSD& data)
368{ 366{
369 reset();
370 XML_Status status; 367 XML_Status status;
371 368
372 static const int BUFFER_SIZE = 1024; 369 static const int BUFFER_SIZE = 1024;
@@ -420,14 +417,86 @@ S32 LLSDXMLParser::Impl::parse(std::istream& input, LLSD& data)
420 return mParseCount; 417 return mParseCount;
421} 418}
422 419
423void LLSDXMLParser::Impl::reset() 420
421S32 LLSDXMLParser::Impl::parseLines(std::istream& input, LLSD& data)
424{ 422{
425 if (mPreStaged) 423 XML_Status status = XML_STATUS_OK;
424
425 data = LLSD();
426
427 static const int BUFFER_SIZE = 1024;
428
429 //static char last_buffer[ BUFFER_SIZE ];
430 //std::streamsize last_num_read;
431
432 // Must get rid of any leading \n, otherwise the stream gets into an error/eof state
433 clear_eol(input);
434
435 while( !mGracefullStop
436 && input.good()
437 && !input.eof())
426 { 438 {
427 mPreStaged = false; 439 void* buffer = XML_GetBuffer(mParser, BUFFER_SIZE);
428 return; 440 /*
441 * If we happened to end our last buffer right at the end of the llsd, but the
442 * stream is still going we will get a null buffer here. Check for mGracefullStop.
443 * -- I don't think this is actually true - zero 2008-05-09
444 */
445 if (!buffer)
446 {
447 break;
448 }
449
450 // Get one line
451 input.getline((char*)buffer, BUFFER_SIZE);
452 std::streamsize num_read = input.gcount();
453
454 //memcpy( last_buffer, buffer, num_read );
455 //last_num_read = num_read;
456
457 if ( num_read > 0 )
458 {
459 if (!input.good() )
460 { // Clear state that's set when we run out of buffer
461 input.clear();
462 }
463
464 // Don't parse the NULL at the end which might be added if \n was absorbed by getline()
465 char * text = (char *) buffer;
466 if ( text[num_read - 1] == 0)
467 {
468 num_read--;
469 }
470 }
471
472 status = XML_ParseBuffer(mParser, num_read, false);
473 if (status == XML_STATUS_ERROR)
474 {
475 break;
476 }
429 } 477 }
430 478
479 if (status != XML_STATUS_ERROR
480 && !mGracefullStop)
481 { // Parse last bit
482 status = XML_ParseBuffer(mParser, 0, true);
483 }
484
485 if (status == XML_STATUS_ERROR
486 && !mGracefullStop)
487 {
488 llinfos << "LLSDXMLParser::Impl::parseLines: XML_STATUS_ERROR" << llendl;
489 return LLSDParser::PARSE_FAILURE;
490 }
491
492 clear_eol(input);
493 data = mResult;
494 return mParseCount;
495}
496
497
498void LLSDXMLParser::Impl::reset()
499{
431 mResult.clear(); 500 mResult.clear();
432 mParseCount = 0; 501 mParseCount = 0;
433 502
@@ -476,14 +545,15 @@ LLSDXMLParser::Impl::findAttribute(const XML_Char* name, const XML_Char** pairs)
476 545
477void LLSDXMLParser::Impl::parsePart(const char* buf, int len) 546void LLSDXMLParser::Impl::parsePart(const char* buf, int len)
478{ 547{
479 void * buffer = XML_GetBuffer(mParser, len); 548 if ( buf != NULL
480 if (buffer != NULL && buf != NULL) 549 && len > 0 )
481 { 550 {
482 memcpy(buffer, buf, len); 551 XML_Status status = XML_Parse(mParser, buf, len, false);
552 if (status == XML_STATUS_ERROR)
553 {
554 llinfos << "Unexpected XML parsing error at start" << llendl;
555 }
483 } 556 }
484 XML_ParseBuffer(mParser, len, false);
485
486 mPreStaged = true;
487} 557}
488 558
489void LLSDXMLParser::Impl::startElementHandler(const XML_Char* name, const XML_Char** attributes) 559void LLSDXMLParser::Impl::startElementHandler(const XML_Char* name, const XML_Char** attributes)
@@ -738,5 +808,18 @@ void LLSDXMLParser::parsePart(const char *buf, int len)
738// virtual 808// virtual
739S32 LLSDXMLParser::doParse(std::istream& input, LLSD& data) const 809S32 LLSDXMLParser::doParse(std::istream& input, LLSD& data) const
740{ 810{
741 return impl.parse(input, data); 811// Remove code - emergency fix DEV-17785 parsing newline failure
812// if (mParseLines)
813// {
814 // Use line-based reading (faster code)
815// return impl.parseLines(input, data);
816// }
817
818 return impl.parse(input, data);
819}
820
821// virtual
822void LLSDXMLParser::doReset()
823{
824 impl.reset();
742} 825}