diff options
author | arseny.kapoulkine@gmail.com <arseny.kapoulkine@gmail.com@99668b35-9821-0410-8761-19e4c4f06640> | 2012-10-31 04:47:17 +0000 |
---|---|---|
committer | arseny.kapoulkine@gmail.com <arseny.kapoulkine@gmail.com@99668b35-9821-0410-8761-19e4c4f06640> | 2012-10-31 04:47:17 +0000 |
commit | 09f9ab079e952853fe0f5ed61657f285a2fcd577 (patch) | |
tree | fd0b29876689d62445868f0e446366b26a72f271 /src/pugixml.cpp | |
parent | 68d533a8287650030265beab8949c76be3493279 (diff) |
Adjust parsing so that it is possible to parse a document fragment into an existing subtree; can be used to implement append_buffer.
git-svn-id: http://pugixml.googlecode.com/svn/trunk@922 99668b35-9821-0410-8761-19e4c4f06640
Diffstat (limited to 'src/pugixml.cpp')
-rw-r--r-- | src/pugixml.cpp | 89 |
1 files changed, 47 insertions, 42 deletions
diff --git a/src/pugixml.cpp b/src/pugixml.cpp index 03a4b9f..168ca0a 100644 --- a/src/pugixml.cpp +++ b/src/pugixml.cpp @@ -2380,13 +2380,13 @@ PUGI__NS_BEGIN return s; } - char_t* parse(char_t* s, xml_node_struct* xmldoc, unsigned int optmsk, char_t endch) + char_t* parse(char_t* s, xml_node_struct* root, unsigned int optmsk, char_t endch) { strconv_attribute_t strconv_attribute = get_strconv_attribute(optmsk); strconv_pcdata_t strconv_pcdata = get_strconv_pcdata(optmsk); char_t ch = 0; - xml_node_struct* cursor = xmldoc; + xml_node_struct* cursor = root; char_t* mark = s; while (*s != 0) @@ -2606,36 +2606,37 @@ PUGI__NS_BEGIN } // check that last tag is closed - if (cursor != xmldoc) PUGI__THROW_ERROR(status_end_element_mismatch, s); + if (cursor != root) PUGI__THROW_ERROR(status_end_element_mismatch, s); return s; } - static xml_parse_result parse(char_t* buffer, size_t length, xml_node_struct* root, unsigned int optmsk) + static xml_parse_result parse(char_t* buffer, size_t length, xml_document_struct* xmldoc, xml_node_struct* root, unsigned int optmsk) { - xml_document_struct* xmldoc = static_cast<xml_document_struct*>(root); + // allocator object is a part of document object + xml_allocator& alloc = *static_cast<xml_allocator*>(xmldoc); // store buffer for offset_debug - xmldoc->buffer = buffer; + if (xmldoc == root) xmldoc->buffer = buffer; // early-out for empty documents if (length == 0) return make_parse_result(status_ok); // create parser on stack - xml_parser parser(*xmldoc); + xml_parser parser(alloc); // save last character and make buffer zero-terminated (speeds up parsing) char_t endch = buffer[length - 1]; buffer[length - 1] = 0; // perform actual parsing - parser.parse(buffer, xmldoc, optmsk, endch); + parser.parse(buffer, root, optmsk, endch); xml_parse_result result = make_parse_result(parser.error_status, parser.error_offset ? parser.error_offset - buffer : 0); assert(result.offset >= 0 && static_cast<size_t>(result.offset) <= length); // update allocator state - *static_cast<xml_allocator*>(xmldoc) = parser.alloc; + alloc = parser.alloc; // since we removed last character, we have to handle the only possible false positive if (result && endch == '<') @@ -3650,6 +3651,35 @@ PUGI__NS_BEGIN return result == 0; } + + PUGI__FN xml_parse_result load_buffer_impl(xml_document_struct* doc, xml_node_struct* root, void* contents, size_t size, unsigned int options, xml_encoding encoding, bool is_mutable, bool own, char_t** out_buffer) + { + // check input buffer + assert(contents || size == 0); + + // get actual encoding + xml_encoding buffer_encoding = impl::get_buffer_encoding(encoding, contents, size); + + // get private buffer + char_t* buffer = 0; + size_t length = 0; + + if (!impl::convert_buffer(buffer, length, buffer_encoding, contents, size, is_mutable)) return impl::make_parse_result(status_out_of_memory); + + // delete original buffer if we performed a conversion + if (own && buffer != contents && contents) impl::xml_memory::deallocate(contents); + + // parse + xml_parse_result res = impl::xml_parser::parse(buffer, length, doc, root, options); + + // remember encoding + res.encoding = buffer_encoding; + + // grab onto buffer if it's our buffer, user is responsible for deallocating contents himself + if (own || buffer != contents) *out_buffer = buffer; + + return res; + } PUGI__NS_END namespace pugi @@ -5224,50 +5254,25 @@ namespace pugi return impl::load_file_impl(*this, file, options, encoding); } - PUGI__FN xml_parse_result xml_document::load_buffer_impl(void* contents, size_t size, unsigned int options, xml_encoding encoding, bool is_mutable, bool own) + PUGI__FN xml_parse_result xml_document::load_buffer(const void* contents, size_t size, unsigned int options, xml_encoding encoding) { reset(); - // check input buffer - assert(contents || size == 0); - - // get actual encoding - xml_encoding buffer_encoding = impl::get_buffer_encoding(encoding, contents, size); - - // get private buffer - char_t* buffer = 0; - size_t length = 0; - - if (!impl::convert_buffer(buffer, length, buffer_encoding, contents, size, is_mutable)) return impl::make_parse_result(status_out_of_memory); - - // delete original buffer if we performed a conversion - if (own && buffer != contents && contents) impl::xml_memory::deallocate(contents); - - // parse - xml_parse_result res = impl::xml_parser::parse(buffer, length, _root, options); - - // remember encoding - res.encoding = buffer_encoding; - - // grab onto buffer if it's our buffer, user is responsible for deallocating contens himself - if (own || buffer != contents) _buffer = buffer; - - return res; - } - - PUGI__FN xml_parse_result xml_document::load_buffer(const void* contents, size_t size, unsigned int options, xml_encoding encoding) - { - return load_buffer_impl(const_cast<void*>(contents), size, options, encoding, false, false); + return load_buffer_impl(static_cast<impl::xml_document_struct*>(_root), _root, const_cast<void*>(contents), size, options, encoding, false, false, &_buffer); } PUGI__FN xml_parse_result xml_document::load_buffer_inplace(void* contents, size_t size, unsigned int options, xml_encoding encoding) { - return load_buffer_impl(contents, size, options, encoding, true, false); + reset(); + + return load_buffer_impl(static_cast<impl::xml_document_struct*>(_root), _root, contents, size, options, encoding, true, false, &_buffer); } PUGI__FN xml_parse_result xml_document::load_buffer_inplace_own(void* contents, size_t size, unsigned int options, xml_encoding encoding) { - return load_buffer_impl(contents, size, options, encoding, true, true); + reset(); + + return load_buffer_impl(static_cast<impl::xml_document_struct*>(_root), _root, contents, size, options, encoding, true, true, &_buffer); } PUGI__FN void xml_document::save(xml_writer& writer, const char_t* indent, unsigned int flags, xml_encoding encoding) const |