aboutsummaryrefslogtreecommitdiff
path: root/web/xhtml-fragment.cxx
diff options
context:
space:
mode:
authorKaren Arutyunov <karen@codesynthesis.com>2019-05-01 22:32:11 +0300
committerKaren Arutyunov <karen@codesynthesis.com>2019-05-15 17:36:01 +0300
commit8f9a80a9ac8f353ce2cdafa23f0e5163d30d5800 (patch)
treeedb89ce300c831897cbe80b9e4e2000b0807acff /web/xhtml-fragment.cxx
parent038ba04cc0e5a6b933254813c34108d6e3fd4a38 (diff)
Add support for description-type package manifest value
Diffstat (limited to 'web/xhtml-fragment.cxx')
-rw-r--r--web/xhtml-fragment.cxx49
1 files changed, 39 insertions, 10 deletions
diff --git a/web/xhtml-fragment.cxx b/web/xhtml-fragment.cxx
index 4d1c178..fe8a0a7 100644
--- a/web/xhtml-fragment.cxx
+++ b/web/xhtml-fragment.cxx
@@ -20,25 +20,38 @@ namespace web
namespace xhtml
{
fragment::
- fragment (const string& text, const string& name)
+ fragment (const string& text, const string& name, size_t length)
{
// To parse the fragment make it a valid xml document, wrapping with the
- // root element.
+ // root element. If requested, truncate the fragment before the
+ // first-level element when the content length limit is exceeded.
//
string doc ("<d>" + text + "</d>");
- parser p (
- doc.c_str (),
- doc.size (),
- name,
- parser::receive_elements | parser::receive_characters |
- parser::receive_attributes_event);
+ parser p (doc.c_str (),
+ doc.size (),
+ name,
+ parser::receive_elements |
+ parser::receive_characters |
+ parser::receive_attributes_event);
+
+ size_t len (0);
+ size_t level (0);
for (parser::event_type e: p)
{
switch (e)
{
case parser::start_element:
+ {
+ truncated = length != 0 && level == 1 && len >= length;
+
+ if (truncated)
+ break;
+
+ ++level;
+ }
+ // Fall through.
case parser::start_attribute:
{
const auto& n (p.qname ());
@@ -51,6 +64,10 @@ namespace web
break;
}
case parser::end_element:
+ {
+ --level;
+ }
+ // Fall through.
case parser::end_attribute:
{
events_.emplace_back (e, "");
@@ -58,12 +75,25 @@ namespace web
}
case parser::characters:
{
- events_.emplace_back (e, p.value ());
+ string& s (p.value ());
+
+ assert (!events_.empty ()); // Contains root element start.
+
+ if (events_.back ().first != parser::start_attribute)
+ len += s.size ();
+
+ events_.emplace_back (e, move (s));
break;
}
default:
assert (false);
}
+
+ if (truncated)
+ {
+ events_.emplace_back (parser::end_element, ""); // Close root.
+ break;
+ }
}
// Unwrap the fragment removing the root element events.
@@ -85,7 +115,6 @@ namespace web
s.start_element (xmlns, e.second);
break;
}
-
case parser::start_attribute:
{
s.start_attribute (e.second);