Optimize and refactor node output implementation a bit (+5% perf gain)
git-svn-id: https://pugixml.googlecode.com/svn/trunk@1019 99668b35-9821-0410-8761-19e4c4f06640
This commit is contained in:
parent
fff1991743
commit
bb6eaa7565
126
src/pugixml.cpp
126
src/pugixml.cpp
@ -3059,47 +3059,57 @@ PUGI__NS_BEGIN
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void write(const char_t* data, size_t length)
|
void write_direct(const char_t* data, size_t length)
|
||||||
{
|
{
|
||||||
if (bufsize + length > bufcapacity)
|
// flush the remaining buffer contents
|
||||||
|
flush();
|
||||||
|
|
||||||
|
// handle large chunks
|
||||||
|
if (length > bufcapacity)
|
||||||
{
|
{
|
||||||
// flush the remaining buffer contents
|
if (encoding == get_write_native_encoding())
|
||||||
flush();
|
|
||||||
|
|
||||||
// handle large chunks
|
|
||||||
if (length > bufcapacity)
|
|
||||||
{
|
{
|
||||||
if (encoding == get_write_native_encoding())
|
// fast path, can just write data chunk
|
||||||
{
|
writer.write(data, length * sizeof(char_t));
|
||||||
// fast path, can just write data chunk
|
return;
|
||||||
writer.write(data, length * sizeof(char_t));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// need to convert in suitable chunks
|
|
||||||
while (length > bufcapacity)
|
|
||||||
{
|
|
||||||
// get chunk size by selecting such number of characters that are guaranteed to fit into scratch buffer
|
|
||||||
// and form a complete codepoint sequence (i.e. discard start of last codepoint if necessary)
|
|
||||||
size_t chunk_size = get_valid_length(data, bufcapacity);
|
|
||||||
|
|
||||||
// convert chunk and write
|
|
||||||
flush(data, chunk_size);
|
|
||||||
|
|
||||||
// iterate
|
|
||||||
data += chunk_size;
|
|
||||||
length -= chunk_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
// small tail is copied below
|
|
||||||
bufsize = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// need to convert in suitable chunks
|
||||||
|
while (length > bufcapacity)
|
||||||
|
{
|
||||||
|
// get chunk size by selecting such number of characters that are guaranteed to fit into scratch buffer
|
||||||
|
// and form a complete codepoint sequence (i.e. discard start of last codepoint if necessary)
|
||||||
|
size_t chunk_size = get_valid_length(data, bufcapacity);
|
||||||
|
|
||||||
|
// convert chunk and write
|
||||||
|
flush(data, chunk_size);
|
||||||
|
|
||||||
|
// iterate
|
||||||
|
data += chunk_size;
|
||||||
|
length -= chunk_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
// small tail is copied below
|
||||||
|
bufsize = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(buffer + bufsize, data, length * sizeof(char_t));
|
memcpy(buffer + bufsize, data, length * sizeof(char_t));
|
||||||
bufsize += length;
|
bufsize += length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void write(const char_t* data, size_t length)
|
||||||
|
{
|
||||||
|
if (bufsize + length <= bufcapacity)
|
||||||
|
{
|
||||||
|
memcpy(buffer + bufsize, data, length * sizeof(char_t));
|
||||||
|
bufsize += length;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
write_direct(data, length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void write(const char_t* data)
|
void write(const char_t* data)
|
||||||
{
|
{
|
||||||
write(data, strlength(data));
|
write(data, strlength(data));
|
||||||
@ -3336,7 +3346,8 @@ PUGI__NS_BEGIN
|
|||||||
writer.write('<');
|
writer.write('<');
|
||||||
writer.write(name);
|
writer.write(name);
|
||||||
|
|
||||||
node_output_attributes(writer, node, flags);
|
if (node.first_attribute())
|
||||||
|
node_output_attributes(writer, node, flags);
|
||||||
|
|
||||||
if (flags & format_raw)
|
if (flags & format_raw)
|
||||||
{
|
{
|
||||||
@ -3349,26 +3360,31 @@ PUGI__NS_BEGIN
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (!node.first_child())
|
|
||||||
writer.write(' ', '/', '>', '\n');
|
|
||||||
else if (node.first_child() == node.last_child() && (node.first_child().type() == node_pcdata || node.first_child().type() == node_cdata))
|
|
||||||
{
|
|
||||||
writer.write('>');
|
|
||||||
|
|
||||||
if (node.first_child().type() == node_pcdata)
|
|
||||||
text_output(writer, node.first_child().value(), ctx_special_pcdata, flags);
|
|
||||||
else
|
|
||||||
text_output_cdata(writer, node.first_child().value());
|
|
||||||
|
|
||||||
writer.write('<', '/');
|
|
||||||
writer.write(name);
|
|
||||||
writer.write('>', '\n');
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
writer.write('>', '\n');
|
xml_node first = node.first_child();
|
||||||
|
|
||||||
return true;
|
if (!first)
|
||||||
|
writer.write(' ', '/', '>', '\n');
|
||||||
|
else if (!first.next_sibling() && (first.type() == node_pcdata || first.type() == node_cdata))
|
||||||
|
{
|
||||||
|
writer.write('>');
|
||||||
|
|
||||||
|
if (first.type() == node_pcdata)
|
||||||
|
text_output(writer, first.value(), ctx_special_pcdata, flags);
|
||||||
|
else
|
||||||
|
text_output_cdata(writer, first.value());
|
||||||
|
|
||||||
|
writer.write('<', '/');
|
||||||
|
writer.write(name);
|
||||||
|
writer.write('>', '\n');
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
writer.write('>', '\n');
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@ -3381,10 +3397,11 @@ PUGI__NS_BEGIN
|
|||||||
|
|
||||||
writer.write('<', '/');
|
writer.write('<', '/');
|
||||||
writer.write(name);
|
writer.write(name);
|
||||||
writer.write('>');
|
|
||||||
|
|
||||||
if ((flags & format_raw) == 0)
|
if (flags & format_raw)
|
||||||
writer.write('\n');
|
writer.write('>');
|
||||||
|
else
|
||||||
|
writer.write('>', '\n');
|
||||||
}
|
}
|
||||||
|
|
||||||
PUGI__FN void node_output_simple(xml_buffered_writer& writer, const xml_node& node, unsigned int flags)
|
PUGI__FN void node_output_simple(xml_buffered_writer& writer, const xml_node& node, unsigned int flags)
|
||||||
@ -4582,10 +4599,7 @@ namespace pugi
|
|||||||
|
|
||||||
PUGI__FN xml_node xml_node::next_sibling() const
|
PUGI__FN xml_node xml_node::next_sibling() const
|
||||||
{
|
{
|
||||||
if (!_root) return xml_node();
|
return _root ? xml_node(_root->next_sibling) : xml_node();
|
||||||
|
|
||||||
if (_root->next_sibling) return xml_node(_root->next_sibling);
|
|
||||||
else return xml_node();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PUGI__FN xml_node xml_node::previous_sibling(const char_t* name_) const
|
PUGI__FN xml_node xml_node::previous_sibling(const char_t* name_) const
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user