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

   1 karl  1.54 //%2006////////////////////////////////////////////////////////////////////////
   2 chip  1.1  //
   3 karl  1.43 // Copyright (c) 2000, 2001, 2002 BMC Software; Hewlett-Packard Development
   4            // Company, L.P.; IBM Corp.; The Open Group; Tivoli Systems.
   5            // Copyright (c) 2003 BMC Software; Hewlett-Packard Development Company, L.P.;
   6 karl  1.30 // IBM Corp.; EMC Corporation, The Open Group.
   7 karl  1.43 // Copyright (c) 2004 BMC Software; Hewlett-Packard Development Company, L.P.;
   8            // IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group.
   9 karl  1.45 // Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.;
  10            // EMC Corporation; VERITAS Software Corporation; The Open Group.
  11 karl  1.54 // Copyright (c) 2006 Hewlett-Packard Development Company, L.P.; IBM Corp.;
  12            // EMC Corporation; Symantec Corporation; The Open Group.
  13 chip  1.1  //
  14            // Permission is hereby granted, free of charge, to any person obtaining a copy
  15            // of this software and associated documentation files (the "Software"), to
  16            // deal in the Software without restriction, including without limitation the
  17            // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  18            // sell copies of the Software, and to permit persons to whom the Software is
  19            // furnished to do so, subject to the following conditions:
  20 r.kieninger 1.56 //
  21 chip        1.1  // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
  22                  // ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
  23                  // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
  24                  // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
  25                  // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
  26                  // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
  27                  // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  28                  // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  29                  //
  30                  //==============================================================================
  31                  //
  32                  //%/////////////////////////////////////////////////////////////////////////////
  33                  
  34 kumpf       1.2  #include <Pegasus/Common/Config.h>
  35                  #include <cstring>
  36 kumpf       1.22 #include <iostream>
  37 kumpf       1.2  #include "HashTable.h"
  38                  #include "CIMObjectPath.h"
  39                  #include "Indentor.h"
  40                  #include "CIMName.h"
  41                  #include "XmlWriter.h"
  42                  #include "XmlReader.h"
  43 kumpf       1.11 #include "ArrayInternal.h"
  44 chip        1.1  
  45                  PEGASUS_NAMESPACE_BEGIN
  46 kumpf       1.2  
  47 kumpf       1.16 #define PEGASUS_ARRAY_T CIMKeyBinding
  48 kumpf       1.2  # include "ArrayImpl.h"
  49                  #undef PEGASUS_ARRAY_T
  50                  
  51                  #define PEGASUS_ARRAY_T CIMObjectPath
  52                  # include "ArrayImpl.h"
  53                  #undef PEGASUS_ARRAY_T
  54                  
  55                  // ATTN: KS May 2002 P0 Add resolve method to CIMObjectPath.
  56                  // Add a resolve method to this class to verify that the
  57                  // reference is correct (that the class name corresponds to a real
  58                  // class and that the property names are really keys and that all keys
  59                  // of the class or used. Also be sure that there is a valid conversion
  60                  // between the string value and the value of that property).
  61                  //
  62                  // ATTN: also check to see that the reference refers to a class that is the
  63                  // same or derived from the _className member.
  64                  
  65                  ////////////////////////////////////////////////////////////////////////////////
  66                  //
  67                  // Local routines:
  68                  //
  69 kumpf       1.2  ////////////////////////////////////////////////////////////////////////////////
  70                  
  71                  static String _escapeSpecialCharacters(const String& str)
  72                  {
  73                      String result;
  74                  
  75                      for (Uint32 i = 0, n = str.size(); i < n; i++)
  76                      {
  77                          switch (str[i])
  78                          {
  79 kumpf       1.28             case '\\':
  80                                  result.append("\\\\");
  81 kumpf       1.2                  break;
  82                  
  83                              case '"':
  84 kumpf       1.13                 result.append("\\\"");
  85 kumpf       1.2                  break;
  86                  
  87                              default:
  88 kumpf       1.13                 result.append(str[i]);
  89 kumpf       1.2          }
  90                      }
  91                  
  92                      return result;
  93                  }
  94                  
  95 kumpf       1.16 static void _BubbleSort(Array<CIMKeyBinding>& x)
  96 kumpf       1.2  {
  97                      Uint32 n = x.size();
  98                  
  99 kumpf       1.24     //
 100 chip        1.47     //  If the key is a reference, the keys in the reference must also be
 101 kumpf       1.24     //  sorted
 102                      //
 103                      for (Uint32 k = 0; k < n ; k++)
 104                          if (x[k].getType () == CIMKeyBinding::REFERENCE)
 105                          {
 106                              CIMObjectPath tmp (x[k].getValue ());
 107                              Array <CIMKeyBinding> keyBindings = tmp.getKeyBindings ();
 108                              _BubbleSort (keyBindings);
 109                              tmp.setKeyBindings (keyBindings);
 110                              x[k].setValue (tmp.toString ());
 111                          }
 112                  
 113 kumpf       1.2      if (n < 2)
 114                          return;
 115                  
 116                      for (Uint32 i = 0; i < n - 1; i++)
 117                      {
 118                          for (Uint32 j = 0; j < n - 1; j++)
 119                          {
 120 chip        1.47             if (String::compareNoCase(x[j].getName().getString(),
 121 kumpf       1.17                                       x[j+1].getName().getString()) > 0)
 122 kumpf       1.2              {
 123 kumpf       1.16                 CIMKeyBinding t = x[j];
 124 kumpf       1.2                  x[j] = x[j+1];
 125                                  x[j+1] = t;
 126                              }
 127                          }
 128                      }
 129                  }
 130                  
 131                  ////////////////////////////////////////////////////////////////////////////////
 132                  //
 133 kumpf       1.16 // CIMKeyBinding
 134 kumpf       1.2  //
 135                  ////////////////////////////////////////////////////////////////////////////////
 136                  
 137 kumpf       1.16 class CIMKeyBindingRep
 138 kumpf       1.2  {
 139                  public:
 140 kumpf       1.16     CIMKeyBindingRep()
 141 kumpf       1.2      {
 142                      }
 143                  
 144 kumpf       1.16     CIMKeyBindingRep(const CIMKeyBindingRep& x)
 145 kumpf       1.2          : _name(x._name), _value(x._value), _type(x._type)
 146                      {
 147                      }
 148                  
 149 kumpf       1.16     CIMKeyBindingRep(
 150 kumpf       1.7          const CIMName& name,
 151 kumpf       1.2          const String& value,
 152 kumpf       1.16         CIMKeyBinding::Type type)
 153 kumpf       1.2          : _name(name), _value(value), _type(type)
 154                      {
 155                      }
 156                  
 157 kumpf       1.16     ~CIMKeyBindingRep()
 158 kumpf       1.2      {
 159                      }
 160                  
 161 kumpf       1.16     CIMKeyBindingRep& operator=(const CIMKeyBindingRep& x)
 162 kumpf       1.2      {
 163                          if (&x != this)
 164                          {
 165                              _name = x._name;
 166                              _value = x._value;
 167                              _type = x._type;
 168                          }
 169                          return *this;
 170                      }
 171                  
 172 kumpf       1.7      CIMName _name;
 173 kumpf       1.2      String _value;
 174 kumpf       1.16     CIMKeyBinding::Type _type;
 175 kumpf       1.2  };
 176                  
 177                  
 178 a.arora     1.39 CIMKeyBinding::CIMKeyBinding()
 179 kumpf       1.2  {
 180 a.arora     1.39     _rep = new CIMKeyBindingRep();
 181 kumpf       1.2  }
 182                  
 183 a.arora     1.39 CIMKeyBinding::CIMKeyBinding(const CIMKeyBinding& x)
 184 kumpf       1.2  {
 185 a.arora     1.39     _rep = new CIMKeyBindingRep(*x._rep);
 186 kumpf       1.2  }
 187                  
 188 kumpf       1.57 CIMKeyBinding::CIMKeyBinding(
 189                      const CIMName& name,
 190                      const String& value,
 191                      Type type)
 192 kumpf       1.2  {
 193 a.arora     1.39     _rep = new CIMKeyBindingRep(name, value, type);
 194 kumpf       1.2  }
 195                  
 196 kumpf       1.18 CIMKeyBinding::CIMKeyBinding(const CIMName& name, const CIMValue& value)
 197                  {
 198 kumpf       1.21     if (value.isArray())
 199 kumpf       1.20     {
 200                          throw TypeMismatchException();
 201                      }
 202                  
 203 kumpf       1.18     String kbValue = value.toString();
 204                      Type kbType;
 205                  
 206                      switch (value.getType())
 207                      {
 208                      case CIMTYPE_BOOLEAN:
 209                          kbType = BOOLEAN;
 210                          break;
 211                      case CIMTYPE_CHAR16:
 212                      case CIMTYPE_STRING:
 213                      case CIMTYPE_DATETIME:
 214                          kbType = STRING;
 215                          break;
 216                      case CIMTYPE_REFERENCE:
 217                          kbType = REFERENCE;
 218                          break;
 219 dave.sudlik 1.46 //  case CIMTYPE_REAL32:
 220                  //  case CIMTYPE_REAL64:
 221 dave.sudlik 1.44     case CIMTYPE_OBJECT:
 222 a.dunfey    1.55 #ifdef PEGASUS_EMBEDDED_INSTANCE_SUPPORT
 223                      case CIMTYPE_INSTANCE:
 224                  #endif // PEGASUS_EMBEDDED_INSTANCE_SUPPORT
 225 dave.sudlik 1.46         // From PEP 194: EmbeddedObjects cannot be keys.
 226 dave.sudlik 1.44         throw TypeMismatchException();
 227                          break;
 228 kumpf       1.18     default:
 229                          kbType = NUMERIC;
 230                          break;
 231                      }
 232                  
 233 a.arora     1.39     _rep = new CIMKeyBindingRep(name, kbValue, kbType);
 234 kumpf       1.18 }
 235                  
 236 kumpf       1.16 CIMKeyBinding::~CIMKeyBinding()
 237 kumpf       1.2  {
 238 a.arora     1.39     delete _rep;
 239 kumpf       1.2  }
 240                  
 241 kumpf       1.16 CIMKeyBinding& CIMKeyBinding::operator=(const CIMKeyBinding& x)
 242 kumpf       1.2  {
 243 a.arora     1.39     *_rep = *x._rep;
 244 kumpf       1.2      return *this;
 245                  }
 246                  
 247 kumpf       1.16 const CIMName& CIMKeyBinding::getName() const
 248 kumpf       1.2  {
 249                      return _rep->_name;
 250                  }
 251                  
 252 kumpf       1.16 void CIMKeyBinding::setName(const CIMName& name)
 253 kumpf       1.2  {
 254                      _rep->_name = name;
 255                  }
 256                  
 257 kumpf       1.16 const String& CIMKeyBinding::getValue() const
 258 kumpf       1.2  {
 259                      return _rep->_value;
 260                  }
 261                  
 262 kumpf       1.16 void CIMKeyBinding::setValue(const String& value)
 263 kumpf       1.2  {
 264                      _rep->_value = value;
 265                  }
 266                  
 267 kumpf       1.16 CIMKeyBinding::Type CIMKeyBinding::getType() const
 268 kumpf       1.2  {
 269                      return _rep->_type;
 270                  }
 271                  
 272 kumpf       1.16 void CIMKeyBinding::setType(CIMKeyBinding::Type type)
 273 kumpf       1.2  {
 274                      _rep->_type = type;
 275                  }
 276 kumpf       1.18 
 277                  Boolean CIMKeyBinding::equal(CIMValue value)
 278                  {
 279 kumpf       1.21     if (value.isArray())
 280 kumpf       1.20     {
 281                          return false;
 282                      }
 283                  
 284 kumpf       1.18     CIMValue kbValue;
 285                  
 286                      try
 287                      {
 288                          switch (value.getType())
 289                          {
 290                          case CIMTYPE_CHAR16:
 291 kumpf       1.20             if (getType() != STRING) return false;
 292 kumpf       1.18             kbValue.set(getValue()[0]);
 293                              break;
 294                          case CIMTYPE_DATETIME:
 295 kumpf       1.20             if (getType() != STRING) return false;
 296 kumpf       1.18             kbValue.set(CIMDateTime(getValue()));
 297                              break;
 298                          case CIMTYPE_STRING:
 299 kumpf       1.20             if (getType() != STRING) return false;
 300 kumpf       1.18             kbValue.set(getValue());
 301                              break;
 302                          case CIMTYPE_REFERENCE:
 303 kumpf       1.20             if (getType() != REFERENCE) return false;
 304 kumpf       1.18             kbValue.set(CIMObjectPath(getValue()));
 305                              break;
 306 kumpf       1.20         case CIMTYPE_BOOLEAN:
 307                              if (getType() != BOOLEAN) return false;
 308                              kbValue = XmlReader::stringToValue(0, getValue().getCString(),
 309                                                                 value.getType());
 310                              break;
 311 dave.sudlik 1.46 //      case CIMTYPE_REAL32:
 312                  //      case CIMTYPE_REAL64:
 313 dave.sudlik 1.44         case CIMTYPE_OBJECT:
 314 a.dunfey    1.55 #ifdef PEGASUS_EMBEDDED_INSTANCE_SUPPORT
 315                          case CIMTYPE_INSTANCE:
 316                  #endif // PEGASUS_EMBEDDED_INSTANCE_SUPPORT
 317 dave.sudlik 1.46             // From PEP 194: EmbeddedObjects cannot be keys.
 318 dave.sudlik 1.44             return false;
 319                              break;
 320 kumpf       1.20         default:  // Numerics
 321                              if (getType() != NUMERIC) return false;
 322 kumpf       1.18             kbValue = XmlReader::stringToValue(0, getValue().getCString(),
 323                                                                 value.getType());
 324                              break;
 325                          }
 326                      }
 327 kumpf       1.19     catch (Exception&)
 328 kumpf       1.18     {
 329                          return false;
 330                      }
 331                  
 332                      return value.equal(kbValue);
 333                  }
 334 kumpf       1.2  
 335 kumpf       1.16 Boolean operator==(const CIMKeyBinding& x, const CIMKeyBinding& y)
 336 kumpf       1.2  {
 337 kumpf       1.33     // Check that the names and types match
 338                      if (!(x.getName().equal(y.getName())) ||
 339                          !(x.getType() == y.getType()))
 340                      {
 341                          return false;
 342                      }
 343                  
 344                      switch (x.getType())
 345                      {
 346                      case CIMKeyBinding::REFERENCE:
 347                          try
 348                          {
 349                              // References should be compared as CIMObjectPaths
 350                              return (CIMObjectPath(x.getValue()) == CIMObjectPath(y.getValue()));
 351                          }
 352                          catch (Exception&)
 353                          {
 354                              // If CIMObjectPath parsing fails, just compare strings
 355 kumpf       1.58             return String::equal(x.getValue(), y.getValue());
 356 kumpf       1.33         }
 357                          break;
 358                      case CIMKeyBinding::BOOLEAN:
 359                          // Case-insensitive comparison is sufficient for booleans
 360 kumpf       1.58         return String::equalNoCase(x.getValue(), y.getValue());
 361 kumpf       1.33         break;
 362                      case CIMKeyBinding::NUMERIC:
 363                          // Note: This comparison assumes XML syntax for integers
 364                          // First try comparing as unsigned integers
 365                          {
 366                              Uint64 xValue;
 367                              Uint64 yValue;
 368                              if (XmlReader::stringToUnsignedInteger(
 369                                      x.getValue().getCString(), xValue) &&
 370                                  XmlReader::stringToUnsignedInteger(
 371                                      y.getValue().getCString(), yValue))
 372                              {
 373                                  return (xValue == yValue);
 374                              }
 375                          }
 376                          // Next try comparing as signed integers
 377                          {
 378                              Sint64 xValue;
 379                              Sint64 yValue;
 380                              if (XmlReader::stringToSignedInteger(
 381                                      x.getValue().getCString(), xValue) &&
 382 kumpf       1.33                 XmlReader::stringToSignedInteger(
 383                                      y.getValue().getCString(), yValue))
 384                              {
 385                                  return (xValue == yValue);
 386                              }
 387                          }
 388                          // Note: Keys may not be real values, so don't try comparing as reals
 389                          // We couldn't parse the numbers, so just compare the strings
 390 kumpf       1.58         return String::equal(x.getValue(), y.getValue());
 391 kumpf       1.33         break;
 392                      default:  // CIMKeyBinding::STRING
 393 kumpf       1.58         return String::equal(x.getValue(), y.getValue());
 394 kumpf       1.33         break;
 395                      }
 396                  
 397                      PEGASUS_UNREACHABLE(return false;)
 398 kumpf       1.2  }
 399                  
 400                  
 401                  ////////////////////////////////////////////////////////////////////////////////
 402                  //
 403                  // CIMObjectPath
 404                  //
 405                  ////////////////////////////////////////////////////////////////////////////////
 406                  
 407                  class CIMObjectPathRep
 408                  {
 409                  public:
 410                      CIMObjectPathRep()
 411                      {
 412                      }
 413                  
 414                      CIMObjectPathRep(const CIMObjectPathRep& x)
 415                          : _host(x._host), _nameSpace(x._nameSpace),
 416                          _className(x._className), _keyBindings(x._keyBindings)
 417                      {
 418                      }
 419 kumpf       1.2  
 420                      CIMObjectPathRep(
 421                          const String& host,
 422 kumpf       1.7          const CIMNamespaceName& nameSpace,
 423                          const CIMName& className,
 424 kumpf       1.16         const Array<CIMKeyBinding>& keyBindings)
 425 kumpf       1.2          : _host(host), _nameSpace(nameSpace),
 426                          _className(className), _keyBindings(keyBindings)
 427                      {
 428                      }
 429                  
 430                      ~CIMObjectPathRep()
 431                      {
 432                      }
 433                  
 434                      CIMObjectPathRep& operator=(const CIMObjectPathRep& x)
 435                      {
 436                          if (&x != this)
 437                          {
 438                              _host = x._host;
 439                              _nameSpace = x._nameSpace;
 440                              _className = x._className;
 441                              _keyBindings = x._keyBindings;
 442                          }
 443                          return *this;
 444                      }
 445                  
 446 kumpf       1.34     static Boolean isValidHostname(const String& hostname)
 447                      {
 448                          //------------------------------------------------------------------
 449                          // Validate the hostname.  The hostname value may or may not be a
 450                          // fully-qualified domain name (e.g., xyz.company.com) or may be an
 451                          // IP address.  A port number may follow the hostname.
 452                          // Hostnames must match one of the following regular expressions:
 453 dave.sudlik 1.42         // ^([A-Za-z0-9][A-Za-z0-9-]*)(\.[A-Za-z][A-Za-z0-9-]*)*(:[0-9]*)?$
 454 kumpf       1.34         // ^([0-9]*\.[0-9]*\.[0-9]*\.[0-9]*)(:[0-9]*)?$
 455 dave.sudlik 1.42         // Note for Bug#1462. Be careful here, from RFC 1123:
 456 chip        1.47         // - The syntax of a legal Internet host name was specified in
 457                          //   RFC-952 [DNS:4]. One aspect of host name syntax is hereby
 458                          //   changed: the restriction on the first character is relaxed to
 459                          //   allow either a letter or a digit.
 460 dave.sudlik 1.42         // - If a dotted-decimal number can be entered without identifying
 461                          //   delimiters, then a full syntactic check must be made, because
 462                          //   a segment of a host domain name is now allowed to begin with a
 463                          //   digit and could legally be entirely numeric (see Section 6.1.2.4).
 464                          //   However, a valid host name can never have the dotted-decimal form
 465                          //   #.#.#.#, since at least the highest-level component label will be
 466 chip        1.47         //   alphabetic.
 467 dave.sudlik 1.42         // The algorithm below has been updated accordingly.
 468 kumpf       1.34         //------------------------------------------------------------------
 469                  
 470                          Uint32 i = 0;
 471                  
 472 dave.sudlik 1.42         Boolean isValid = false;
 473                  
 474 kumpf       1.52         if (isascii(hostname[0]) && isdigit(hostname[0]))
 475 kumpf       1.34         {
 476 dave.sudlik 1.42             //--------------------------------------------------------------
 477 chip        1.47             // Attempt to validate an IP address, but keep in mind that it
 478 dave.sudlik 1.42             // might be a host name, since the leading character can now be
 479                              // a digit.
 480                              //--------------------------------------------------------------
 481                              isValid = true;
 482 kumpf       1.34 
 483                              for (Uint32 octet=1; octet<=4; octet++)
 484                              {
 485 rishika.kedia 1.59                 Uint32 octetValue = 0, j = 0;
 486 kumpf         1.34 
 487 dave.sudlik   1.42                 //----------------------------------------------------------
 488                                    // If a non-digit is encountered in the input parameter,
 489                                    // then break from here and attempt to validate as host name.
 490                                    //----------------------------------------------------------
 491 kumpf         1.52                 if (!(isascii(hostname[i]) && isdigit(hostname[i])))
 492 kumpf         1.34                 {
 493 dave.sudlik   1.42                     isValid = false;
 494                                        break;
 495 kumpf         1.34                 }
 496                    
 497 kumpf         1.52                 // skip over digits
 498                                    while (isascii(hostname[i]) && isdigit(hostname[i]))
 499 kumpf         1.34                 {
 500 rishika.kedia 1.59                     if (j == 3)
 501                                        {
 502                                           isValid = false;
 503                                           break;
 504                                        }
 505 kumpf         1.34                     octetValue = octetValue*10 + (hostname[i] - '0');
 506                                        i++;
 507 rishika.kedia 1.59                     j++;
 508 kumpf         1.34                 }
 509                    
 510                                    if (octetValue > 255)
 511                                    {
 512 dave.sudlik   1.42                     isValid = false;
 513                                        break;
 514 kumpf         1.34                 }
 515                    
 516 dave.sudlik   1.42                 // Check for invalid character in IP address
 517 kumpf         1.34                 if ((octet != 4) && (hostname[i++] != '.'))
 518                                    {
 519 dave.sudlik   1.42                     isValid = false;
 520                                        break;
 521                                    }
 522                    
 523                                    // Check for the case where it's a valid host name that happens
 524                                    // to have 4 (or more) leading all-numeric host segments.
 525 kumpf         1.57                 if ((octet == 4) && (hostname[i] != ':') &&
 526                                        hostname[i] != char(0))
 527 dave.sudlik   1.42                 {
 528                                        isValid = false;
 529                                        break;
 530 kumpf         1.34                 }
 531                                }
 532                            }
 533 dave.sudlik   1.42         if (!isValid)   // if it is not a valid IP address
 534 kumpf         1.34         {
 535 dave.sudlik   1.42             i = 0;  // reset index for host name check
 536                    
 537                                // Validate a host name
 538                                isValid = true;
 539 kumpf         1.34 
 540                                Boolean expectHostSegment = true;
 541 dave.sudlik   1.42             Boolean hostSegmentIsNumeric;
 542 kumpf         1.34 
 543                                while (expectHostSegment == true)
 544                                {
 545                                    expectHostSegment = false;
 546 dave.sudlik   1.42                 hostSegmentIsNumeric = true; // assume all-numeric host segment
 547 kumpf         1.34 
 548 kumpf         1.53                 if (!(isascii(hostname[i]) &&
 549                                          (isalnum(hostname[i]) || (hostname[i] == '_'))))
 550 kumpf         1.34                 {
 551                                        return false;
 552                                    }
 553                    
 554 kumpf         1.52                 while (isascii(hostname[i]) &&
 555                                           (isalnum(hostname[i]) || (hostname[i] == '-') ||
 556                                            (hostname[i] == '_')))
 557 kumpf         1.34                 {
 558 dave.sudlik   1.42                     // If a non-digit is encountered, set "all-numeric"
 559                                        // flag to false
 560 vijay.eli     1.51                     if (isalpha(hostname[i]) || (hostname[i] == '-') ||
 561 kumpf         1.58                                                 (hostname[i] == '_'))
 562                                        {
 563 dave.sudlik   1.42                         hostSegmentIsNumeric = false;
 564                                        }
 565 kumpf         1.34                     i++;
 566                                    }
 567                    
 568                                    if (hostname[i] == '.')
 569                                    {
 570                                        i++;
 571                                        expectHostSegment = true;
 572                                    }
 573                                }
 574 dave.sudlik   1.42             // If the last Host Segment is all numeric, then return false.
 575                                // RFC 1123 says "highest-level component label will be alphabetic".
 576 kumpf         1.58             if (hostSegmentIsNumeric)
 577                                {
 578 dave.sudlik   1.42                 return false;
 579                                }
 580                            }
 581                    
 582                            if (!isValid) // if not a valid IP address or host name
 583                            {
 584                                return false;
 585 kumpf         1.34         }
 586                    
 587                            // Check for a port number:
 588                    
 589                            if (hostname[i] == ':')
 590                            {
 591 kumpf         1.52             i++;
 592 dave.sudlik   1.60             // First check that there is at least one digit specified for the
 593                                // port number if the ':' delimiter is present. Note that there is
 594                                // a question as to whether ':' can exist without the port number.
 595                                // ATTN: See bug 6424.
 596 kumpf         1.52             if (!(isascii(hostname[i]) && isdigit(hostname[i])))
 597 kumpf         1.34             {
 598                                    return false;
 599                                }
 600 dave.sudlik   1.60 
 601                                Uint32 port = (hostname[i] - '0');
 602 kumpf         1.52             i++;
 603 chip          1.47 
 604 dave.sudlik   1.60             // Check that remaining characters in port number are all digits,
 605                                // and that the port number can be represented by 16-bits.
 606 kumpf         1.52             while (isascii(hostname[i]) && isdigit(hostname[i]))
 607                                {
 608 dave.sudlik   1.60                 port = port*10 + (hostname[i] - '0');
 609                                    if(port > 65535)
 610                                    {
 611                                        return false;
 612                                    }
 613 kumpf         1.52                 i++;
 614                                }
 615 kumpf         1.34         }
 616                    
 617                            return (hostname[i] == char(0));
 618                        }
 619                    
 620 kumpf         1.2      //
 621                        // Contains port as well (e.g., myhost:1234).
 622                        //
 623                        String _host;
 624                    
 625 kumpf         1.7      CIMNamespaceName _nameSpace;
 626                        CIMName _className;
 627 kumpf         1.16     Array<CIMKeyBinding> _keyBindings;
 628 kumpf         1.2  };
 629                    
 630                    
 631 a.arora       1.39 CIMObjectPath::CIMObjectPath()
 632 kumpf         1.2  {
 633 a.arora       1.39     _rep = new CIMObjectPathRep();
 634 kumpf         1.2  }
 635                    
 636 a.arora       1.39 CIMObjectPath::CIMObjectPath(const CIMObjectPath& x)
 637 kumpf         1.2  {
 638 a.arora       1.39     _rep = new CIMObjectPathRep(*x._rep);
 639 kumpf         1.2  }
 640                    
 641                    CIMObjectPath::CIMObjectPath(const String& objectName)
 642                    {
 643                        // Test the objectName out to see if we get an exception
 644                        CIMObjectPath tmpRef;
 645                        tmpRef.set(objectName);
 646                    
 647 a.arora       1.39     _rep = new CIMObjectPathRep(*tmpRef._rep);
 648 kumpf         1.2  }
 649                    
 650                    CIMObjectPath::CIMObjectPath(
 651                        const String& host,
 652 kumpf         1.7      const CIMNamespaceName& nameSpace,
 653                        const CIMName& className,
 654 kumpf         1.16     const Array<CIMKeyBinding>& keyBindings)
 655 kumpf         1.2  {
 656                        // Test the objectName out to see if we get an exception
 657                        CIMObjectPath tmpRef;
 658                        tmpRef.set(host, nameSpace, className, keyBindings);
 659                    
 660 a.arora       1.39     _rep = new CIMObjectPathRep(*tmpRef._rep);
 661 kumpf         1.2  }
 662                    
 663                    CIMObjectPath::~CIMObjectPath()
 664                    {
 665 a.arora       1.39     delete _rep;
 666 kumpf         1.2  }
 667                    
 668                    CIMObjectPath& CIMObjectPath::operator=(const CIMObjectPath& x)
 669                    {
 670 a.arora       1.39     *_rep = *x._rep;
 671 kumpf         1.2      return *this;
 672                    }
 673                    
 674                    void CIMObjectPath::clear()
 675                    {
 676                        _rep->_host.clear();
 677                        _rep->_nameSpace.clear();
 678                        _rep->_className.clear();
 679                        _rep->_keyBindings.clear();
 680                    }
 681                    
 682                    void CIMObjectPath::set(
 683                        const String& host,
 684 kumpf         1.7      const CIMNamespaceName& nameSpace,
 685                        const CIMName& className,
 686 kumpf         1.16     const Array<CIMKeyBinding>& keyBindings)
 687 kumpf         1.2  {
 688                       setHost(host);
 689                       setNameSpace(nameSpace);
 690                       setClassName(className);
 691                       setKeyBindings(keyBindings);
 692                    }
 693                    
 694 kumpf         1.22 Boolean _parseHostElement(
 695 kumpf         1.2      const String& objectName,
 696                        char*& p,
 697 kumpf         1.9      String& host)
 698 kumpf         1.2  {
 699                        // See if there is a host name (true if it begins with "//"):
 700 kumpf         1.32     // Host is of the form <hostname>:<port> and begins with "//"
 701 kumpf         1.2      // and ends with "/":
 702                    
 703                        if (p[0] != '/' || p[1] != '/')
 704                        {
 705                            return false;
 706                        }
 707                    
 708                        p += 2;
 709                    
 710 kumpf         1.34     char* slash = strchr(p, '/');
 711                        if (!slash)
 712 chuck         1.23     {
 713 kumpf         1.34         throw MalformedObjectNameException(objectName);
 714 kumpf         1.2      }
 715                    
 716 kumpf         1.34     String hostname = String(p, (Uint32)(slash - p));
 717                        if (!CIMObjectPathRep::isValidHostname(hostname))
 718 kumpf         1.2      {
 719 kumpf         1.10         throw MalformedObjectNameException(objectName);
 720 kumpf         1.2      }
 721 kumpf         1.34     host = hostname;
 722 kumpf         1.2  
 723 kumpf         1.31     // Do not step past the '/'; it will be consumed by the namespace parser
 724 kumpf         1.34     p = slash;
 725 kumpf         1.2  
 726                        return true;
 727                    }
 728                    
 729 kumpf         1.22 Boolean _parseNamespaceElement(
 730 kumpf         1.2      const String& objectName,
 731                        char*& p,
 732 kumpf         1.7      CIMNamespaceName& nameSpace)
 733 kumpf         1.2  {
 734                        // If we don't find a valid namespace name followed by a ':', we
 735                        // assume we're not looking at a namespace name.
 736                    
 737 kumpf         1.7      char* colon = strchr(p, ':');
 738                        if (!colon)
 739                        {
 740                            return false;
 741                        }
 742                    
 743 chip          1.47     // A ':' as part of a keybinding value should not be interpreted as
 744 kumpf         1.25     // a namespace delimiter.  Since keybinding pairs follow the first '.'
 745                        // in the object path string, the ':' delimiter only counts if it
 746                        // appears before the '.'.
 747                    
 748                        char* dot = strchr(p, '.');
 749                        if (dot && (dot < colon))
 750                        {
 751                            return false;
 752                        }
 753                    
 754 kumpf         1.2      //----------------------------------------------------------------------
 755                        // Validate the namespace path.  Namespaces must match the following
 756                        // regular expression: "[A-Za-z_]+(/[A-Za-z_]+)*"
 757                        //----------------------------------------------------------------------
 758                    
 759 david         1.27     String namespaceName = String(p, (Uint32)(colon - p));
 760 kumpf         1.7      if (!CIMNamespaceName::legal(namespaceName))
 761 kumpf         1.2      {
 762 kumpf         1.10         throw MalformedObjectNameException(objectName);
 763 kumpf         1.2      }
 764 kumpf         1.7      nameSpace = namespaceName;
 765 kumpf         1.2  
 766 kumpf         1.7      p = colon+1;
 767 kumpf         1.2      return true;
 768                    }
 769                    
 770                    /**
 771 kumpf         1.29     ATTN-RK: The DMTF specification for the string form of an
 772                        object path makes it impossible for a parser to distinguish
 773                        between a key values of String type and Reference type.
 774                    
 775                        Given the ambiguity, this implementation takes a guess at the
 776                        type of a quoted key value.  If the value can be parsed into
 777                        a CIMObjectPath with at least one key binding, the type is
 778                        set to REFERENCE.  Otherwise, the type is set to STRING.
 779                        Note: This algorithm appears to be in line with what the Sun
 780                        WBEM Services implementation does.
 781                    
 782                        To be totally correct, it would be necessary to retrieve the
 783                        class definition and look up the types of the key properties
 784                        to determine how to interpret the key values.  This is clearly
 785                        too inefficient for internal transformations between
 786                        CIMObjectPaths and String values.
 787 kumpf         1.2  */
 788 kumpf         1.22 void _parseKeyBindingPairs(
 789 kumpf         1.2      const String& objectName,
 790                        char*& p,
 791 chip          1.47     Array<CIMKeyBinding>& keyBindings)
 792 kumpf         1.2  {
 793                        // Get the key-value pairs:
 794                    
 795                        while (*p)
 796                        {
 797                            // Get key part:
 798                    
 799 kumpf         1.5          char* equalsign = strchr(p, '=');
 800                            if (!equalsign)
 801 kumpf         1.2          {
 802 kumpf         1.10             throw MalformedObjectNameException(objectName);
 803 kumpf         1.2          }
 804                    
 805 kumpf         1.5          *equalsign = 0;
 806 kumpf         1.2  
 807 kumpf         1.17         if (!CIMName::legal(p))
 808 kumpf         1.10             throw MalformedObjectNameException(objectName);
 809 kumpf         1.2  
 810 kumpf         1.17         CIMName keyName (p);
 811                    
 812 kumpf         1.2          // Get the value part:
 813                    
 814                            String valueString;
 815 kumpf         1.5          p = equalsign + 1;
 816 kumpf         1.16         CIMKeyBinding::Type type;
 817 kumpf         1.2  
 818 kumpf         1.29         if (*p == '"')
 819 kumpf         1.2          {
 820 kumpf         1.29             // Could be CIMKeyBinding::STRING or CIMKeyBinding::REFERENCE
 821                    
 822 kumpf         1.2              p++;
 823                    
 824                                while (*p && *p != '"')
 825                                {
 826                                    if (*p == '\\')
 827 kumpf         1.28                 {
 828 kumpf         1.2                      *p++;
 829                    
 830 kumpf         1.28                     if ((*p != '\\') && (*p != '"'))
 831                                        {
 832                                            throw MalformedObjectNameException(objectName);
 833                                        }
 834                                    }
 835                    
 836 kumpf         1.2                  valueString.append(*p++);
 837                                }
 838                    
 839                                if (*p++ != '"')
 840 kumpf         1.10                 throw MalformedObjectNameException(objectName);
 841 kumpf         1.2  
 842 kumpf         1.29             /*
 843                                    Guess at the type of this quoted key value.  If the value
 844                                    can be parsed into a CIMObjectPath with at least one key
 845                                    binding, the type is assumed to be a REFERENCE.  Otherwise,
 846                                    the type is set to STRING.  (See method header for details.)
 847                                 */
 848 kumpf         1.16             type = CIMKeyBinding::STRING;
 849 kumpf         1.2  
 850 kumpf         1.29             try
 851 kumpf         1.2              {
 852 kumpf         1.29                 CIMObjectPath testForPath(valueString);
 853                                    if (testForPath.getKeyBindings().size() > 0)
 854 kumpf         1.28                 {
 855 kumpf         1.29                     // We've found a reference value!
 856                                        type = CIMKeyBinding::REFERENCE;
 857 kumpf         1.28                 }
 858 kumpf         1.2              }
 859 david.dillard 1.41             catch (const Exception &)
 860 kumpf         1.29             {
 861                                    // Not a reference value; leave type as STRING
 862                                }
 863 kumpf         1.2          }
 864                            else if (toupper(*p) == 'T' || toupper(*p) == 'F')
 865                            {
 866 kumpf         1.16             type = CIMKeyBinding::BOOLEAN;
 867 kumpf         1.2  
 868                                char* r = p;
 869                                Uint32 n = 0;
 870                    
 871                                while (*r && *r != ',')
 872                                {
 873                                    *r = toupper(*r);
 874                                    r++;
 875                                    n++;
 876                                }
 877                    
 878                                if (!(((strncmp(p, "TRUE", n) == 0) && n == 4) ||
 879                                      ((strncmp(p, "FALSE", n) == 0) && n == 5)))
 880 kumpf         1.10                 throw MalformedObjectNameException(objectName);
 881 kumpf         1.2  
 882                                valueString.assign(p, n);
 883                    
 884                                p = p + n;
 885                            }
 886                            else
 887                            {
 888 kumpf         1.16             type = CIMKeyBinding::NUMERIC;
 889 kumpf         1.2  
 890                                char* r = p;
 891                                Uint32 n = 0;
 892                    
 893                                while (*r && *r != ',')
 894                                {
 895                                    r++;
 896                                    n++;
 897                                }
 898                    
 899                                Boolean isComma = false;
 900                                if (*r)
 901                                {
 902                                    *r = '\0';
 903                                    isComma = true;
 904                                }
 905                    
 906 r.kieninger   1.56             if (*p == '-')
 907                                {
 908                                    Sint64 x;
 909                                    if (!XmlReader::stringToSignedInteger(p, x))
 910                                        throw MalformedObjectNameException(objectName);
 911                                }
 912                                else
 913                                {
 914                                    Uint64 x;
 915                                    if (!XmlReader::stringToUnsignedInteger(p, x))
 916                                        throw MalformedObjectNameException(objectName);
 917                                }
 918 kumpf         1.2  
 919                                valueString.assign(p, n);
 920                    
 921                                if (isComma)
 922                                {
 923                                    *r = ',';
 924                                }
 925                    
 926                                p = p + n;
 927                            }
 928                    
 929 chip          1.47         keyBindings.append(CIMKeyBinding(keyName.getString (), valueString,
 930 kumpf         1.17             type));
 931 kumpf         1.2  
 932                            if (*p)
 933                            {
 934                                if (*p++ != ',')
 935                                {
 936 kumpf         1.10                 throw MalformedObjectNameException(objectName);
 937 kumpf         1.2              }
 938                            }
 939                        }
 940                    
 941                        _BubbleSort(keyBindings);
 942                    }
 943                    
 944 chip          1.47 void CIMObjectPath::set(const String& objectName)
 945 kumpf         1.2  {
 946                        clear();
 947                    
 948                        //--------------------------------------------------------------------------
 949                        // We will extract components from an object name. Here is an sample
 950                        // object name:
 951                        //
 952                        //     //atp:9999/root/cimv25:TennisPlayer.first="Patrick",last="Rafter"
 953                        //--------------------------------------------------------------------------
 954                    
 955                        // Convert to a C String first:
 956                    
 957 david         1.37     CString pCString = objectName.getCString();
 958 kumpf         1.26     char* p = const_cast<char*>((const char*) pCString);
 959 kumpf         1.2      Boolean gotHost;
 960                        Boolean gotNamespace;
 961                    
 962                        gotHost = _parseHostElement(objectName, p, _rep->_host);
 963                        gotNamespace = _parseNamespaceElement(objectName, p, _rep->_nameSpace);
 964                    
 965                        if (gotHost && !gotNamespace)
 966                        {
 967 kumpf         1.10         throw MalformedObjectNameException(objectName);
 968 kumpf         1.2      }
 969                    
 970                        // Extract the class name:
 971                    
 972                        char* dot = strchr(p, '.');
 973                    
 974                        if (!dot)
 975                        {
 976                            if (!CIMName::legal(p))
 977                            {
 978 kumpf         1.10             throw MalformedObjectNameException(objectName);
 979 kumpf         1.2          }
 980                    
 981                            // ATTN: remove this later: a reference should only be able to hold
 982                            // an instance name.
 983                    
 984 kumpf         1.17         _rep->_className = CIMName (p);
 985 kumpf         1.2          return;
 986                        }
 987                    
 988 david         1.27     String className = String(p, (Uint32)(dot - p));
 989 kumpf         1.7      if (!CIMName::legal(className))
 990                        {
 991 kumpf         1.10         throw MalformedObjectNameException(objectName);
 992 kumpf         1.7      }
 993                        _rep->_className = className;
 994 kumpf         1.2  
 995                        // Advance past dot:
 996                    
 997                        p = dot + 1;
 998                    
 999                        _parseKeyBindingPairs(objectName, p, _rep->_keyBindings);
1000                    }
1001                    
1002                    CIMObjectPath& CIMObjectPath::operator=(const String& objectName)
1003                    {
1004                        set(objectName);
1005                        return *this;
1006                    }
1007                    
1008                    const String& CIMObjectPath::getHost() const
1009                    {
1010                        return _rep->_host;
1011                    }
1012                    
1013                    void CIMObjectPath::setHost(const String& host)
1014                    {
1015 kumpf         1.35     if ((host != String::EMPTY) && !CIMObjectPathRep::isValidHostname(host))
1016                        {
1017                            throw MalformedObjectNameException(host);
1018                        }
1019                    
1020 kumpf         1.2      _rep->_host = host;
1021                    }
1022                    
1023 kumpf         1.7  const CIMNamespaceName& CIMObjectPath::getNameSpace() const
1024 kumpf         1.2  {
1025                        return _rep->_nameSpace;
1026                    }
1027                    
1028 kumpf         1.7  void CIMObjectPath::setNameSpace(const CIMNamespaceName& nameSpace)
1029 kumpf         1.2  {
1030                       _rep->_nameSpace = nameSpace;
1031                    }
1032                    
1033 kumpf         1.7  const CIMName& CIMObjectPath::getClassName() const
1034 kumpf         1.2  {
1035                        return _rep->_className;
1036                    }
1037                    
1038 kumpf         1.7  void CIMObjectPath::setClassName(const CIMName& className)
1039 kumpf         1.2  {
1040                        _rep->_className = className;
1041                    }
1042                    
1043 kumpf         1.16 const Array<CIMKeyBinding>& CIMObjectPath::getKeyBindings() const
1044 kumpf         1.2  {
1045                        return _rep->_keyBindings;
1046                    }
1047                    
1048 kumpf         1.16 void CIMObjectPath::setKeyBindings(const Array<CIMKeyBinding>& keyBindings)
1049 kumpf         1.2  {
1050                        _rep->_keyBindings = keyBindings;
1051                        _BubbleSort(_rep->_keyBindings);
1052                    }
1053                    
1054 kumpf         1.15 String CIMObjectPath::toString() const
1055 kumpf         1.2  {
1056                        String objectName;
1057                    
1058                        // Get the host:
1059                    
1060 kumpf         1.15     if (_rep->_host.size())
1061 kumpf         1.2      {
1062                            objectName = "//";
1063 kumpf         1.13         objectName.append(_rep->_host);
1064                            objectName.append("/");
1065 kumpf         1.2      }
1066                    
1067                        // Get the namespace (if we have a host name, we must write namespace):
1068                    
1069 kumpf         1.7      if (!_rep->_nameSpace.isNull() || _rep->_host.size())
1070 kumpf         1.2      {
1071 kumpf         1.17         objectName.append(_rep->_nameSpace.getString ());
1072 kumpf         1.13         objectName.append(":");
1073 kumpf         1.2      }
1074                    
1075                        // Get the class name:
1076                    
1077 kumpf         1.17     objectName.append(getClassName().getString ());
1078 kumpf         1.2  
1079 kumpf         1.9      //
1080                        //  ATTN-CAKG-P2-20020726:  The following condition does not correctly
1081                        //  distinguish instanceNames from classNames in every case
1082                        //  The instanceName of a singleton instance of a keyless class has no
1083                        //  key bindings
1084                        //
1085                        if (_rep->_keyBindings.size () != 0)
1086 kumpf         1.2      {
1087                            objectName.append('.');
1088                    
1089                            // Append each key-value pair:
1090                    
1091 kumpf         1.16         const Array<CIMKeyBinding>& keyBindings = getKeyBindings();
1092 kumpf         1.2  
1093                            for (Uint32 i = 0, n = keyBindings.size(); i < n; i++)
1094                            {
1095 kumpf         1.17             objectName.append(keyBindings[i].getName().getString ());
1096 kumpf         1.2              objectName.append('=');
1097                    
1098                                const String& value = _escapeSpecialCharacters(
1099                                    keyBindings[i].getValue());
1100                    
1101 kumpf         1.16             CIMKeyBinding::Type type = keyBindings[i].getType();
1102 chip          1.47 
1103 kumpf         1.57             if (type == CIMKeyBinding::STRING ||
1104                                    type == CIMKeyBinding::REFERENCE)
1105 kumpf         1.2                  objectName.append('"');
1106                    
1107                                objectName.append(value);
1108                    
1109 kumpf         1.57             if (type == CIMKeyBinding::STRING ||
1110                                    type == CIMKeyBinding::REFERENCE)
1111 kumpf         1.2                  objectName.append('"');
1112                    
1113                                if (i + 1 != n)
1114                                    objectName.append(',');
1115                            }
1116                        }
1117                    
1118                        return objectName;
1119                    }
1120                    
1121 kumpf         1.15 String CIMObjectPath::_toStringCanonical() const
1122 kumpf         1.2  {
1123                        CIMObjectPath ref = *this;
1124                    
1125 kumpf         1.33     // Normalize hostname by changing to lower case
1126 chip          1.47     ref._rep->_host.toLower(); // ICU_TODO:
1127 kumpf         1.2  
1128 kumpf         1.33     // Normalize namespace by changing to lower case
1129                        if (!ref._rep->_nameSpace.isNull())
1130                        {
1131                            String nameSpaceLower = ref._rep->_nameSpace.getString();
1132 chip          1.47         nameSpaceLower.toLower(); // ICU_TODO:
1133 kumpf         1.33         ref._rep->_nameSpace = nameSpaceLower;
1134                        }
1135                    
1136                        // Normalize class name by changing to lower case
1137                        if (!ref._rep->_className.isNull())
1138                        {
1139                            String classNameLower = ref._rep->_className.getString();
1140 chip          1.47         classNameLower.toLower(); // ICU_TODO:
1141 kumpf         1.33         ref._rep->_className = classNameLower;
1142                        }
1143 kumpf         1.2  
1144                        for (Uint32 i = 0, n = ref._rep->_keyBindings.size(); i < n; i++)
1145                        {
1146 kumpf         1.33         // Normalize key binding name by changing to lower case
1147                            if (!ref._rep->_keyBindings[i]._rep->_name.isNull())
1148                            {
1149 chip          1.47             String keyBindingNameLower =
1150 kumpf         1.33                 ref._rep->_keyBindings[i]._rep->_name.getString();
1151                                keyBindingNameLower.toLower(); // ICU_TODO:
1152                                ref._rep->_keyBindings[i]._rep->_name = keyBindingNameLower;
1153                            }
1154                    
1155                            // Normalize the key value
1156                            switch (ref._rep->_keyBindings[i]._rep->_type)
1157                            {
1158                            case CIMKeyBinding::REFERENCE:
1159                                try
1160                                {
1161                                    // Convert reference to CIMObjectPath and recurse
1162                                    ref._rep->_keyBindings[i]._rep->_value =
1163                                        CIMObjectPath(ref._rep->_keyBindings[i]._rep->_value).
1164                                            _toStringCanonical();
1165                                }
1166                                catch (Exception&)
1167                                {
1168                                    // Leave value unchanged if the CIMObjectPath parsing fails
1169                                }
1170                                break;
1171 kumpf         1.33         case CIMKeyBinding::BOOLEAN:
1172                                // Normalize the boolean string by changing to lower case
1173                                ref._rep->_keyBindings[i]._rep->_value.toLower(); // ICU_TODO:
1174                                break;
1175                            case CIMKeyBinding::NUMERIC:
1176                                // Normalize the numeric string by converting to integer and back
1177                                Uint64 uValue;
1178                                Sint64 sValue;
1179                                // First try converting to unsigned integer
1180                                if (XmlReader::stringToUnsignedInteger(
1181                                        ref._rep->_keyBindings[i]._rep->_value.getCString(),
1182                                            uValue))
1183                                {
1184                                    char buffer[32];  // Should need 21 chars max
1185                                    sprintf(buffer, "%" PEGASUS_64BIT_CONVERSION_WIDTH "u", uValue);
1186                                    ref._rep->_keyBindings[i]._rep->_value = String(buffer);
1187                                }
1188                                // Next try converting to signed integer
1189                                else if (XmlReader::stringToSignedInteger(
1190                                             ref._rep->_keyBindings[i]._rep->_value.getCString(),
1191                                                 sValue))
1192 kumpf         1.33             {
1193                                    char buffer[32];  // Should need 21 chars max
1194                                    sprintf(buffer, "%" PEGASUS_64BIT_CONVERSION_WIDTH "d", sValue);
1195                                    ref._rep->_keyBindings[i]._rep->_value = String(buffer);
1196                                }
1197                                // Leave value unchanged if it cannot be converted to an integer
1198                                break;
1199                            default:  // CIMKeyBinding::STRING
1200                                // No normalization required for STRING
1201                                break;
1202                            }
1203 kumpf         1.2      }
1204                    
1205 kumpf         1.33     // Note: key bindings are sorted when set in the CIMObjectPath
1206 kumpf         1.12 
1207 kumpf         1.15     return ref.toString();
1208 kumpf         1.2  }
1209                    
1210                    Boolean CIMObjectPath::identical(const CIMObjectPath& x) const
1211                    {
1212                        return
1213 kumpf         1.33         String::equalNoCase(_rep->_host, x._rep->_host) &&
1214 kumpf         1.7          _rep->_nameSpace.equal(x._rep->_nameSpace) &&
1215                            _rep->_className.equal(x._rep->_className) &&
1216 kumpf         1.2          _rep->_keyBindings == x._rep->_keyBindings;
1217                    }
1218                    
1219                    Uint32 CIMObjectPath::makeHashCode() const
1220                    {
1221 kumpf         1.12     return HashFunc<String>::hash(_toStringCanonical());
1222 kumpf         1.2  }
1223                    
1224                    Boolean operator==(const CIMObjectPath& x, const CIMObjectPath& y)
1225                    {
1226                        return x.identical(y);
1227                    }
1228                    
1229                    Boolean operator!=(const CIMObjectPath& x, const CIMObjectPath& y)
1230                    {
1231                        return !operator==(x, y);
1232                    }
1233                    
1234 chip          1.1  PEGASUS_NAMESPACE_END

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2