(file) Return to XmlParser.cpp CVS log (file) (dir) Up to [Pegasus] / pegasus / src / Pegasus / Common

Diff for /pegasus/src/Pegasus/Common/XmlParser.cpp between version 1.43.2.8 and 1.56

version 1.43.2.8, 2008/03/20 16:49:35 version 1.56, 2012/07/26 11:14:54
Line 1 
Line 1 
 //%2006////////////////////////////////////////////////////////////////////////  //%LICENSE////////////////////////////////////////////////////////////////
 // //
 // Copyright (c) 2000, 2001, 2002 BMC Software; Hewlett-Packard Development  // Licensed to The Open Group (TOG) under one or more contributor license
 // Company, L.P.; IBM Corp.; The Open Group; Tivoli Systems.  // agreements.  Refer to the OpenPegasusNOTICE.txt file distributed with
 // Copyright (c) 2003 BMC Software; Hewlett-Packard Development Company, L.P.;  // this work for additional information regarding copyright ownership.
 // IBM Corp.; EMC Corporation, The Open Group.  // Each contributor licenses this file to you under the OpenPegasus Open
 // Copyright (c) 2004 BMC Software; Hewlett-Packard Development Company, L.P.;  // Source License; you may not use this file except in compliance with the
 // IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group.  // License.
 // Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.;  //
 // EMC Corporation; VERITAS Software Corporation; The Open Group.  // Permission is hereby granted, free of charge, to any person obtaining a
 // Copyright (c) 2006 Hewlett-Packard Development Company, L.P.; IBM Corp.;  // copy of this software and associated documentation files (the "Software"),
 // EMC Corporation; Symantec Corporation; The Open Group.  // to deal in the Software without restriction, including without limitation
 //  // the rights to use, copy, modify, merge, publish, distribute, sublicense,
 // Permission is hereby granted, free of charge, to any person obtaining a copy  // and/or sell copies of the Software, and to permit persons to whom the
 // of this software and associated documentation files (the "Software"), to  // Software is furnished to do so, subject to the following conditions:
 // deal in the Software without restriction, including without limitation the  //
 // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or  // The above copyright notice and this permission notice shall be included
 // sell copies of the Software, and to permit persons to whom the Software is  // in all copies or substantial portions of the Software.
 // furnished to do so, subject to the following conditions:  //
 //  // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN  // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 // ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED  // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT  // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
 // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR  // CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT  // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN  // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION  
 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  
 // //
 //==============================================================================  //////////////////////////////////////////////////////////////////////////
 // //
 //%///////////////////////////////////////////////////////////////////////////// //%/////////////////////////////////////////////////////////////////////////////
  
Line 129 
Line 127 
     char replacement;     char replacement;
 }; };
  
 // ATTN: Add support for more entity references  
 static EntityReference _references[] =  
 {  
     { "&", 5, '&' },  
     { "&lt;", 4, '<' },  
     { "&gt;", 4, '>' },  
     { "&quot;", 6, '"' },  
     { "&apos;", 6, '\'' }  
 };  
   
   
 // Implements a check for a whitespace character, without calling // Implements a check for a whitespace character, without calling
 // isspace( ).  The isspace( ) function is locale-sensitive, // isspace( ).  The isspace( ) function is locale-sensitive,
 // and incorrectly flags some chars above 0x7f as whitespace.  This // and incorrectly flags some chars above 0x7f as whitespace.  This
Line 153 
Line 140 
     return CharSet::isXmlWhiteSpace((Uint8)c);     return CharSet::isXmlWhiteSpace((Uint8)c);
 } }
  
 static Uint32 _REFERENCES_SIZE = (sizeof(_references) / sizeof(_references[0]));  
  
 //////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
 // //
Line 179 
Line 165 
     "More than one root element was encountered",     "More than one root element was encountered",
     "Validation error",     "Validation error",
     "Semantic error",     "Semantic error",
     "Malformed namespace declaration",  
     "Namespace not supported",  
     "Namespace not declared"     "Namespace not declared"
 }; };
  
Line 202 
Line 186 
     "Common.XmlParser.MULTIPLE_ROOTS",     "Common.XmlParser.MULTIPLE_ROOTS",
     "Common.XmlParser.VALIDATION_ERROR",     "Common.XmlParser.VALIDATION_ERROR",
     "Common.XmlParser.SEMANTIC_ERROR",     "Common.XmlParser.SEMANTIC_ERROR",
     "Common.XmlParser.MALFORMED_NAMESPACE_DECL",  
     "Common.XmlParser.UNSUPPORTED_NAMESPACE",  
     "Common.XmlParser.UNDECLARED_NAMESPACE"     "Common.XmlParser.UNDECLARED_NAMESPACE"
 }; };
  
Line 214 
Line 196 
     const String& message)     const String& message)
 { {
     String dftMsg = _xmlMessages[Uint32(code) - 1];     String dftMsg = _xmlMessages[Uint32(code) - 1];
     String key = _xmlKeys[Uint32(code) - 1];      const char* key = _xmlKeys[Uint32(code) - 1];
     String msg = message;     String msg = message;
  
     dftMsg.append(": on line $0");     dftMsg.append(": on line $0");
Line 224 
Line 206 
         dftMsg.append("$1");         dftMsg.append("$1");
     }     }
  
     return MessageLoaderParms(key, dftMsg, line ,msg);      return MessageLoaderParms(key, dftMsg.getCString(), line ,msg);
 } }
  
 static MessageLoaderParms _formPartialMessage(Uint32 code, Uint32 line) static MessageLoaderParms _formPartialMessage(Uint32 code, Uint32 line)
 { {
     String dftMsg = _xmlMessages[Uint32(code) - 1];     String dftMsg = _xmlMessages[Uint32(code) - 1];
     String key = _xmlKeys[Uint32(code) - 1];      const char* key = _xmlKeys[Uint32(code) - 1];
  
     dftMsg.append(": on line $0");     dftMsg.append(": on line $0");
  
     return MessageLoaderParms(key, dftMsg, line);      return MessageLoaderParms(key, dftMsg.getCString(), line);
 } }
  
  
Line 312 
Line 294 
 // //
 //////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
  
 XmlParser::XmlParser(char* text, XmlNamespace* ns)  XmlParser::XmlParser(char* text, XmlNamespace* ns, Boolean hideEmptyTags)
     : _line(1),     : _line(1),
       _current(text),       _current(text),
       _restoreChar('\0'),       _restoreChar('\0'),
       _foundRoot(false),       _foundRoot(false),
       _scopeLevel(0),        _supportedNamespaces(ns),
       _supportedNamespaces(ns)        // Start valid indexes with -2. -1 is reserved for not found.
         _currentUnsupportedNSType(-2),
         _hideEmptyTags(hideEmptyTags)
 { {
 } }
  
Line 378 
Line 362 
 #pragma optimize( "", on ) #pragma optimize( "", on )
 #endif #endif
  
 static inline int _getCharRef(char*& p, bool hex)  static inline int _getCharRef(char*& p)
 { {
     char* end;     char* end;
     unsigned long ch;     unsigned long ch;
       Boolean hex = false;
  
     if (hex)      if (*p == 'x')
     {     {
         ch = strtoul(p, &end, 16);          hex = true;
           ch = strtoul(++p, &end, 16);
     }     }
     else     else
     {     {
Line 407 
Line 393 
     return ch;     return ch;
 } }
  
 static void _normalize(Uint32& line, char*& p, char end_char, char*& start)  // Parse an entity reference or a character reference
   static inline int _getRef(Uint32 line, char*& p)
 { {
     // Skip over leading whitespace:      int ch;
  
     _skipWhitespace(line, p);      if (*p == '#')
     start = p;      {
           ch = _getCharRef(++p);
       }
       else
       {
           ch = _getEntityRef(p);
       }
  
       if (ch == -1)
       {
           throw XmlException(XmlException::MALFORMED_REFERENCE, line);
       }
   
       return ch;
   }
   
   static inline void _normalizeElementValue(
       Uint32& line,
       char*& p,
       Uint32 &textLen)
   {
     // Process one character at a time:     // Process one character at a time:
  
     char* q = p;     char* q = p;
       char *start = p;
  
     while (*p && (*p != end_char))      while (*p && (*p != '<'))
     {     {
         if (_isspace(*p))         if (_isspace(*p))
         {         {
             // Compress sequences of whitespace characters to a single space              // Trim whitespace from the end of the value, but do not compress
             // character. Update line number when newlines encountered.              // whitespace within the value.
   
               const char* start = p;
  
             if (*p++ == '\n')             if (*p++ == '\n')
             {             {
                 line++;                 line++;
             }             }
  
             *q++ = ' ';  
   
             _skipWhitespace(line, p);             _skipWhitespace(line, p);
         }  
         else if (*p == '&')  
         {  
             // Process entity characters and entity references:  
  
             p++;              if (*p && (*p != '<'))
             int ch;  
   
             if (*p == '#')  
             {             {
                 *p++;                  // Transfer internal whitespace to q without compressing it.
                   const char* i = start;
                 if (*p == 'x')                  while (i < p)
                 {                 {
                     p++;                      *q++ = *i++;
                     ch = _getCharRef(p, true);                  }
                 }                 }
                 else                 else
                 {                 {
                     ch = _getCharRef(p, false);                  // Do not transfer trailing whitespace to q.
                   break;
               }
                 }                 }
           else if (*p == '&')
           {
               // Process an entity reference or a character reference.
   
               *q++ = _getRef(line, ++p);
             }             }
             else             else
             {             {
                 ch = _getEntityRef(p);              *q++ = *p++;
           }
             }             }
  
             if (ch == -1)      // If q got behind p, it is safe and necessary to null-terminate q
   
       if (q != p)
             {             {
                 throw XmlException(XmlException::MALFORMED_REFERENCE, line);          *q = '\0';
       }
       textLen = (Uint32)(q - start);
             }             }
  
             *q++ = ch;  static inline void _normalizeAttributeValue(
       Uint32& line,
       char*& p,
       char end_char,
       char*& start)
   {
       // Skip over leading whitespace:
   
       _skipWhitespace(line, p);
       start = p;
   
       // Process one character at a time:
   
       char* q = p;
   
       while (*p && (*p != end_char))
       {
           if (_isspace(*p))
           {
               // Compress sequences of whitespace characters to a single space
               // character. Update line number when newlines encountered.
   
               if (*p++ == '\n')
               {
                   line++;
               }
   
               *q++ = ' ';
   
               _skipWhitespace(line, p);
           }
           else if (*p == '&')
           {
               // Process an entity reference or a character reference.
   
               *q++ = _getRef(line, ++p);
         }         }
         else         else
         {         {
Line 473 
Line 520 
         }         }
     }     }
  
     // We encountered a the end_char or a zero-terminator.  
   
     *q = *p;  
   
     // Remove single trailing whitespace (consecutive whitespaces already     // Remove single trailing whitespace (consecutive whitespaces already
     // compressed above).  Since p >= q, we can tell if we need to strip a     // compressed above).  Since p >= q, we can tell if we need to strip a
     // trailing space from q by looking at the end of p.  We must not look at     // trailing space from q by looking at the end of p.  We must not look at
     // the last character of p, though, if p is an empty string.     // the last character of p, though, if p is an empty string.
       Boolean adjust_q = (p != start) && _isspace(p[-1]);
  
     if ((p != start) && _isspace(p[-1]))      // We encountered a the end_char or a zero-terminator.
   
       *q = *p;
   
       if (adjust_q)
     {     {
         q--;         q--;
     }     }
Line 495 
Line 543 
     }     }
 } }
  
 Boolean XmlParser::next(  Boolean XmlParser::_next(
     XmlEntry& entry,     XmlEntry& entry,
     Boolean includeComment)     Boolean includeComment)
 { {
     entry.attributes.clear();  
   
     if (!_putBackStack.isEmpty())     if (!_putBackStack.isEmpty())
     {     {
         entry = _putBackStack.top();         entry = _putBackStack.top();
Line 521 
Line 567 
         _restoreChar = '\0';         _restoreChar = '\0';
     }     }
  
       entry.attributes.clear();
   
       if (_supportedNamespaces)
       {
           // Remove namespaces of a deeper scope level from the stack.
           while (!_nameSpaces.isEmpty() &&
                  _nameSpaces.top().scopeLevel > _stack.size())
           {
               _nameSpaces.pop();
           }
       }
   
     // Loop until we are done with comments if includeComment is false.     // Loop until we are done with comments if includeComment is false.
     do     do
     {     {
Line 571 
Line 629 
         {         {
             // Normalize the content:             // Normalize the content:
  
             char* start;              char* start = _current;
             _normalize(_line, _current, '<', start);              Uint32 textLen;
               _normalizeElementValue(_line, _current, textLen);
  
             // Get the content:             // Get the content:
  
             entry.type = XmlEntry::CONTENT;             entry.type = XmlEntry::CONTENT;
             entry.text = start;             entry.text = start;
               entry.textLen = textLen;
  
             // Overwrite '<' with a null character (temporarily).             // Overwrite '<' with a null character (temporarily).
  
Line 594 
Line 654 
          entry.type == XmlEntry::EMPTY_TAG ||          entry.type == XmlEntry::EMPTY_TAG ||
          entry.type == XmlEntry::END_TAG))          entry.type == XmlEntry::END_TAG))
     {     {
         // Process attributes and enter namespaces into the table          // Determine the namespace type for this entry
   
         if (entry.type == XmlEntry::START_TAG ||         if (entry.type == XmlEntry::START_TAG ||
             entry.type == XmlEntry::EMPTY_TAG)             entry.type == XmlEntry::EMPTY_TAG)
         {         {
             _scopeLevel++;              // Process namespace declarations and determine the namespace type
             for (unsigned int i = 0; i < entry.attributes.size(); i++)              // for the attributes.
   
               Uint32 scopeLevel = _stack.size();
               if (entry.type == XmlEntry::EMPTY_TAG)
               {
                   // Empty tags are deeper scope, but not pushed onto the stack
                   scopeLevel++;
               }
   
               for (Uint32 i = 0, n = entry.attributes.size(); i < n; i++)
             {             {
                 XmlAttribute& attr = entry.attributes[i];                 XmlAttribute& attr = entry.attributes[i];
                 if (strncmp(attr.name, "xmlns", 5) == 0)                  if ((strncmp(attr.name, "xmlns:", 6) == 0) ||
                       (strcmp(attr.name, "xmlns") == 0))
                 {                 {
                       // Process a namespace declaration
                     XmlNamespace ns;                     XmlNamespace ns;
                     if (attr.name[5] == ':')                     if (attr.name[5] == ':')
                     {                     {
                         ns.localName = attr.name + 6;                          ns.localName = attr.localName;
   
                         // Check if we have malformed XML of the form:  
                         // "xmlns:=URI". In this case attr.name will be set  
                         // to "xmlns:" and ns.localName will point to '\0'  
                         if (ns.localName[0] == '\0')  
                         {  
                             throw XmlException(  
                                 XmlException::MALFORMED_NAMESPACE_DECL,  
                                 _line);  
                         }  
                     }                     }
                     else                     else
                     {                     {
Line 625 
Line 687 
                         ns.localName = 0;                         ns.localName = 0;
                     }                     }
                     ns.extendedName = attr.value;                     ns.extendedName = attr.value;
                     ns.scopeLevel = _scopeLevel;                      ns.scopeLevel = scopeLevel;
                     ns.type = getSupportedNamespaceType(ns.extendedName);                      ns.type = _getSupportedNamespaceType(ns.extendedName);
   
                       // If the namespace is not supported, assign it a unique
                       // negative identifier.
                       if (ns.type == -1)
                       {
                           ns.type = _currentUnsupportedNSType--;
                       }
  
                     // Even unsupported namespaces get pushed onto the stack.  
                     // We will throw an exception of there is an attempt to  
                     // reference an unsupported namespace later.  
                     _nameSpaces.push(ns);                     _nameSpaces.push(ns);
                 }                 }
                 else                 else
                 {                 {
                     // Attribute names may also be namespace qualified.                      // Get the namespace type for this attribute.
                     attr.nsType = _getNamespaceType(attr.name);                     attr.nsType = _getNamespaceType(attr.name);
                 }                 }
             }             }
         }         }
  
         // Get the namespace type for this tag.  
         entry.nsType = _getNamespaceType(entry.text);         entry.nsType = _getNamespaceType(entry.text);
       }
         if (entry.type == XmlEntry::END_TAG ||      else
             entry.type == XmlEntry::EMPTY_TAG)  
         {  
             // Remove any namespaces of the current scope level from  
             // the scope stack.  
             while (!_nameSpaces.isEmpty() &&  
                    _scopeLevel <= _nameSpaces.top().scopeLevel)  
             {             {
                 _nameSpaces.pop();          entry.nsType = -1;
             }             }
  
             PEGASUS_ASSERT(_scopeLevel > 0);      return true;
             _scopeLevel--;  
         }  
     }     }
     else  
   Boolean XmlParser::next(XmlEntry& entry, Boolean includeComment)
     {     {
         entry.nsType = -1;      if (_hideEmptyTags)
       {
           // Get the next tag.
   
           if (!_next(entry, includeComment))
               return false;
   
           // If an EMPTY_TAG is encountered, then convert it to a START_TAG and
           // push a matching END_TAG on the put-back stack. This hides every
           // EMPTY_TAG from the caller.
   
           if (entry.type == XmlEntry::EMPTY_TAG)
           {
               entry.type = XmlEntry::START_TAG;
   
               XmlEntry tmp;
               tmp.type = XmlEntry::END_TAG;
               tmp.text = entry.text;
               tmp.nsType = entry.nsType;
               tmp.localName = entry.localName;
   
               _putBackStack.push(tmp);
     }     }
  
     return true;     return true;
 } }
       else
           return _next(entry, includeComment);
   }
  
 // Get the namespace type of the given tag // Get the namespace type of the given tag
 int XmlParser::_getNamespaceType(const char* tag) int XmlParser::_getNamespaceType(const char* tag)
 { {
     const char* pos = strchr(tag, ':');     const char* pos = strchr(tag, ':');
  
     // If ":" is not found, the tag is not namespace qualified and we      // If ':' is not found, the tag is not namespace qualified and we
     // need to look for the default name space.     // need to look for the default name space.
  
     // Search the namespace stack from the top     // Search the namespace stack from the top
     for (int i = _nameSpaces.size() - 1; i >=0; i--)      for (Sint32 i = _nameSpaces.size() - 1; i >=0; i--)
     {     {
         // If ":" is found, look for the name space with the matching          // If ':' is found, look for the name space with the matching
         // local name...         // local name...
         if ((pos && _nameSpaces[i].localName &&         if ((pos && _nameSpaces[i].localName &&
              !strncmp(_nameSpaces[i].localName, tag, pos - tag)) ||              !strncmp(_nameSpaces[i].localName, tag, pos - tag)) ||
Line 686 
Line 768 
             // one with localName set to NULL             // one with localName set to NULL
             (!pos && !_nameSpaces[i].localName))             (!pos && !_nameSpaces[i].localName))
         {         {
             // If it's a reference to an unsupported namespace,  
             // throw an exception  
             if (_nameSpaces[i].type == -1)  
             {  
                 throw XmlException(XmlException::UNSUPPORTED_NAMESPACE, _line);  
             }  
             return _nameSpaces[i].type;             return _nameSpaces[i].type;
         }         }
     }     }
Line 709 
Line 785 
     return -1;     return -1;
 } }
  
 // Gived the extended namespace name, find it in the table of supported  // Given the extended namespace name, find it in the table of supported
 // namespaces and return its type. // namespaces and return its type.
 int XmlParser::getSupportedNamespaceType(const char* extendedName)  int XmlParser::_getSupportedNamespaceType(const char* extendedName)
 { {
     for (int i = 0;      for (Sint32 i = 0;
          _supportedNamespaces[i].localName != 0;          _supportedNamespaces[i].localName != 0;
          i++)          i++)
     {     {
Line 728 
Line 804 
  
 XmlNamespace* XmlParser::getNamespace(int nsType) XmlNamespace* XmlParser::getNamespace(int nsType)
 { {
     for (int i = _nameSpaces.size() - 1; i >=0; i--)      for (Sint32 i = _nameSpaces.size() - 1; i >=0; i--)
     {     {
         if (_nameSpaces[i].type == nsType)         if (_nameSpaces[i].type == nsType)
         {         {
Line 748 
Line 824 
     // Nothing to do!     // Nothing to do!
 } }
  
 // A-Za-z0-9_-:.  // A-Za-z0-9_-.  (Note that ':' is not included and must be checked separately)
 static unsigned char _isInnerElementChar[] = static unsigned char _isInnerElementChar[] =
 { {
     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
     0,0,0,0,0,0,0,0,1,1,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,      0,0,0,0,0,0,0,0,1,1,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,
     1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,     1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
     1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,     1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 }; };
  
 Boolean XmlParser::_getElementName(char*& p)  inline Boolean _getQName(char*& p, const char*& localName)
 { {
       localName = p;
   
     if (!CharSet::isAlNumUnder(Uint8(*p)))     if (!CharSet::isAlNumUnder(Uint8(*p)))
         throw XmlException(XmlException::BAD_START_TAG, _line);          return false;
  
     p++;     p++;
  
     while (*p && _isInnerElementChar[Uint8(*p)])      // No explicit test for NULL termination is needed.
       // On position 0 of the array false is returned.
       while (_isInnerElementChar[Uint8(*p)])
         p++;         p++;
  
       // We've validated the prefix, now validate the local name
       if (*p == ':')
       {
           localName = ++p;
   
           if (!CharSet::isAlNumUnder(Uint8(*p)))
               return false;
   
           p++;
           // No explicit test for NULL termination is needed.
           // On position 0 of the array false is returned.
           while (_isInnerElementChar[Uint8(*p)])
               p++;
       }
   
       return true;
   }
   
   Boolean XmlParser::_getElementName(char*& p, const char*& localName)
   {
       if (!_getQName(p, localName))
           throw XmlException(XmlException::BAD_START_TAG, _line);
   
     // The next character must be a space:     // The next character must be a space:
  
     if (_isspace(*p))     if (_isspace(*p))
Line 787 
Line 890 
     return false;     return false;
 } }
  
 Boolean XmlParser::_getOpenElementName(char*& p, Boolean& openCloseElement)  Boolean XmlParser::_getOpenElementName(
       char*& p,
       const char*& localName,
       Boolean& openCloseElement)
 { {
     openCloseElement = false;     openCloseElement = false;
  
     if (!CharSet::isAlNumUnder(Uint8(*p)))      if (!_getQName(p, localName))
         throw XmlException(XmlException::BAD_START_TAG, _line);         throw XmlException(XmlException::BAD_START_TAG, _line);
  
     p++;  
   
     while (*p && _isInnerElementChar[Uint8(*p)])  
         p++;  
   
     // The next character must be a space:     // The next character must be a space:
  
     if (_isspace(*p))     if (_isspace(*p))
Line 824 
Line 925 
     return false;     return false;
 } }
  
 void XmlParser::_getAttributeNameAndEqual(char*& p)  void XmlParser::_getAttributeNameAndEqual(char*& p, const char*& localName)
 { {
     if (!CharSet::isAlNumUnder((Uint8)*p))      if (!_getQName(p, localName))
         throw XmlException(XmlException::BAD_ATTRIBUTE_NAME, _line);         throw XmlException(XmlException::BAD_ATTRIBUTE_NAME, _line);
  
     p++;  
   
     while (*p && _isInnerElementChar[Uint8(*p)])  
         p++;  
   
     char* term = p;     char* term = p;
  
     _skipWhitespace(_line, p);     _skipWhitespace(_line, p);
Line 923 
Line 1019 
         entry.type = XmlEntry::XML_DECLARATION;         entry.type = XmlEntry::XML_DECLARATION;
         entry.text = ++p;         entry.text = ++p;
  
         Boolean openCloseElement = false;          if (_getElementName(p, entry.localName))
   
         if (_getElementName(p))  
             return;             return;
     }     }
     else if (*p == '!')     else if (*p == '!')
Line 948 
Line 1042 
             entry.type = XmlEntry::CDATA;             entry.type = XmlEntry::CDATA;
             entry.text = p;             entry.text = p;
             _getCData(p);             _getCData(p);
               entry.textLen = strlen(entry.text);
             return;             return;
         }         }
         else if (memcmp(p, "DOCTYPE", 7) == 0)         else if (memcmp(p, "DOCTYPE", 7) == 0)
Line 964 
Line 1059 
         entry.type = XmlEntry::END_TAG;         entry.type = XmlEntry::END_TAG;
         entry.text = ++p;         entry.text = ++p;
  
         if (!_getElementName(p))          if (!_getElementName(p, entry.localName))
             throw(XmlException(XmlException::BAD_END_TAG, _line));             throw(XmlException(XmlException::BAD_END_TAG, _line));
  
         return;         return;
     }     }
     else if ((((*p >= 'A') && (*p <= 'Z')) ||      else if (CharSet::isAlphaUnder(Uint8(*p)))
               ((*p >= 'a') && (*p <= 'z')) ||  
               (*p == '_')))  
     {     {
         entry.type = XmlEntry::START_TAG;         entry.type = XmlEntry::START_TAG;
         entry.text = p;         entry.text = p;
  
         Boolean openCloseElement = false;         Boolean openCloseElement = false;
  
         if (_getOpenElementName(p, openCloseElement))          if (_getOpenElementName(p, entry.localName, openCloseElement))
         {         {
             if (openCloseElement)             if (openCloseElement)
                 entry.type = XmlEntry::EMPTY_TAG;                 entry.type = XmlEntry::EMPTY_TAG;
Line 1017 
Line 1110 
         XmlAttribute attr;         XmlAttribute attr;
         attr.nsType = -1;         attr.nsType = -1;
         attr.name = p;         attr.name = p;
         _getAttributeNameAndEqual(p);          _getAttributeNameAndEqual(p, attr.localName);
  
         // Get the attribute value (e.g., "some value")         // Get the attribute value (e.g., "some value")
         {         {
Line 1029 
Line 1122 
             char quote = *p++;             char quote = *p++;
  
             char* start;             char* start;
             _normalize(_line, p, quote, start);              _normalizeAttributeValue(_line, p, quote, start);
             attr.value = start;             attr.value = start;
  
             if (*p != quote)             if (*p != quote)
Line 1077 
Line 1170 
     "CONTENT"     "CONTENT"
 }; };
  
 const char* XmlEntry::getUnqualifiedName() const  
 {  
     PEGASUS_ASSERT(  
         (type == XmlEntry::START_TAG) ||  
         (type == XmlEntry::EMPTY_TAG) ||  
         (type == XmlEntry::END_TAG));  
   
     const char* colonPos = strchr(text, ':');  
     if (colonPos == NULL)  
     {  
         return text;  
     }  
   
     return colonPos + 1;  
 }  
   
 void XmlEntry::print() const void XmlEntry::print() const
 { {
     PEGASUS_STD(cout) << "=== " << _typeStrings[type] << " ";     PEGASUS_STD(cout) << "=== " << _typeStrings[type] << " ";
Line 1109 
Line 1186 
  
     PEGASUS_STD(cout) << '\n';     PEGASUS_STD(cout) << '\n';
  
     for (Uint32 i = 0; i < attributes.size(); i++)      for (Uint32 i = 0, n = attributes.size(); i < n; i++)
     {     {
         PEGASUS_STD(cout) << "    " << attributes[i].name << "=\"";         PEGASUS_STD(cout) << "    " << attributes[i].name << "=\"";
         _printValue(attributes[i].value);         _printValue(attributes[i].value);
Line 1120 
Line 1197 
 const XmlAttribute* XmlEntry::findAttribute( const XmlAttribute* XmlEntry::findAttribute(
     const char* name) const     const char* name) const
 { {
     for (Uint32 i = 0; i < attributes.size(); i++)      for (Uint32 i = 0, n = attributes.size(); i < n; i++)
     {     {
         if (strcmp(attributes[i].name, name) == 0)         if (strcmp(attributes[i].name, name) == 0)
             return &attributes[i];             return &attributes[i];
Line 1130 
Line 1207 
 } }
  
 const XmlAttribute* XmlEntry::findAttribute( const XmlAttribute* XmlEntry::findAttribute(
     int nsType,      int attrNsType,
     const char* name) const     const char* name) const
 { {
     for (Uint32 i = 0; i < attributes.size(); i++)      for (Uint32 i = 0, n = attributes.size(); i < n; i++)
     {     {
         if ((attributes[i].nsType == nsType) &&          if ((attributes[i].nsType == attrNsType) &&
             (strcmp(attributes[i].name, name) == 0))              (strcmp(attributes[i].localName, name) == 0))
         {         {
             return &attributes[i];             return &attributes[i];
         }         }


Legend:
Removed from v.1.43.2.8  
changed lines
  Added in v.1.56

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2