📄 xmlcursor.cxx
字号:
{
if (!atLeaf() &&
!mAttributesSet)
{
mAttributes.clear();
mAttributesSet = true;
ParseBuffer pb(mCursor->mPb);
pb.reset(mCursor->mPb.start());
Data attribute;
Data value;
static const Data term(">/");
pb.skipToOneOf(ParseBuffer::Whitespace, term);
while (!pb.eof() &&
*pb.position() != Symbols::RA_QUOTE[0] &&
*pb.position() != Symbols::SLASH[0])
{
attribute.clear();
value.clear();
const char* anchor = pb.skipWhitespace();
pb.skipToOneOf(ParseBuffer::Whitespace, Symbols::EQUALS);
pb.data(attribute, anchor);
XMLCursor::decodeName(attribute);
StackLog(<< "attribute: " << attribute);
pb.skipWhitespace();
pb.skipToChar(Symbols::EQUALS[0]);
pb.skipChar();
pb.skipWhitespace();
if (!pb.eof())
{
const char quote = *pb.position();
StackLog(<< "quote is <" << quote << ">");
if (quote != Symbols::DOUBLE_QUOTE[0] &&
quote != '\'')
{
InfoLog(<< "XML: badly quoted attribute value");
pb.fail(__FILE__, __LINE__);
}
anchor = pb.skipChar();
pb.skipToChar(quote);
pb.data(value, anchor);
XMLCursor::decode(value);
pb.skipChar();
mAttributes[attribute] = value;
}
pb.skipWhitespace();
}
}
return mAttributes;
}
const Data&
XMLCursor::getValue() const
{
if (atLeaf())
{
ParseBuffer pb(mCursor->mPb);
pb.skipToEnd();
mValue = pb.data(pb.start());
XMLCursor::decode(mValue);
}
else
{
mValue.clear();
}
return mValue;
}
std::ostream&
XMLCursor::encode(std::ostream& str, const AttributeMap& attrs)
{
for(AttributeMap::const_iterator i = attrs.begin();
i != attrs.end(); ++i)
{
if (i != attrs.begin())
{
str << " ";
}
// !dlb! some sort of character encoding required here
str << i->first << "=\"" << i->second << "\"";
}
return str;
}
XMLCursor::Node::Node(const ParseBuffer& pb)
: mPb(pb.position(), pb.end() - pb.position()),
mParent(0),
mChildren(),
mNext(mChildren.begin()),
mIsLeaf(false)
{
mPb.assertNotEof();
StackLog(<< "XMLCursor::Node::Node" << *this);
}
XMLCursor::Node::~Node()
{
for (vector<Node*>::iterator i = mChildren.begin();
i != mChildren.end(); ++i)
{
delete *i;
}
}
// start:
//<foo >
//^
// end:
//<foo >
// ^
bool
XMLCursor::Node::extractTag()
{
ParseBuffer pb(mPb);
const char* anchor = pb.skipChar();
static Data SLASH_RA_QUOTE("/>");
pb.skipToOneOf(ParseBuffer::Whitespace, SLASH_RA_QUOTE);
pb.assertNotEof();
pb.data(mTag, anchor);
return !pb.eof() && *pb.position() == Symbols::SLASH[0];
}
void
XMLCursor::Node::addChild(Node* child)
{
mChildren.push_back(child);
child->mParent = this;
}
//<foo> <bar> </bar> <baz> </baz> </foo>
//^start
// ^child
// ^child
// ^end
//
//<foo> sdfsf sadfsf <bar> asdfdf </bar> sadfsdf </foo>
//^start
// ^child
// ^child sub
// ^child
void
XMLCursor::Node::skipToEndTag()
{
extractTag();
StackLog(<< "XMLCursor::Node::skipToEndTag(" << mTag << ")");
//StackLog(<< "XMLCursor::Node::skipToEndTag(" << Data(mPb.position(), mPb.end() - mPb.position()) << ")");
//<foo />
mPb.skipToChar(Symbols::RA_QUOTE[0]);
if (*(mPb.position()-1) == Symbols::SLASH[0])
{
mPb.skipChar();
mPb = ParseBuffer(mPb.start(), mPb.position() - mPb.start());
return;
}
//<foo> ...<child> ... </child> </foo>
// ^
mPb.skipChar();
//<foo> ...<child> ... </child> </foo>
// ^
while (true)
{
if (!WhitespaceSignificant)
{
mPb.skipWhitespace();
}
// Some text contents ...<
// ^ ^
if (*mPb.position() != Symbols::LA_QUOTE[0])
{
const char* anchor = mPb.position();
mPb.skipToChar(Symbols::LA_QUOTE[0]);
Node* leaf = new Node(ParseBuffer(anchor, mPb.position() - anchor));
leaf->mIsLeaf = true;
addChild(leaf);
}
//<...
//^
mPb.skipChar();
//<...
// ^
// exit condition
//</foo>
if (*mPb.position() == Symbols::SLASH[0])
{
mPb.skipChar();
// CodeWarrior isn't helpful enough to pick the "obvious" operator definition
// so we add volatile here so CW is completely unconfused what to do.
// second note - MSVC 7.0 won't compile the volatile - tried the following to fix
const char* end = mPb.position();
if ( (const char*)mPb.end() < end + mTag.size() )
{
InfoLog(<< "XML: unexpected end");
mPb.fail(__FILE__, __LINE__);
}
if (strncmp(mTag.data(), mPb.position(), mTag.size()) == 0)
{
mPb.skipToChar(Symbols::RA_QUOTE[0]);
mPb.skipChar();
mPb = ParseBuffer(mPb.start(), mPb.position() - mPb.start());
return;
}
else
{
InfoLog(<< "Badly formed XML: unexpected endtag");
mPb.fail(__FILE__, __LINE__);
}
}
//<child>...
// ^
if (mPb.position() == mPb.start())
{
InfoLog(<< "XML: badly formed element");
mPb.fail(__FILE__, __LINE__);
}
mPb.reset(mPb.position()-1);
//<child>...
//^
Node* child = new Node(mPb);
addChild(child);
child->skipToEndTag();
mPb.reset(child->mPb.end());
XMLCursor::decodeName(child->mTag);
StackLog(<< mTag << "(" << child->mTag << ")");
}
}
//<!-- declarations for <head> & <body> -->
const char*
XMLCursor::Node::skipComments(ParseBuffer& pb)
{
while (*pb.position() == Symbols::LA_QUOTE[0] &&
*(pb.position()+1) == BANG[0] &&
*(pb.position()+2) == HYPHEN[0] &&
*(pb.position()+3) == HYPHEN[0])
{
pb.skipToChars(COMMENT_END);
pb.assertNotEof();
}
return pb.position();
}
std::ostream&
resip::operator<<(std::ostream& str, const XMLCursor::Node& node)
{
Data::size_type size = node.mPb.end() - node.mPb.start();
static const Data::size_type showSize(35);
str << &node << "["
<< Data(node.mPb.start(),
min(showSize, size))
<< "]" << (size ? "" : "...");
return str;
}
std::ostream&
resip::operator<<(std::ostream& str, const XMLCursor& cursor)
{
str << "XMLCursor " << *cursor.mCursor;
return str;
}
/* ====================================================================
* The Vovida Software License, Version 1.0
*
* Copyright (c) 2000 Vovida Networks, Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The names "VOCAL", "Vovida Open Communication Application Library",
* and "Vovida Open Communication Application Library (VOCAL)" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact vocal@vovida.org.
*
* 4. Products derived from this software may not be called "VOCAL", nor
* may "VOCAL" appear in their name, without prior written
* permission of Vovida Networks, Inc.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA
* NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES
* IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGE.
*
* ====================================================================
*
* This software consists of voluntary contributions made by Vovida
* Networks, Inc. and many individuals on behalf of Vovida Networks,
* Inc. For more information on Vovida Networks, Inc., please see
* <http://www.vovida.org/>.
*
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -