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

Diff for /pegasus/src/Pegasus/Common/CIMObjectPath.cpp between version 1.29 and 1.43.2.1

version 1.29, 2003/09/19 19:56:26 version 1.43.2.1, 2005/03/29 19:35:20
Line 1 
Line 1 
 //%/////////////////////////////////////////////////////////////////////////////  //%2004////////////////////////////////////////////////////////////////////////
 // //
 // Copyright (c) 2000, 2001, 2002 BMC Software, Hewlett-Packard Company, IBM,  // Copyright (c) 2000, 2001, 2002 BMC Software; Hewlett-Packard Development
 // The Open Group, Tivoli Systems  // Company, L.P.; IBM Corp.; The Open Group; Tivoli Systems.
   // Copyright (c) 2003 BMC Software; Hewlett-Packard Development Company, L.P.;
   // IBM Corp.; EMC Corporation, The Open Group.
   // Copyright (c) 2004 BMC Software; 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 copy // Permission is hereby granted, free of charge, to any person obtaining a copy
 // of this software and associated documentation files (the "Software"), to // of this software and associated documentation files (the "Software"), to
Line 26 
Line 30 
 // Modified By: Roger Kumpf, Hewlett-Packard Company (roger_kumpf@hp.com) // Modified By: Roger Kumpf, Hewlett-Packard Company (roger_kumpf@hp.com)
 //              Carol Ann Krug Graves, Hewlett-Packard Company //              Carol Ann Krug Graves, Hewlett-Packard Company
 //                (carolann_graves@hp.com) //                (carolann_graves@hp.com)
   //              Dave Sudlik, IBM (dsudlik@us.ibm.com) for Bug#1462
 // //
 //%///////////////////////////////////////////////////////////////////////////// //%/////////////////////////////////////////////////////////////////////////////
  
Line 41 
Line 46 
 #include "XmlWriter.h" #include "XmlWriter.h"
 #include "XmlReader.h" #include "XmlReader.h"
 #include "ArrayInternal.h" #include "ArrayInternal.h"
 #include "CIMOMPort.h"  
  
 PEGASUS_NAMESPACE_BEGIN PEGASUS_NAMESPACE_BEGIN
  
Line 314 
Line 318 
  
 Boolean operator==(const CIMKeyBinding& x, const CIMKeyBinding& y) Boolean operator==(const CIMKeyBinding& x, const CIMKeyBinding& y)
 { {
     return      // Check that the names and types match
         x.getName().equal(y.getName()) &&      if (!(x.getName().equal(y.getName())) ||
         String::equal(x.getValue(), y.getValue()) &&          !(x.getType() == y.getType()))
         x.getType() == y.getType();      {
           return false;
       }
   
       switch (x.getType())
       {
       case CIMKeyBinding::REFERENCE:
           try
           {
               // References should be compared as CIMObjectPaths
               return (CIMObjectPath(x.getValue()) == CIMObjectPath(y.getValue()));
           }
           catch (Exception&)
           {
               // If CIMObjectPath parsing fails, just compare strings
               return (String::equal(x.getValue(), y.getValue()));
           }
           break;
       case CIMKeyBinding::BOOLEAN:
           // Case-insensitive comparison is sufficient for booleans
           return (String::equalNoCase(x.getValue(), y.getValue()));
           break;
       case CIMKeyBinding::NUMERIC:
           // Note: This comparison assumes XML syntax for integers
           // First try comparing as unsigned integers
           {
               Uint64 xValue;
               Uint64 yValue;
               if (XmlReader::stringToUnsignedInteger(
                       x.getValue().getCString(), xValue) &&
                   XmlReader::stringToUnsignedInteger(
                       y.getValue().getCString(), yValue))
               {
                   return (xValue == yValue);
               }
           }
           // Next try comparing as signed integers
           {
               Sint64 xValue;
               Sint64 yValue;
               if (XmlReader::stringToSignedInteger(
                       x.getValue().getCString(), xValue) &&
                   XmlReader::stringToSignedInteger(
                       y.getValue().getCString(), yValue))
               {
                   return (xValue == yValue);
               }
           }
           // Note: Keys may not be real values, so don't try comparing as reals
           // We couldn't parse the numbers, so just compare the strings
           return (String::equal(x.getValue(), y.getValue()));
           break;
       default:  // CIMKeyBinding::STRING
           return (String::equal(x.getValue(), y.getValue()));
           break;
       }
   
       PEGASUS_UNREACHABLE(return false;)
 } }
  
  
Line 366 
Line 427 
         return *this;         return *this;
     }     }
  
       static Boolean isValidHostname(const String& hostname)
       {
           //------------------------------------------------------------------
           // Validate the hostname.  The hostname value may or may not be a
           // fully-qualified domain name (e.g., xyz.company.com) or may be an
           // IP address.  A port number may follow the hostname.
           // Hostnames must match one of the following regular expressions:
           // ^([A-Za-z0-9][A-Za-z0-9-]*)(\.[A-Za-z][A-Za-z0-9-]*)*(:[0-9]*)?$
           // ^([0-9]*\.[0-9]*\.[0-9]*\.[0-9]*)(:[0-9]*)?$
           // Note for Bug#1462. Be careful here, from RFC 1123:
           // - The syntax of a legal Internet host name was specified in
           //   RFC-952 [DNS:4]. One aspect of host name syntax is hereby
           //   changed: the restriction on the first character is relaxed to
           //   allow either a letter or a digit.
           // - If a dotted-decimal number can be entered without identifying
           //   delimiters, then a full syntactic check must be made, because
           //   a segment of a host domain name is now allowed to begin with a
           //   digit and could legally be entirely numeric (see Section 6.1.2.4).
           //   However, a valid host name can never have the dotted-decimal form
           //   #.#.#.#, since at least the highest-level component label will be
           //   alphabetic.
           // The algorithm below has been updated accordingly.
           //------------------------------------------------------------------
   
           Uint32 i = 0;
   
           Boolean isValid = false;
   
           if (isdigit(hostname[0]))
           {
               //--------------------------------------------------------------
               // Attempt to validate an IP address, but keep in mind that it
               // might be a host name, since the leading character can now be
               // a digit.
               //--------------------------------------------------------------
               isValid = true;
   
               for (Uint32 octet=1; octet<=4; octet++)
               {
                   Uint32 octetValue = 0;
   
                   //----------------------------------------------------------
                   // If a non-digit is encountered in the input parameter,
                   // then break from here and attempt to validate as host name.
                   //----------------------------------------------------------
                   if (!isdigit(hostname[i]))
                   {
                       isValid = false;
                       break;
                   }
   
                   while (isdigit(hostname[i]))  // skip over digits
                   {
                       octetValue = octetValue*10 + (hostname[i] - '0');
                       i++;
                   }
   
                   if (octetValue > 255)
                   {
                       isValid = false;
                       break;
                   }
   
                   // Check for invalid character in IP address
                   if ((octet != 4) && (hostname[i++] != '.'))
                   {
                       isValid = false;
                       break;
                   }
   
                   // Check for the case where it's a valid host name that happens
                   // to have 4 (or more) leading all-numeric host segments.
                   if ((octet == 4) && (hostname[i] != ':') && hostname[i] != char(0))
                   {
                       isValid = false;
                       break;
                   }
               }
           }
           if (!isValid)   // if it is not a valid IP address
           {
               i = 0;  // reset index for host name check
   
               // Validate a host name
               isValid = true;
   
               Boolean expectHostSegment = true;
               Boolean hostSegmentIsNumeric;
   
               while (expectHostSegment == true)
               {
                   expectHostSegment = false;
                   hostSegmentIsNumeric = true; // assume all-numeric host segment
   
                   if (!isalnum(hostname[i]))
                   {
                       return false;
                   }
   
                   while (isalnum(hostname[i]) || (hostname[i] == '-'))
                   {
                       // If a non-digit is encountered, set "all-numeric"
                       // flag to false
                       if (isalpha(hostname[i]) || (hostname[i] == '-')) {
                           hostSegmentIsNumeric = false;
                       }
                       i++;
                   }
   
                   if (hostname[i] == '.')
                   {
                       i++;
                       expectHostSegment = true;
                   }
               }
               // If the last Host Segment is all numeric, then return false.
               // RFC 1123 says "highest-level component label will be alphabetic".
               if (hostSegmentIsNumeric) {
                   return false;
               }
           }
   
           if (!isValid) // if not a valid IP address or host name
           {
               return false;
           }
   
           // Check for a port number:
   
           if (hostname[i] == ':')
           {
               if (!isdigit(hostname[++i]))
               {
                   return false;
               }
   
               while (isdigit(hostname[++i]));
           }
   
           return (hostname[i] == char(0));
       }
   
     //     //
     // Contains port as well (e.g., myhost:1234).     // Contains port as well (e.g., myhost:1234).
     //     //
Line 446 
Line 649 
     String& host)     String& host)
 { {
     // See if there is a host name (true if it begins with "//"):     // See if there is a host name (true if it begins with "//"):
     // Host is of the from <hostname>-<port> and begins with "//"      // Host is of the form <hostname>:<port> and begins with "//"
     // and ends with "/":     // and ends with "/":
  
     if (p[0] != '/' || p[1] != '/')     if (p[0] != '/' || p[1] != '/')
Line 456 
Line 659 
  
     p += 2;     p += 2;
  
     //----------------------------------------------------------------------      char* slash = strchr(p, '/');
     // Validate the hostname. A domain is allowed after the hostname.      if (!slash)
     // Eg. xyz.company.com  
     // Hostnames must match the following regular expression:  
     // ^([A-Za-z][A-Za-z0-9-]*)(\.[A-Za-z][A-Za-z0-9-]*)*$  
     //----------------------------------------------------------------------  
   
     char* q = p;  
   
     Boolean foundDot = true;  
     while (foundDot == true)  
     {     {
         foundDot = false;  
   
         if (!isalpha(*q))  
             throw MalformedObjectNameException(objectName);             throw MalformedObjectNameException(objectName);
   
         q++;  
   
         while (isalnum(*q) || *q == '-')  
         {  
             q++;  
         }         }
  
         if (*q == '.')      String hostname = String(p, (Uint32)(slash - p));
         {      if (!CIMObjectPathRep::isValidHostname(hostname))
             q++;  
             foundDot = true;  
         }  
      }  
   
     // We now expect a port (or default the port).  
   
     if (*q == ':')  
     {     {
         q++;  
         // Check for a port number:  
   
         if (!isdigit(*q))  
             throw MalformedObjectNameException(objectName);             throw MalformedObjectNameException(objectName);
   
         while (isdigit(*q))  
             q++;  
   
         // Finally, assign the host name:  
   
         host.assign(p, q - p);  
     }     }
     else      host = hostname;
     {  
         host.assign(p, q - p);  
  
         // Assign the default port number:      // Do not step past the '/'; it will be consumed by the namespace parser
       p = slash;
         host.append(":");  
         host.append(PEGASUS_CIMOM_DEFAULT_PORT_STRING);  
     }  
   
     // Check for slash terminating the entire sequence:  
   
     if (*q != '/')  
     {  
         host.clear();  
         throw MalformedObjectNameException(objectName);  
     }  
   
     p = ++q;  
  
     return true;     return true;
 } }
Line 657 
Line 808 
                     type = CIMKeyBinding::REFERENCE;                     type = CIMKeyBinding::REFERENCE;
                 }                 }
             }             }
             catch (Exception & e)              catch (const Exception &)
             {             {
                 // Not a reference value; leave type as STRING                 // Not a reference value; leave type as STRING
             }             }
Line 747 
Line 898 
  
     // Convert to a C String first:     // Convert to a C String first:
  
     CString pCString = objectName.getCStringUTF8();      CString pCString = objectName.getCString();
     char* p = const_cast<char*>((const char*) pCString);     char* p = const_cast<char*>((const char*) pCString);
     Boolean gotHost;     Boolean gotHost;
     Boolean gotNamespace;     Boolean gotNamespace;
Line 805 
Line 956 
  
 void CIMObjectPath::setHost(const String& host) void CIMObjectPath::setHost(const String& host)
 { {
       if ((host != String::EMPTY) && !CIMObjectPathRep::isValidHostname(host))
       {
           throw MalformedObjectNameException(host);
       }
   
     _rep->_host = host;     _rep->_host = host;
 } }
  
Line 908 
Line 1064 
 { {
     CIMObjectPath ref = *this;     CIMObjectPath ref = *this;
  
     // ATTN-RK-P2-20020510: Need to make hostname and namespace lower case?      // Normalize hostname by changing to lower case
       ref._rep->_host.toLower(); // ICU_TODO:
   
       // Normalize namespace by changing to lower case
       if (!ref._rep->_nameSpace.isNull())
       {
           String nameSpaceLower = ref._rep->_nameSpace.getString();
           nameSpaceLower.toLower(); // ICU_TODO:
           ref._rep->_nameSpace = nameSpaceLower;
       }
  
       // Normalize class name by changing to lower case
       if (!ref._rep->_className.isNull())
       {
     String classNameLower = ref._rep->_className.getString ();     String classNameLower = ref._rep->_className.getString ();
     classNameLower.toLower(); // ICU_TODO:     classNameLower.toLower(); // ICU_TODO:
     ref._rep->_className = classNameLower;     ref._rep->_className = classNameLower;
       }
  
     for (Uint32 i = 0, n = ref._rep->_keyBindings.size(); i < n; i++)     for (Uint32 i = 0, n = ref._rep->_keyBindings.size(); i < n; i++)
     {     {
           // Normalize key binding name by changing to lower case
           if (!ref._rep->_keyBindings[i]._rep->_name.isNull())
           {
         String keyBindingNameLower =         String keyBindingNameLower =
             ref._rep->_keyBindings[i]._rep->_name.getString ();             ref._rep->_keyBindings[i]._rep->_name.getString ();
         keyBindingNameLower.toLower();              keyBindingNameLower.toLower(); // ICU_TODO:
         ref._rep->_keyBindings[i]._rep->_name = keyBindingNameLower;         ref._rep->_keyBindings[i]._rep->_name = keyBindingNameLower;
     }     }
  
     // ATTN-RK-20020826: Need to sort keys?          // Normalize the key value
           switch (ref._rep->_keyBindings[i]._rep->_type)
           {
           case CIMKeyBinding::REFERENCE:
               try
               {
                   // Convert reference to CIMObjectPath and recurse
                   ref._rep->_keyBindings[i]._rep->_value =
                       CIMObjectPath(ref._rep->_keyBindings[i]._rep->_value).
                           _toStringCanonical();
               }
               catch (Exception&)
               {
                   // Leave value unchanged if the CIMObjectPath parsing fails
               }
               break;
           case CIMKeyBinding::BOOLEAN:
               // Normalize the boolean string by changing to lower case
               ref._rep->_keyBindings[i]._rep->_value.toLower(); // ICU_TODO:
               break;
           case CIMKeyBinding::NUMERIC:
               // Normalize the numeric string by converting to integer and back
               Uint64 uValue;
               Sint64 sValue;
               // First try converting to unsigned integer
               if (XmlReader::stringToUnsignedInteger(
                       ref._rep->_keyBindings[i]._rep->_value.getCString(),
                           uValue))
               {
                   char buffer[32];  // Should need 21 chars max
                   sprintf(buffer, "%" PEGASUS_64BIT_CONVERSION_WIDTH "u", uValue);
                   ref._rep->_keyBindings[i]._rep->_value = String(buffer);
               }
               // Next try converting to signed integer
               else if (XmlReader::stringToSignedInteger(
                            ref._rep->_keyBindings[i]._rep->_value.getCString(),
                                sValue))
               {
                   char buffer[32];  // Should need 21 chars max
                   sprintf(buffer, "%" PEGASUS_64BIT_CONVERSION_WIDTH "d", sValue);
                   ref._rep->_keyBindings[i]._rep->_value = String(buffer);
               }
               // Leave value unchanged if it cannot be converted to an integer
               break;
           default:  // CIMKeyBinding::STRING
               // No normalization required for STRING
               break;
           }
       }
   
       // Note: key bindings are sorted when set in the CIMObjectPath
  
     return ref.toString();     return ref.toString();
 } }
Line 930 
Line 1152 
 Boolean CIMObjectPath::identical(const CIMObjectPath& x) const Boolean CIMObjectPath::identical(const CIMObjectPath& x) const
 { {
     return     return
         String::equal(_rep->_host, x._rep->_host) &&          String::equalNoCase(_rep->_host, x._rep->_host) &&
         _rep->_nameSpace.equal(x._rep->_nameSpace) &&         _rep->_nameSpace.equal(x._rep->_nameSpace) &&
         _rep->_className.equal(x._rep->_className) &&         _rep->_className.equal(x._rep->_className) &&
         _rep->_keyBindings == x._rep->_keyBindings;         _rep->_keyBindings == x._rep->_keyBindings;
Line 951 
Line 1173 
     return !operator==(x, y);     return !operator==(x, y);
 } }
  
 #ifndef PEGASUS_REMOVE_DEPRECATED  
 PEGASUS_STD(ostream)& operator<<(  
     PEGASUS_STD(ostream)& os,  
     const CIMObjectPath& x)  
 {  
     return os << x.toString();  
 }  
 #endif  
   
 PEGASUS_NAMESPACE_END PEGASUS_NAMESPACE_END


Legend:
Removed from v.1.29  
changed lines
  Added in v.1.43.2.1

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2