summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorArseny Kapoulkine <arseny.kapoulkine@gmail.com>2014-09-22 06:29:14 +0000
committerArseny Kapoulkine <arseny.kapoulkine@gmail.com>2014-09-22 06:29:14 +0000
commitbb6eaa756588df7ed270a4f32a43922f7e006bba (patch)
treeac9a555f21a21f543a23f66e40a43bad433a60f4 /src
parentfff1991743c196a471cb5e05569a7631dd15a4fe (diff)
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
Diffstat (limited to 'src')
-rw-r--r--src/pugixml.cpp118
1 files changed, 66 insertions, 52 deletions
diff --git a/src/pugixml.cpp b/src/pugixml.cpp
index cc19c10..28b805d 100644
--- a/src/pugixml.cpp
+++ b/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();
+ // flush the remaining buffer contents
+ flush();
- // handle large chunks
- if (length > bufcapacity)
+ // handle large chunks
+ if (length > bufcapacity)
+ {
+ if (encoding == get_write_native_encoding())
{
- if (encoding == get_write_native_encoding())
- {
- // fast path, can just write data chunk
- 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);
+ // fast path, can just write data chunk
+ writer.write(data, length * sizeof(char_t));
+ return;
+ }
- // convert chunk and write
- flush(data, chunk_size);
+ // 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);
- // iterate
- data += chunk_size;
- length -= chunk_size;
- }
+ // convert chunk and write
+ flush(data, chunk_size);
- // small tail is copied below
- bufsize = 0;
+ // iterate
+ data += chunk_size;
+ length -= chunk_size;
}
+
+ // small tail is copied below
+ bufsize = 0;
}
memcpy(buffer + bufsize, data, length * sizeof(char_t));
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)
{
write(data, strlength(data));
@@ -3336,7 +3346,8 @@ PUGI__NS_BEGIN
writer.write('<');
writer.write(name);
- node_output_attributes(writer, node, flags);
+ if (node.first_attribute())
+ node_output_attributes(writer, node, flags);
if (flags & format_raw)
{
@@ -3349,26 +3360,31 @@ PUGI__NS_BEGIN
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))
+ else
{
- writer.write('>');
+ xml_node first = node.first_child();
- 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());
+ if (!first)
+ writer.write(' ', '/', '>', '\n');
+ else if (!first.next_sibling() && (first.type() == node_pcdata || first.type() == node_cdata))
+ {
+ writer.write('>');
- writer.write('<', '/');
- writer.write(name);
- writer.write('>', '\n');
- }
- else
- {
- writer.write('>', '\n');
+ if (first.type() == node_pcdata)
+ text_output(writer, first.value(), ctx_special_pcdata, flags);
+ else
+ text_output_cdata(writer, first.value());
- return true;
+ writer.write('<', '/');
+ writer.write(name);
+ writer.write('>', '\n');
+ }
+ else
+ {
+ writer.write('>', '\n');
+
+ return true;
+ }
}
return false;
@@ -3381,10 +3397,11 @@ PUGI__NS_BEGIN
writer.write('<', '/');
writer.write(name);
- writer.write('>');
- if ((flags & format_raw) == 0)
- writer.write('\n');
+ if (flags & format_raw)
+ writer.write('>');
+ else
+ writer.write('>', '\n');
}
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
{
- if (!_root) return xml_node();
-
- if (_root->next_sibling) return xml_node(_root->next_sibling);
- else return xml_node();
+ return _root ? xml_node(_root->next_sibling) : xml_node();
}
PUGI__FN xml_node xml_node::previous_sibling(const char_t* name_) const