Skip to content
Snippets Groups Projects
Commit c60320e2 authored by Martin Nilsson's avatar Martin Nilsson
Browse files

Optimizations in the XML serialization code. Added render_to_file to avoid to...

Optimizations in the XML serialization code. Added render_to_file to avoid to store the result in memory. Improved _sprintf.

Rev: lib/modules/Parser.pmod/XML.pmod/Tree.pmod:1.21
parent 3a2dcea3
No related branches found
No related tags found
No related merge requests found
#pike __REAL_VERSION__
/*
* $Id: Tree.pmod,v 1.20 2002/10/25 16:47:41 nilsson Exp $
* $Id: Tree.pmod,v 1.21 2002/11/29 00:50:27 nilsson Exp $
*
*/
......@@ -47,39 +47,48 @@ constant XML_NODE = (XML_ROOT | XML_ELEMENT | XML_TEXT |
#define XML_NODE (XML_ROOT | XML_ELEMENT | XML_TEXT | \
XML_PI | XML_COMMENT | XML_ATTR)
//! Quotes the string given in @[data] by escaping &, < and >. If
//! the flag @[preserve_roxen_entities] is set entities on the form
//! @tt{&foo.bar;@} will not be escaped.
string text_quote(string data, void|int(0..1) preserve_roxen_entities)
//! Quotes the string given in @[data] by escaping &, < and >.
string text_quote(string data)
{
if (preserve_roxen_entities) {
return replace(data, ([ "&":"&amp;",
"<":"&lt;",
">":"&gt;" ]) );
}
//! Quotes strings just like @[text_quote], but entities in the form
//! @tt{&foo.bar;@} will not be quoted.
string roxen_text_quote(string data) {
string out = "";
int pos, opos;
while ((pos = search(data, "&", pos)) >= 0) {
if ((sscanf(data[pos..], "&%[^ <>;&];", string entity) == 1) &&
search(entity, ".") >= 0) {
out += text_quote(data[opos..pos - 1], 0) + "&" + entity + ";";
out += text_quote(data[opos..pos - 1]) + "&" + entity + ";";
pos += strlen(entity) + 2;
} else {
out += text_quote(data[opos..pos], 0);
out += text_quote(data[opos..pos]);
pos++;
}
opos = pos;
}
return out + text_quote(data[opos..], 0);
return out + text_quote(data[opos..]);
}
else
return replace(data, ([ "&":"&amp;",
//! Quotes the string given in @[data] by escaping &, <, >, ' and ".
string attribute_quote(string data)
{
return replace(data, ([ "\"":"&quot;",
"'":"&apos;",
"&":"&amp;",
"<":"&lt;",
">":"&gt;" ]) );
}
//! Quotes the string given in @[data] by escaping &, <, >, ' and ".
//! If the flag @[preserve_roxen_entities] is set entities on the form
//! @tt{&foo.bar;@} will not be escaped.
string attribute_quote(string data, void|int(0..1) preserve_roxen_entities)
//! Quotes strings just like @[attribute_quote], but entities in the
//! form @tt{&foo.bar;@} will not be quoted.
string roxen_attribute_quote(string data)
{
return replace(text_quote(data, preserve_roxen_entities),
return replace(roxen_text_quote(data),
([ "\"":"&quot;",
"'":"&apos;" ]));
}
......@@ -583,19 +592,12 @@ class Node {
error( "Can not case Node to "+to+".\n" );
}
//! Creates an XML representation of the nodes sub tree. If the
//! flag @[preserve_roxen_entities] is set entities on the form
//! @tt{&foo.bar;@} will not be escaped.
string render_xml(void|int(0..1) preserve_roxen_entities)
{
String.Buffer data = String.Buffer();
walk_preorder_2(
lambda(Node n) {
static void low_render_xml(String.Buffer data, Node n,
function(string:string) textq,
function(string:string) attrq) {
switch(n->get_node_type()) {
case XML_TEXT:
data->add(text_quote(n->get_text(),
preserve_roxen_entities));
data->add(textq(n->get_text()));
break;
case XML_ELEMENT:
......@@ -604,9 +606,7 @@ class Node {
data->add("<", n->get_tag_name());
if (mapping attr = n->get_attributes()) {
foreach(indices(attr), string a)
data->add(" ", a, "='",
attribute_quote(attr[a],
preserve_roxen_entities), "'");
data->add(" ", a, "='", attrq(attr[a]), "'");
}
if (n->count_children())
data->add(">");
......@@ -618,9 +618,7 @@ class Node {
data->add("<?xml");
if (mapping attr = n->get_attributes()) {
foreach(indices(attr), string a)
data->add(" ", a, "='",
attribute_quote(attr[a],
preserve_roxen_entities), "'");
data->add(" ", a, "='", attrq(attr[a]), "'");
}
data->add("?>\n");
break;
......@@ -637,17 +635,49 @@ class Node {
data->add("<!--", n->get_text(), "-->");
break;
}
},
lambda(Node n) {
array(Node) children = n->get_children();
foreach(children, Node n) {
low_render_xml(data, n, textq, attrq);
}
if (n->get_node_type() == XML_ELEMENT)
if (n->count_children())
if (sizeof(children))
if (strlen(n->get_tag_name()))
data->add("</", n->get_tag_name(), ">");
});
}
//! Creates an XML representation of the node sub tree. If the
//! flag @[preserve_roxen_entities] is set, entities on the form
//! @tt{&foo.bar;@} will not be escaped.
string render_xml(void|int(0..1) preserve_roxen_entities)
{
String.Buffer data = String.Buffer();
if(preserve_roxen_entities)
low_render_xml(data, this_object(), roxen_text_quote,
roxen_attribute_quote);
else
low_render_xml(data, this_object(), text_quote, attribute_quote);
return (string)data;
}
//! Creates an XML representation fo the node sub tree and streams
//! the output to the file @[f]. If the flag @[preserve_roxen_entities]
//! is set, entities on the form @tt{&foo.bar;@} will not be escaped.
void render_to_file(Stdio.File f,
void|int(0..1) preserve_roxen_entities) {
object data = class (Stdio.File f) {
void add(string ... args) {
f->write(args[*]);
}
} (f);
if(preserve_roxen_entities)
low_render_xml(data, this_object(), roxen_text_quote,
roxen_attribute_quote);
else
low_render_xml(data, this_object(), text_quote, attribute_quote);
}
// Override AbstractNode::`[]
Node `[](mixed pos)
{
......@@ -698,8 +728,9 @@ class Node {
return (mAttrNodes);
}
string _sprintf() {
return sprintf("Node(#%d:%d,%s)", mDocOrder, get_node_type(), get_any_name());
string _sprintf(int t) {
return t=='O' && sprintf("%O(#%d:%d,%s)", this_program, mDocOrder,
get_node_type(), get_any_name());
}
};
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment