mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-08-22 06:12:32 -06:00
Core: XmlNode is now pick/deep copy option type; fixed issues with XmlParser stream and short files
git-svn-id: svn://ultimatepp.org/upp/trunk@6888 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
parent
7792d14644
commit
1bb77e4e7e
3 changed files with 57 additions and 63 deletions
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
NAMESPACE_UPP
|
||||
|
||||
#define LLOG(x) // LOG(x);
|
||||
#define LLOG(x) // LOG(x)
|
||||
|
||||
static inline void sDeXmlChar(StringBuffer& result, char chr, byte charset, bool escapelf)
|
||||
{
|
||||
|
|
@ -208,13 +208,14 @@ inline static bool IsXmlNameChar(int c)
|
|||
}
|
||||
|
||||
void XmlParser::LoadMore0()
|
||||
{
|
||||
if(in) {
|
||||
{ // WARNING: Invalidates pointers to buffer
|
||||
if(in && !in->IsEof()) {
|
||||
int pos = int(term - begin);
|
||||
if(len - pos < MCHARS) {
|
||||
LLOG("LoadMore0 " << pos << ", " << len);
|
||||
begincolumn = GetColumn0();
|
||||
len -= pos;
|
||||
memcpy(buffer, term, len);
|
||||
memmove(buffer, term, len);
|
||||
term = begin = buffer;
|
||||
len += in->Get(~buffer + len, CHUNK);
|
||||
buffer[len] = '\0';
|
||||
|
|
@ -223,10 +224,11 @@ void XmlParser::LoadMore0()
|
|||
}
|
||||
|
||||
bool XmlParser::More()
|
||||
{
|
||||
{ // WARNING: Invalidates pointers to buffer
|
||||
begincolumn = GetColumn();
|
||||
if(!in)
|
||||
if(!in || in->IsEof())
|
||||
return false;
|
||||
LLOG("More " << (int)CHUNK);
|
||||
len = in->Get(buffer, CHUNK);
|
||||
buffer[len] = '\0';
|
||||
term = begin = buffer;
|
||||
|
|
@ -262,6 +264,7 @@ void XmlParser::Next()
|
|||
if(empty_tag) {
|
||||
empty_tag = false;
|
||||
type = XML_END;
|
||||
LLOG("XML_END (empty tag) " << tagtext);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -270,6 +273,7 @@ void XmlParser::Next()
|
|||
for(;;) {
|
||||
if(!HasMore()) {
|
||||
type = XML_EOF;
|
||||
LLOG("XML_EOF");
|
||||
return;
|
||||
}
|
||||
LoadMore();
|
||||
|
|
@ -312,8 +316,10 @@ void XmlParser::Next()
|
|||
if(cdata.GetCount() && (npreserve || preserveall))
|
||||
type = XML_TEXT;
|
||||
|
||||
if(type == XML_TEXT)
|
||||
if(type == XML_TEXT) {
|
||||
LLOG("XML_TEXT " << cdata);
|
||||
return;
|
||||
}
|
||||
|
||||
term++;
|
||||
LoadMore();
|
||||
|
|
@ -355,6 +361,7 @@ void XmlParser::Next()
|
|||
line++;
|
||||
tagtext.Cat(*term++);
|
||||
}
|
||||
LLOG("XML_DECL " << tagtext);
|
||||
}
|
||||
else
|
||||
if(*term == '?') {
|
||||
|
|
@ -372,6 +379,7 @@ void XmlParser::Next()
|
|||
line++;
|
||||
tagtext.Cat(*term++);
|
||||
}
|
||||
LLOG("XML_PI " << tagtext);
|
||||
}
|
||||
else
|
||||
if(*term == '/') {
|
||||
|
|
@ -381,6 +389,7 @@ void XmlParser::Next()
|
|||
while(IsXmlNameChar(*term))
|
||||
term++;
|
||||
tagtext = String(t, term);
|
||||
LLOG("XML_END " << tagtext);
|
||||
if(*term != '>')
|
||||
throw XmlError("Unterminated end-tag");
|
||||
term++;
|
||||
|
|
@ -388,9 +397,10 @@ void XmlParser::Next()
|
|||
else {
|
||||
type = XML_TAG;
|
||||
const char *t = term;
|
||||
while(HasMore() && IsXmlNameChar(*term))
|
||||
while(IsXmlNameChar(*term))
|
||||
term++;
|
||||
tagtext = String(t, term);
|
||||
LLOG("XML_TAG " << tagtext);
|
||||
for(;;) {
|
||||
SkipWhites();
|
||||
if(*term == '>') {
|
||||
|
|
@ -405,8 +415,9 @@ void XmlParser::Next()
|
|||
}
|
||||
if(!HasMore())
|
||||
throw XmlError("Unterminated tag");
|
||||
LoadMore();
|
||||
const char *t = term++;
|
||||
while(HasMore() && (byte)*term > ' ' && *term != '=' && *term != '>')
|
||||
while((byte)*term > ' ' && *term != '=' && *term != '>')
|
||||
term++;
|
||||
String attr(t, term);
|
||||
SkipWhites();
|
||||
|
|
@ -458,7 +469,7 @@ String XmlParser::ReadTag(bool next)
|
|||
{
|
||||
if(type != XML_TAG)
|
||||
throw XmlError("Expected tag");
|
||||
LLOG("ReadTag " << text);
|
||||
LLOG("ReadTag " << tagtext);
|
||||
String h = tagtext;
|
||||
if(next) {
|
||||
stack.Add(Nesting(h, npreserve));
|
||||
|
|
@ -520,7 +531,7 @@ bool XmlParser::End()
|
|||
if(IsEof())
|
||||
throw XmlError("Unexpected end of file");
|
||||
if(IsEnd()) {
|
||||
LLOG("EndTag " << text);
|
||||
LLOG("EndTag " << tagtext);
|
||||
if(stack.IsEmpty())
|
||||
throw XmlError(NFormat("Unexpected end-tag: </%s>", tagtext));
|
||||
if(stack.Top().tag != tagtext && !relaxed) {
|
||||
|
|
@ -847,6 +858,17 @@ void XmlNode::Shrink()
|
|||
node.Shrink();
|
||||
}
|
||||
|
||||
XmlNode::XmlNode(const XmlNode& n, int)
|
||||
{
|
||||
type = n.type;
|
||||
text = n.text;
|
||||
node <<= n.node;
|
||||
if(n.attr) {
|
||||
attr.Create();
|
||||
*attr <<= *n.attr;
|
||||
}
|
||||
}
|
||||
|
||||
bool Ignore(XmlParser& p, dword style)
|
||||
{
|
||||
if((XML_IGNORE_DECLS & style) && p.IsDecl() ||
|
||||
|
|
@ -891,6 +913,8 @@ static XmlNode sReadXmlNode(XmlParser& p, ParseXmlFilter *filter, dword style)
|
|||
m.CreateComment(p.ReadComment());
|
||||
return m;
|
||||
}
|
||||
if(!p.IsText())
|
||||
throw XmlError("Invalid XML.");
|
||||
m.CreateText(p.ReadText());
|
||||
m.Shrink();
|
||||
return m;
|
||||
|
|
@ -972,55 +996,6 @@ bool ShouldPreserve(const String& s)
|
|||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
String AsXML(const XmlNode& node, dword style)
|
||||
{
|
||||
StringBuffer r;
|
||||
if(style & XML_HEADER)
|
||||
r << XmlHeader();
|
||||
if(style & XML_DOCTYPE)
|
||||
for(int i = 0; i < node.GetCount(); i++) {
|
||||
const XmlNode& m = node.Node(i);
|
||||
if(m.GetType() == XML_TAG) {
|
||||
r << XmlDocType(m.GetText());
|
||||
break;
|
||||
}
|
||||
}
|
||||
style &= ~(XML_HEADER|XML_DOCTYPE);
|
||||
switch(node.GetType()) {
|
||||
case XML_PI:
|
||||
r << "<?" << node.GetText() << "?>\r\n";
|
||||
break;
|
||||
case XML_DECL:
|
||||
r << "<!" << node.GetText() << ">\r\n";
|
||||
break;
|
||||
case XML_COMMENT:
|
||||
r << "<!--" << node.GetText() << "-->\r\n";
|
||||
break;
|
||||
case XML_DOC:
|
||||
for(int i = 0; i < node.GetCount(); i++)
|
||||
r << AsXML(node.Node(i), style);
|
||||
break;
|
||||
case XML_TEXT:
|
||||
r << DeXml(node.GetText());
|
||||
break;
|
||||
case XML_TAG:
|
||||
XmlTag tag(node.GetText());
|
||||
for(int i = 0; i < node.GetAttrCount(); i++)
|
||||
tag(node.AttrId(i), node.Attr(i));
|
||||
if(node.GetCount()) {
|
||||
StringBuffer body;
|
||||
for(int i = 0; i < node.GetCount(); i++)
|
||||
body << AsXML(node.Node(i), style);
|
||||
r << tag(~body);
|
||||
}
|
||||
else
|
||||
r << tag();
|
||||
}
|
||||
return r;
|
||||
}
|
||||
*/
|
||||
|
||||
static void sAsXML(Stream& out, const XmlNode& node, dword style, const String& indent)
|
||||
{
|
||||
if(style & XML_HEADER) {
|
||||
|
|
|
|||
|
|
@ -160,7 +160,7 @@ public:
|
|||
XmlParser(Stream& in);
|
||||
};
|
||||
|
||||
class XmlNode {
|
||||
class XmlNode : Moveable< XmlNode, DeepCopyOption<XmlNode> > {
|
||||
int type;
|
||||
String text;
|
||||
Array<XmlNode> node;
|
||||
|
|
@ -215,8 +215,12 @@ public:
|
|||
void SetAttrsPick(pick_ VectorMap<String, String>& a);
|
||||
|
||||
void Shrink();
|
||||
|
||||
bool IsPicked() const { return node.IsPicked(); }
|
||||
|
||||
XmlNode() { type = XML_DOC; }
|
||||
XmlNode(const XmlNode& n, int);
|
||||
|
||||
XmlNode() { type = XML_DOC; }
|
||||
};
|
||||
|
||||
enum {
|
||||
|
|
|
|||
|
|
@ -18,6 +18,9 @@ structure `- each XmlNode can contain any number of child XmlNodes.
|
|||
XmlNode is mutable and U`+`+ provides function to parse XML and
|
||||
store it to XmlNode and also to take XmlNode and create corresponding
|
||||
XML document.&]
|
||||
[s9;%% XmlNode is [*/^topic`:`/`/Core`/srcdoc`/Moveable`$en`-us^ moveable][*/
|
||||
]type with [*/^topic`:`/`/Core`/srcdoc`/pick`_`$en`-us^ pick and
|
||||
optional deep copy] transfer semantics&]
|
||||
[s3; &]
|
||||
[s0; &]
|
||||
[ {{10000F(128)G(128)@1 [s0;%% [* Public Member List]]}}&]
|
||||
|
|
@ -223,16 +226,28 @@ r]([@(0.0.255) const]_[@(0.0.255) char]_`*[*@3 id], [@(0.0.255) int]_[*@3 val])&
|
|||
[s2;%% Replaces all attributes to [%-*@3 a] using pick operation ([%-*@3 a]
|
||||
is destroyed in operation).&]
|
||||
[s3; &]
|
||||
[s4; &]
|
||||
[s5;:XmlNode`:`:Shrink`(`): [@(0.0.255) void]_[* Shrink]()&]
|
||||
[s2;%% Attempts to minimize memory footprint.&]
|
||||
[s3; &]
|
||||
[s4; &]
|
||||
[s5;:XmlNode`:`:IsPicked`(`)const: [@(0.0.255) bool]_[* IsPicked]()_[@(0.0.255) const]&]
|
||||
[s2;%% Returns true if picked&]
|
||||
[s0; &]
|
||||
[ {{10000F(128)G(128)@1 [s0;%% [* Constructor detail]]}}&]
|
||||
[s3;%% &]
|
||||
[s0; [* XmlNode]()&]
|
||||
[s2;%% Construct an empty XmlNode.&]
|
||||
[s3; &]
|
||||
[s0; &]
|
||||
[s4; &]
|
||||
[s5;:XmlNode`:`:XmlNode`(const XmlNode`&`,int`): [* XmlNode]([@(0.0.255) const]_[* XmlNode][@(0.0.255) `&
|
||||
]_[*@3 n], [@(0.0.255) int])&]
|
||||
[s2;%% Deep copy constructor.&]
|
||||
[s3;%% &]
|
||||
[s0; &]
|
||||
[s0; &]
|
||||
[ {{10000@(113.42.0) [s0;%% [*@7;4 XmlNode `- parse and output functions]]}}&]
|
||||
[s3;%% &]
|
||||
[s4;H0; &]
|
||||
[s5;:ParseXML`(XmlParser`&`,dword`): [_^XmlNode^ XmlNode]_[* ParseXML]([_^XmlParser^ XmlPar
|
||||
ser][@(0.0.255) `&]_[*@3 p], [_^dword^ dword]_[*@3 style]_`=_XML`_IGNORE`_DECLS[@(0.0.255) `|
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue