diff options
Diffstat (limited to '')
-rw-r--r-- | linden/indra/llcommon/llsdserialize_xml.cpp | 137 |
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 | ||
40 | extern "C" | 40 | extern "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) | |||
79 | S32 LLSDXMLFormatter::format_impl(const LLSD& data, std::ostream& ostr, U32 options, U32 level) const | 79 | S32 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 | ||
268 | private: | ||
269 | void reset(); | 269 | void reset(); |
270 | 270 | ||
271 | private: | ||
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 | ||
327 | LLSDXMLParser::Impl::Impl() | 326 | LLSDXMLParser::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 | ||
339 | bool is_eol(char c) | 337 | inline 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 | ||
367 | S32 LLSDXMLParser::Impl::parse(std::istream& input, LLSD& data) | 365 | S32 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 | ||
423 | void LLSDXMLParser::Impl::reset() | 420 | |
421 | S32 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 | |||
498 | void 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 | ||
477 | void LLSDXMLParser::Impl::parsePart(const char* buf, int len) | 546 | void 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 | ||
489 | void LLSDXMLParser::Impl::startElementHandler(const XML_Char* name, const XML_Char** attributes) | 559 | void 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 |
739 | S32 LLSDXMLParser::doParse(std::istream& input, LLSD& data) const | 809 | S32 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 | ||
822 | void LLSDXMLParser::doReset() | ||
823 | { | ||
824 | impl.reset(); | ||
742 | } | 825 | } |