reSIProcate/stack  9373
Public Member Functions | Static Public Member Functions | Public Attributes | Private Member Functions | Friends
resip::XMLCursor::Node Class Reference

#include <XMLCursor.hxx>

Collaboration diagram for resip::XMLCursor::Node:
Collaboration graph
[legend]

List of all members.

Public Member Functions

 Node (const ParseBuffer &pb)
 ~Node ()
void addChild (Node *)
bool extractTag ()
void skipToEndTag ()

Static Public Member Functions

static const char * skipComments (ParseBuffer &pb)

Public Attributes

ParseBuffer mPb
NodemParent
std::vector< Node * > mChildren
std::vector< Node * >
::const_iterator 
mNext
bool mIsLeaf
Data mTag

Private Member Functions

 Node (const Node &)
Nodeoperator= (const Node &)

Friends

EncodeStreamoperator<< (EncodeStream &str, const XMLCursor &cursor)

Detailed Description

Definition at line 155 of file XMLCursor.hxx.


Constructor & Destructor Documentation

XMLCursor::Node::Node ( const ParseBuffer pb)

Definition at line 438 of file XMLCursor.cxx.

References resip::ParseBuffer::assertNotEof(), mPb, and StackLog.

   : mPb(pb.position(), pb.end() - pb.position()),
     mParent(0),
     mChildren(),
     mNext(mChildren.begin()),
     mIsLeaf(false)
{
   mPb.assertNotEof();
   StackLog(<< "XMLCursor::Node::Node" << *this);
}

Here is the call graph for this function:

XMLCursor::Node::~Node ( )

Definition at line 449 of file XMLCursor.cxx.

{
   for (vector<Node*>::iterator i = mChildren.begin();
        i != mChildren.end(); ++i)
   {
      delete *i;
   }
}
resip::XMLCursor::Node::Node ( const Node ) [private]

Member Function Documentation

void XMLCursor::Node::addChild ( Node child)

Definition at line 478 of file XMLCursor.cxx.

References mParent.

Referenced by resip::XMLCursor::parseNextRootChild().

{
   mChildren.push_back(child);
   child->mParent = this;
}
bool XMLCursor::Node::extractTag ( )

Definition at line 466 of file XMLCursor.cxx.

References resip::ParseBuffer::assertNotEof(), resip::ParseBuffer::data(), resip::ParseBuffer::eof(), resip::XMLCursor::mTag, resip::ParseBuffer::position(), resip::ParseBuffer::skipChar(), resip::ParseBuffer::skipToOneOf(), resip::Symbols::SLASH, SLASH_RA_QUOTE, and resip::ParseBuffer::Whitespace.

Referenced by resip::XMLCursor::XMLCursor().

{
   ParseBuffer pb(mPb);
   const char* anchor = pb.skipChar();
   pb.skipToOneOf(ParseBuffer::Whitespace, SLASH_RA_QUOTE);
   pb.assertNotEof();
   pb.data(mTag, anchor);

   return !pb.eof() && *pb.position() == Symbols::SLASH[0];
}

Here is the call graph for this function:

Node& resip::XMLCursor::Node::operator= ( const Node ) [private]
const char * XMLCursor::Node::skipComments ( ParseBuffer pb) [static]

Definition at line 591 of file XMLCursor.cxx.

References BANG, COMMENT_END, resip::ParseBuffer::end(), resip::ParseBuffer::eof(), HYPHEN, resip::Symbols::LA_QUOTE, resip::ParseBuffer::position(), resip::ParseBuffer::skipChars(), resip::ParseBuffer::skipToChars(), and resip::ParseBuffer::skipWhitespace().

Referenced by resip::XMLCursor::XMLCursor().

{
   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.skipChars(COMMENT_END);
      pb.skipWhitespace();
      if(pb.eof())
      {
         return pb.end();
      }
   }

   return pb.position();
}

Here is the call graph for this function:

void XMLCursor::Node::skipToEndTag ( )

Definition at line 496 of file XMLCursor.cxx.

References resip::Data::data(), resip::XMLCursor::decodeName(), resip::ParseBuffer::end(), InfoLog, resip::Symbols::LA_QUOTE, mIsLeaf, mPb, resip::XMLCursor::mTag, mTag, resip::XMLCursor::Node, resip::Symbols::RA_QUOTE, resip::Data::size(), resip::ParseBuffer::skipChar(), skipToEndTag(), resip::Symbols::SLASH, StackLog, and resip::XMLCursor::WhitespaceSignificant.

Referenced by resip::XMLCursor::parseNextRootChild(), and 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 << ")");
    }
}

Here is the call graph for this function:


Friends And Related Function Documentation

EncodeStream& operator<< ( EncodeStream str,
const XMLCursor cursor 
) [friend]

Member Data Documentation

std::vector<Node*>::const_iterator resip::XMLCursor::Node::mNext

The documentation for this class was generated from the following files: