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

   1 mike  1.25 //%/////////////////////////////////////////////////////////////////////////////
   2 mike  1.23 //
   3 kumpf 1.58 // Copyright (c) 2000, 2001, 2002 BMC Software, Hewlett-Packard Company, IBM,
   4 mike  1.25 // The Open Group, Tivoli Systems
   5 mike  1.23 //
   6            // Permission is hereby granted, free of charge, to any person obtaining a copy
   7 kumpf 1.58 // of this software and associated documentation files (the "Software"), to
   8            // deal in the Software without restriction, including without limitation the
   9            // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  10 mike  1.23 // sell copies of the Software, and to permit persons to whom the Software is
  11            // furnished to do so, subject to the following conditions:
  12            // 
  13 kumpf 1.58 // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
  14 mike  1.23 // ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
  15            // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
  16 kumpf 1.58 // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
  17            // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
  18            // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
  19 mike  1.23 // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  20            // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  21            //
  22            //==============================================================================
  23            //
  24            // Author: Mike Brasher (mbrasher@bmc.com)
  25            //
  26 mike  1.25 // Modified By: Carol Ann Krug Graves, Hewlett-Packard Company
  27            //                  (carolann_graves@hp.com)
  28            //              Nitin Upasani, Hewlett-Packard Company (Nitin_Upasani@hp.com)
  29            //              Roger Kumpf, Hewlett-Packard Company (roger_kumpf@hp.com)
  30 mike  1.23 //
  31            //%/////////////////////////////////////////////////////////////////////////////
  32 mday  1.45 #include <Pegasus/Common/Config.h>
  33 mike  1.23 #include <cctype>
  34            #include <cstdio>
  35            #include <cstdlib>
  36 ramnath 1.46 #if defined(PEGASUS_OS_TYPE_UNIX)
  37 mday    1.45 #include <errno.h>
  38              #endif
  39 mike    1.23 #include "CIMName.h"
  40              #include "XmlReader.h"
  41              #include "XmlWriter.h"
  42              #include "CIMQualifier.h"
  43              #include "CIMQualifierDecl.h"
  44              #include "CIMClass.h"
  45              #include "CIMInstance.h"
  46              #include "CIMObject.h"
  47 mike    1.25 #include "CIMParamValue.h"
  48 mike    1.23 
  49 mike    1.25 PEGASUS_USING_STD;
  50 mike    1.23 PEGASUS_NAMESPACE_BEGIN
  51              
  52              static const Uint32 MESSAGE_SIZE = 128;
  53              
  54              //------------------------------------------------------------------------------
  55              //
  56 kumpf   1.49 // getXmlDeclaration()
  57              //
  58              //     <?xml version="1.0" encoding="utf-8"?>
  59 mike    1.23 //
  60              //------------------------------------------------------------------------------
  61              
  62 kumpf   1.49 void XmlReader::getXmlDeclaration(
  63 mike    1.23     XmlParser& parser, 
  64 kumpf   1.49     const char*& xmlVersion,
  65                  const char*& xmlEncoding)
  66 mike    1.23 {
  67 kumpf   1.49     XmlEntry entry;
  68              
  69 mike    1.23     if (!parser.next(entry) ||
  70              	entry.type != XmlEntry::XML_DECLARATION ||
  71              	strcmp(entry.text, "xml") != 0)
  72                  {
  73              	throw XmlValidationError(parser.getLine(),
  74              	    "Expected <?xml ... ?> style declaration");
  75 kumpf   1.49     }
  76              
  77                  if (!entry.getAttributeValue("version", xmlVersion))
  78              	throw XmlValidationError(
  79              	    parser.getLine(), "missing xml.version attribute");
  80              
  81                  if (!entry.getAttributeValue("encoding", xmlEncoding))
  82                  {
  83                      // ATTN-RK-P3-20020403:  Is there a default encoding?
  84 mike    1.23     }
  85              }
  86              
  87              //------------------------------------------------------------------------------
  88              //
  89 mike    1.25 //  testXmlDeclaration ()
  90              //
  91              //------------------------------------------------------------------------------
  92              
  93              Boolean XmlReader::testXmlDeclaration (
  94                  XmlParser& parser,
  95                  XmlEntry& entry)
  96              {
  97                  if (!parser.next (entry) ||
  98                      entry.type != XmlEntry::XML_DECLARATION ||
  99                      strcmp (entry.text, "xml") != 0)
 100                  {
 101                      parser.putBack (entry);
 102                      return false;
 103                  }
 104              
 105                  return true;
 106              }
 107              
 108              //------------------------------------------------------------------------------
 109              //
 110 mike    1.23 // expectStartTag()
 111              //
 112              //------------------------------------------------------------------------------
 113              
 114              void XmlReader::expectStartTag(
 115                  XmlParser& parser, 
 116                  XmlEntry& entry,
 117                  const char* tagName)
 118              {
 119                  if (!parser.next(entry) ||
 120              	entry.type != XmlEntry::START_TAG ||
 121              	strcmp(entry.text, tagName) != 0)
 122                  {
 123              	char message[MESSAGE_SIZE];
 124              	sprintf(message, "Expected open of %s element", tagName);
 125              	throw XmlValidationError(parser.getLine(), message);
 126                  }
 127              }
 128              
 129              //------------------------------------------------------------------------------
 130              //
 131 mike    1.23 // expectEndTag()
 132              //
 133              //------------------------------------------------------------------------------
 134              
 135              void XmlReader::expectEndTag(XmlParser& parser, const char* tagName)
 136              {
 137                  XmlEntry entry;
 138              
 139                  if (!parser.next(entry) ||
 140              	entry.type != XmlEntry::END_TAG ||
 141              	strcmp(entry.text, tagName) != 0)
 142                  {
 143              	char message[MESSAGE_SIZE];
 144              	sprintf(message, "Expected close of %s element, got %s instead",
 145                            tagName,entry.text);
 146              	throw XmlValidationError(parser.getLine(), message);
 147                  }
 148              }
 149              
 150              //------------------------------------------------------------------------------
 151              //
 152 mike    1.23 // expectStartTagOrEmptyTag()
 153              //
 154              //------------------------------------------------------------------------------
 155              
 156              void XmlReader::expectStartTagOrEmptyTag(
 157                  XmlParser& parser, 
 158                  XmlEntry& entry,
 159                  const char* tagName)
 160              {
 161                  if (!parser.next(entry) ||
 162              	(entry.type != XmlEntry::START_TAG &&
 163              	entry.type != XmlEntry::EMPTY_TAG) ||
 164              	strcmp(entry.text, tagName) != 0)
 165                  {
 166              	char message[MESSAGE_SIZE];
 167              	sprintf(message, 
 168              	    "Expected either open or open/close %s element", tagName);
 169              	throw XmlValidationError(parser.getLine(), message);
 170                  }
 171              }
 172              
 173 mike    1.23 //------------------------------------------------------------------------------
 174              //
 175              // expectContentOrCData()
 176              //
 177              //------------------------------------------------------------------------------
 178              
 179              Boolean XmlReader::expectContentOrCData(
 180                  XmlParser& parser, 
 181                  XmlEntry& entry)
 182              {
 183                  if (!parser.next(entry) ||
 184              	(entry.type != XmlEntry::CONTENT &&
 185              	entry.type != XmlEntry::CDATA))
 186                  {
 187              	throw XmlValidationError(parser.getLine(),
 188              	    "Expected content of CDATA");
 189                  }
 190              
 191                  return true;
 192              }
 193              
 194 mike    1.23 //------------------------------------------------------------------------------
 195              //
 196              // testStartTag()
 197              //
 198              //------------------------------------------------------------------------------
 199              
 200              Boolean XmlReader::testStartTag(
 201                  XmlParser& parser, 
 202                  XmlEntry& entry,
 203                  const char* tagName)
 204              {
 205                  if (!parser.next(entry) ||
 206              	entry.type != XmlEntry::START_TAG ||
 207              	strcmp(entry.text, tagName) != 0)
 208                  {
 209              	parser.putBack(entry);
 210              	return false;
 211                  }
 212              
 213                  return true;
 214              }
 215 mike    1.23 
 216              //------------------------------------------------------------------------------
 217              //
 218 kumpf   1.48 // testEndTag()
 219 mike    1.23 //
 220              //------------------------------------------------------------------------------
 221              
 222              Boolean XmlReader::testEndTag(XmlParser& parser, const char* tagName)
 223              {
 224                  XmlEntry entry;
 225              
 226                  if (!parser.next(entry) ||
 227              	entry.type != XmlEntry::END_TAG ||
 228              	strcmp(entry.text, tagName) != 0)
 229                  {
 230              	parser.putBack(entry);
 231              	return false;
 232                  }
 233              
 234                  return true;
 235              }
 236              
 237              //------------------------------------------------------------------------------
 238              //
 239              // testStartTagOrEmptyTag()
 240 mike    1.23 //
 241              //------------------------------------------------------------------------------
 242              
 243              Boolean XmlReader::testStartTagOrEmptyTag(
 244                  XmlParser& parser, 
 245                  XmlEntry& entry,
 246                  const char* tagName)
 247              {
 248                  if (!parser.next(entry) ||
 249              	(entry.type != XmlEntry::START_TAG &&
 250              	entry.type != XmlEntry::EMPTY_TAG) ||
 251              	strcmp(entry.text, tagName) != 0)
 252                  {
 253              	parser.putBack(entry);
 254              	return false;
 255                  }
 256              
 257                  return true;
 258              }
 259              
 260              //------------------------------------------------------------------------------
 261 mike    1.23 //
 262              // testContentOrCData()
 263              //
 264              //------------------------------------------------------------------------------
 265              
 266              Boolean XmlReader::testContentOrCData(
 267                  XmlParser& parser, 
 268                  XmlEntry& entry)
 269              {
 270                  if (!parser.next(entry) ||
 271              	(entry.type != XmlEntry::CONTENT &&
 272              	entry.type != XmlEntry::CDATA))
 273                  {
 274              	parser.putBack(entry);
 275              	return false;
 276                  }
 277              
 278                  return true;
 279              }
 280              
 281              //------------------------------------------------------------------------------
 282 mike    1.23 //
 283 kumpf   1.34 // getCimStartTag()
 284 mike    1.23 //
 285              //     <!ELEMENT CIM (MESSAGE|DECLARATION)>
 286              //     <!ATTRLIST CIM 
 287              //         CIMVERSION CDATA #REQUIRED
 288              //         DTDVERSION CDATA #REQUIRED>
 289              //
 290              //------------------------------------------------------------------------------
 291              
 292 kumpf   1.34 void XmlReader::getCimStartTag(
 293                  XmlParser& parser, 
 294                  const char*& cimVersion,
 295                  const char*& dtdVersion)
 296 mike    1.23 {
 297                  XmlEntry entry;
 298                  XmlReader::expectStartTag(parser, entry, "CIM");
 299              
 300                  if (!entry.getAttributeValue("CIMVERSION", cimVersion))
 301              	throw XmlValidationError(
 302              	    parser.getLine(), "missing CIM.CIMVERSION attribute");
 303              
 304                  if (!entry.getAttributeValue("DTDVERSION", dtdVersion))
 305              	throw XmlValidationError(
 306              	    parser.getLine(), "missing CIM.DTDVERSION attribute");
 307              }
 308              
 309              //------------------------------------------------------------------------------
 310              //
 311              // getCimNameAttribute()
 312              //
 313              //     <!ENTITY % CIMName "NAME CDATA #REQUIRED">
 314              //
 315              //------------------------------------------------------------------------------
 316              
 317 mike    1.23 String XmlReader::getCimNameAttribute(
 318                  Uint32 lineNumber, 
 319                  const XmlEntry& entry,
 320                  const char* elementName,
 321                  Boolean acceptNull)
 322              {
 323                  String name;
 324              
 325                  if (!entry.getAttributeValue("NAME", name))
 326                  {
 327              	char buffer[MESSAGE_SIZE];
 328              	sprintf(buffer, "missing %s.NAME attribute", elementName);
 329              	throw XmlValidationError(lineNumber, buffer);
 330                  }
 331              
 332                  if (acceptNull && name.size() == 0)
 333              	return name;
 334              
 335                  if (!CIMName::legal(name))
 336                  {
 337              	char buffer[MESSAGE_SIZE];
 338 mike    1.23 	sprintf(buffer, "Illegal value for %s.NAME attribute", elementName);
 339              	throw XmlSemanticError(lineNumber, buffer);
 340                  }
 341              
 342                  return name;
 343              }
 344              
 345              //------------------------------------------------------------------------------
 346              //
 347              // getClassNameAttribute()
 348              //
 349              //     <!ENTITY % CIMName "CLASSNAME CDATA #REQUIRED">
 350              //
 351              //------------------------------------------------------------------------------
 352              
 353              String XmlReader::getClassNameAttribute(
 354                  Uint32 lineNumber, 
 355                  const XmlEntry& entry,
 356                  const char* elementName)
 357              {
 358                  String name;
 359 mike    1.23 
 360                  if (!entry.getAttributeValue("CLASSNAME", name))
 361                  {
 362              	char buffer[MESSAGE_SIZE];
 363              	sprintf(buffer, "missing %s.CLASSNAME attribute", elementName);
 364              	throw XmlValidationError(lineNumber, buffer);
 365                  }
 366              
 367                  if (!CIMName::legal(name))
 368                  {
 369              	char buffer[MESSAGE_SIZE];
 370              	sprintf(buffer, 
 371              	    "Illegal value for %s.CLASSNAME attribute", elementName);
 372              	throw XmlSemanticError(lineNumber, buffer);
 373                  }
 374              
 375                  return name;
 376              }
 377              
 378              //------------------------------------------------------------------------------
 379              //
 380 mike    1.23 // getClassOriginAttribute()
 381              //
 382              //     <!ENTITY % ClassOrigin "CLASSORIGIN CDATA #IMPLIED">
 383              //
 384              //------------------------------------------------------------------------------
 385              
 386 kumpf   1.62 CIMName XmlReader::getClassOriginAttribute(
 387 mike    1.23     Uint32 lineNumber, 
 388                  const XmlEntry& entry,
 389                  const char* tagName)
 390              {
 391                  String name;
 392              
 393                  if (!entry.getAttributeValue("CLASSORIGIN", name))
 394 kumpf   1.62 	return CIMName();
 395 mike    1.23 
 396                  if (!CIMName::legal(name))
 397                  {
 398              	char buffer[MESSAGE_SIZE];
 399              	sprintf(buffer, 
 400              	    "Illegal value for %s.CLASSORIGIN attribute", tagName);
 401              	throw XmlSemanticError(lineNumber, buffer);
 402                  }
 403              
 404                  return name;
 405              }
 406              
 407              //------------------------------------------------------------------------------
 408              //
 409              // getReferenceClassAttribute()
 410              //
 411              //     <!ENTITY % ReferenceClass "REFERENCECLASS CDATA #IMPLIED">
 412              //
 413              //------------------------------------------------------------------------------
 414              
 415 kumpf   1.62 CIMName XmlReader::getReferenceClassAttribute(
 416 mike    1.23     Uint32 lineNumber, 
 417                  const XmlEntry& entry,
 418                  const char* elementName)
 419              {
 420                  String name;
 421              
 422                  if (!entry.getAttributeValue("REFERENCECLASS", name))
 423 kumpf   1.62 	return CIMName();
 424 mike    1.23 
 425                  if (!CIMName::legal(name))
 426                  {
 427              	char buffer[MESSAGE_SIZE];
 428              	sprintf(buffer, 
 429              	    "Illegal value for %s.REFERENCECLASS attribute", elementName);
 430              	throw XmlSemanticError(lineNumber, buffer);
 431                  }
 432              
 433                  return name;
 434              }
 435              
 436              //------------------------------------------------------------------------------
 437              //
 438              // getSuperClassAttribute()
 439              //
 440              //     <!ENTITY % SuperClass "SUPERCLASS CDATA #IMPLIED">
 441              //
 442              //------------------------------------------------------------------------------
 443              
 444 kumpf   1.62 CIMName XmlReader::getSuperClassAttribute(
 445 mike    1.23     Uint32 lineNumber, 
 446                  const XmlEntry& entry,
 447                  const char* tagName)
 448              {
 449                  String superClass;
 450              
 451                  if (!entry.getAttributeValue("SUPERCLASS", superClass))
 452 kumpf   1.62 	return CIMName();
 453 mike    1.23 
 454                  if (!CIMName::legal(superClass))
 455                  {
 456              	char buffer[MESSAGE_SIZE];
 457              	sprintf(
 458              	    buffer, "Illegal value for %s.SUPERCLASS attribute", tagName);
 459              	throw XmlSemanticError(lineNumber, buffer);
 460                  }
 461              
 462                  return superClass;
 463              }
 464              
 465              //------------------------------------------------------------------------------
 466              //
 467              // getCimTypeAttribute()
 468              //
 469 kumpf   1.26 // This method can be used to get a TYPE attribute or a PARAMTYPE attribute.
 470              // The only significant difference is that PARAMTYPE may specify a value of
 471              // "reference" type.  This method recognizes these attributes by name, and
 472              // does not allow a "TYPE" attribute to be of "reference" type.
 473              //
 474 mike    1.23 //     <!ENTITY % CIMType "TYPE (boolean|string|char16|uint8|sint8|uint16
 475              //         |sint16|uint32|sint32|uint64|sint64|datetime|real32|real64)">
 476              //
 477 kumpf   1.26 //     <!ENTITY % ParamType "PARAMTYPE (boolean|string|char16|uint8|sint8
 478              //         |uint16|sint16|uint32|sint32|uint64|sint64|datetime|real32|real64
 479              //         |reference)">
 480              //
 481 mike    1.23 //------------------------------------------------------------------------------
 482              
 483 kumpf   1.67 Boolean XmlReader::getCimTypeAttribute(
 484 mike    1.23     Uint32 lineNumber, 
 485                  const XmlEntry& entry, 
 486 kumpf   1.67     CIMType& cimType,  // Output parameter
 487 kumpf   1.26     const char* tagName,
 488                  const char* attributeName,
 489                  Boolean required)
 490 mike    1.23 {
 491                  const char* typeName;
 492              
 493 kumpf   1.26     if (!entry.getAttributeValue(attributeName, typeName))
 494 mike    1.23     {
 495 kumpf   1.26         if (required)
 496              	{
 497              	    char message[MESSAGE_SIZE];
 498              	    sprintf(message, "missing %s.%s attribute", tagName, attributeName);
 499              	    throw XmlValidationError(lineNumber, message);
 500              	}
 501              	else
 502              	{
 503 kumpf   1.67 	    return false;
 504 kumpf   1.26 	}
 505 mike    1.23     }
 506              
 507 kumpf   1.67     CIMType type = CIMTYPE_BOOLEAN;
 508                  Boolean unrecognizedType = false;
 509 mike    1.23 
 510                  if (strcmp(typeName, "boolean") == 0)
 511 kumpf   1.61 	type = CIMTYPE_BOOLEAN;
 512 mike    1.23     else if (strcmp(typeName, "string") == 0)
 513 kumpf   1.61 	type = CIMTYPE_STRING;
 514 mike    1.23     else if (strcmp(typeName, "char16") == 0)
 515 kumpf   1.61 	type = CIMTYPE_CHAR16;
 516 mike    1.23     else if (strcmp(typeName, "uint8") == 0)
 517 kumpf   1.61 	type = CIMTYPE_UINT8;
 518 mike    1.23     else if (strcmp(typeName, "sint8") == 0)
 519 kumpf   1.61 	type = CIMTYPE_SINT8;
 520 mike    1.23     else if (strcmp(typeName, "uint16") == 0)
 521 kumpf   1.61 	type = CIMTYPE_UINT16;
 522 mike    1.23     else if (strcmp(typeName, "sint16") == 0)
 523 kumpf   1.61 	type = CIMTYPE_SINT16;
 524 mike    1.23     else if (strcmp(typeName, "uint32") == 0)
 525 kumpf   1.61 	type = CIMTYPE_UINT32;
 526 mike    1.23     else if (strcmp(typeName, "sint32") == 0)
 527 kumpf   1.61 	type = CIMTYPE_SINT32;
 528 mike    1.23     else if (strcmp(typeName, "uint64") == 0)
 529 kumpf   1.61 	type = CIMTYPE_UINT64;
 530 mike    1.23     else if (strcmp(typeName, "sint64") == 0)
 531 kumpf   1.61 	type = CIMTYPE_SINT64;
 532 mike    1.23     else if (strcmp(typeName, "datetime") == 0)
 533 kumpf   1.61 	type = CIMTYPE_DATETIME;
 534 mike    1.23     else if (strcmp(typeName, "real32") == 0)
 535 kumpf   1.61 	type = CIMTYPE_REAL32;
 536 mike    1.23     else if (strcmp(typeName, "real64") == 0)
 537 kumpf   1.61 	type = CIMTYPE_REAL64;
 538 kumpf   1.26     else if (strcmp(typeName, "reference") == 0)
 539 kumpf   1.61 	type = CIMTYPE_REFERENCE;
 540 kumpf   1.67     else unrecognizedType = true;
 541 mike    1.23 
 542 kumpf   1.67     if (unrecognizedType ||
 543 kumpf   1.61         ((type == CIMTYPE_REFERENCE) &&
 544 kumpf   1.26          (strcmp(attributeName, "PARAMTYPE") != 0)))
 545 mike    1.23     {
 546              	char message[MESSAGE_SIZE];
 547 kumpf   1.26 	sprintf(message, "Illegal value for %s.%s attribute", tagName,
 548              	        attributeName);
 549 mike    1.23 	throw XmlSemanticError(lineNumber, message);
 550                  }
 551              
 552 kumpf   1.67     cimType = type;
 553                  return true;
 554 mike    1.23 }
 555              
 556              //------------------------------------------------------------------------------
 557              //
 558              // getCimBooleanAttribute()
 559              //
 560              //------------------------------------------------------------------------------
 561              
 562              Boolean XmlReader::getCimBooleanAttribute(
 563                  Uint32 lineNumber,
 564                  const XmlEntry& entry,
 565                  const char* tagName,
 566                  const char* attributeName,
 567                  Boolean defaultValue,
 568                  Boolean required)
 569              {
 570                  const char* tmp;
 571              
 572                  if (!entry.getAttributeValue(attributeName, tmp))
 573                  {
 574              	if (!required)
 575 mike    1.23 	    return defaultValue;
 576              
 577              	char buffer[62];
 578              	sprintf(buffer, "missing required %s.%s attribute", 
 579              	    attributeName, tagName);
 580              
 581              	throw XmlValidationError(lineNumber, buffer);
 582                  }
 583              
 584                  if (strcmp(tmp, "true") == 0)
 585              	return true;
 586                  else if (strcmp(tmp, "false") == 0)
 587              	return false;
 588              
 589                  char buffer[62];
 590 kumpf   1.66     sprintf(buffer, "Invalid %s.%s attribute value", attributeName, tagName);
 591 mike    1.23     throw XmlSemanticError(lineNumber, buffer);
 592                  return false;
 593              }
 594              
 595              //------------------------------------------------------------------------------
 596              //
 597              // SringToReal()
 598              //
 599              //	[ "+" | "-" ] *decimalDigit "." 1*decimalDigit 
 600              //	    [ ( "e" | "E" ) [ "+" | "-" ] 1*decimalDigit ]
 601              //
 602              //------------------------------------------------------------------------------
 603              
 604              Boolean XmlReader::stringToReal(const char* stringValue, Real64& x)
 605              {
 606 kumpf   1.43     //
 607                  // Check the string against the DMTF-defined grammar
 608                  //
 609 mike    1.23     const char* p = stringValue;
 610              
 611                  if (!*p)
 612              	return false;
 613              
 614                  // Skip optional sign:
 615              
 616                  if (*p == '+' || *p  == '-')
 617              	p++;
 618              
 619                  // Skip optional first set of digits:
 620              
 621                  while (isdigit(*p))
 622              	p++;
 623              
 624                  // Test required dot:
 625              
 626                  if (*p++ != '.')
 627              	return false;
 628              
 629                  // One or more digits required:
 630 mike    1.23 
 631                  if (!isdigit(*p++))
 632              	return false;
 633              
 634                  while (isdigit(*p))
 635              	p++;
 636              
 637                  // If there is an exponent now:
 638              
 639                  if (*p)
 640                  {
 641              	// Test exponent:
 642              
 643              	if (*p != 'e' && *p != 'E')
 644              	    return false;
 645              
 646              	p++;
 647              
 648              	// Skip optional sign:
 649              
 650              	if (*p == '+' || *p  == '-')
 651 mike    1.23 	    p++;
 652              
 653              	// One or more digits required:
 654              
 655              	if (!isdigit(*p++))
 656              	    return false;
 657              
 658              	while (isdigit(*p))
 659              	    p++;
 660                  }
 661              
 662                  if (*p)
 663              	return false;
 664              
 665 kumpf   1.43     //
 666                  // Do the conversion
 667                  //
 668 mike    1.23     char* end;
 669 kumpf   1.43     errno = 0;
 670 mike    1.23     x = strtod(stringValue, &end);
 671 kumpf   1.43     if (*end || (errno == ERANGE))
 672                  {
 673                      return false;
 674                  }
 675              
 676 mike    1.23     return true;
 677              }
 678              
 679 kumpf   1.41 inline Uint8 _hexCharToNumeric(const char c)
 680              {
 681                  Uint8 n;
 682              
 683                  if (isdigit(c))
 684                      n = (c - '0');
 685                  else if (isupper(c))
 686                      n = (c - 'A' + 10);
 687                  else // if (islower(c))
 688                      n = (c - 'a' + 10);
 689              
 690                  return n;
 691              }
 692              
 693 mike    1.23 //------------------------------------------------------------------------------
 694              //
 695              // stringToSignedInteger
 696              //
 697              //	[ "+" | "-" ] ( positiveDecimalDigit *decimalDigit | "0" )
 698 kumpf   1.41 //    or
 699              //      [ "+" | "-" ] ( "0x" | "0X" ) 1*hexDigit
 700 mike    1.23 //
 701              //------------------------------------------------------------------------------
 702              
 703              Boolean XmlReader::stringToSignedInteger(
 704                  const char* stringValue, 
 705                  Sint64& x)
 706              {
 707                  x = 0;
 708                  const char* p = stringValue;
 709              
 710 kumpf   1.41     if (!p || !*p)
 711 mike    1.23 	return false;
 712              
 713                  // Skip optional sign:
 714              
 715                  Boolean negative = *p == '-';
 716              
 717                  if (negative || *p == '+')
 718              	p++;
 719              
 720                  if (*p == '0')
 721 kumpf   1.41     {
 722                      if ( (p[1] == 'x') || (p[1] == 'X') )
 723                      {
 724                          // Convert a hexadecimal string
 725 mike    1.23 
 726 kumpf   1.41             // Skip over the "0x"
 727                          p+=2;
 728 mike    1.23 
 729 kumpf   1.41             // At least one hexadecimal digit is required
 730                          if (!isxdigit(*p))
 731                              return false;
 732              
 733                          // Build the Sint64 as a negative number, regardless of the
 734                          // eventual sign (negative numbers can be bigger than positive ones)
 735              
 736                          // Add on each digit, checking for overflow errors
 737                          while (isxdigit(*p))
 738                          {
 739                              // Make sure we won't overflow when we multiply by 16
 740                              if (x < PEGASUS_LLONG_MIN/16)
 741                              {
 742                                  return false;
 743                              }
 744                              x = x << 4;
 745              
 746                              // Make sure we don't overflow when we add the next digit
 747                              Sint64 newDigit = Sint64(_hexCharToNumeric(*p++));
 748                              if (PEGASUS_LLONG_MIN - x > -newDigit)
 749                              {
 750 kumpf   1.41                     return false;
 751                              }
 752                              x = x - newDigit;
 753                          }
 754              
 755                          // If we found a non-hexadecimal digit, report an error
 756                          if (*p)
 757                              return false;
 758              
 759                          // Return the integer to positive, if necessary, checking for an
 760                          // overflow error
 761                          if (!negative)
 762                          {
 763                              if (x == PEGASUS_LLONG_MIN)
 764                              {
 765                                  return false;
 766                              }
 767                              x = -x;
 768                          }
 769                          return true;
 770                      }
 771 kumpf   1.41         else
 772                      {
 773                          // A decimal string that starts with '0' must be exactly "0".
 774              	    return p[1] == '\0';
 775                      }
 776                  }
 777 mike    1.23 
 778 kumpf   1.41     // Expect a positive decimal digit:
 779 mike    1.23 
 780 kumpf   1.41     // At least one decimal digit is required
 781                  if (!isdigit(*p))
 782                      return false;
 783              
 784                  // Build the Sint64 as a negative number, regardless of the
 785                  // eventual sign (negative numbers can be bigger than positive ones)
 786 mike    1.23 
 787 kumpf   1.41     // Add on each digit, checking for overflow errors
 788 mike    1.23     while (isdigit(*p))
 789 kumpf   1.37     {
 790 kumpf   1.41         // Make sure we won't overflow when we multiply by 10
 791 kumpf   1.39         if (x < PEGASUS_LLONG_MIN/10)
 792 kumpf   1.37         {
 793                          return false;
 794                      }
 795                      x = 10 * x;
 796 kumpf   1.41 
 797                      // Make sure we won't overflow when we add the next digit
 798                      Sint64 newDigit = (*p++ - '0');
 799 mday    1.38         if (PEGASUS_LLONG_MIN - x > -newDigit)
 800 kumpf   1.37         {
 801                          return false;
 802                      }
 803 kumpf   1.41         x = x - newDigit;
 804 kumpf   1.37     }
 805 mike    1.23 
 806 kumpf   1.41     // If we found a non-decimal digit, report an error
 807                  if (*p)
 808              	return false;
 809              
 810                  // Return the integer to positive, if necessary, checking for an
 811                  // overflow error
 812 kumpf   1.37     if (!negative)
 813                  {
 814 mday    1.38         if (x == PEGASUS_LLONG_MIN)
 815 kumpf   1.37         {
 816                          return false;
 817                      }
 818 kumpf   1.41         x = -x;
 819 kumpf   1.37     }
 820 mike    1.23     return true;
 821              }
 822              
 823              //------------------------------------------------------------------------------
 824              //
 825              // stringToUnsignedInteger
 826              //
 827 kumpf   1.40 //	( positiveDecimalDigit *decimalDigit | "0" )
 828 kumpf   1.41 //    or
 829              //      ( "0x" | "0X" ) 1*hexDigit
 830 mike    1.23 //
 831              //------------------------------------------------------------------------------
 832              
 833              Boolean XmlReader::stringToUnsignedInteger(
 834                  const char* stringValue, 
 835                  Uint64& x)
 836              {
 837                  x = 0;
 838                  const char* p = stringValue;
 839              
 840 kumpf   1.41     if (!p || !*p)
 841 mike    1.23 	return false;
 842              
 843                  if (*p == '0')
 844 kumpf   1.41     {
 845                      if ( (p[1] == 'x') || (p[1] == 'X') )
 846                      {
 847                          // Convert a hexadecimal string
 848 mike    1.23 
 849 kumpf   1.41             // Skip over the "0x"
 850                          p+=2;
 851 mike    1.23 
 852 kumpf   1.41             // At least one hexadecimal digit is required
 853                          if (!*p)
 854                              return false;
 855              
 856                          // Add on each digit, checking for overflow errors
 857                          while (isxdigit(*p))
 858                          {
 859                              // Make sure we won't overflow when we multiply by 16
 860                              if (x > PEGASUS_ULLONG_MAX/16)
 861                              {
 862                                  return false;
 863                              }
 864                              x = x << 4;
 865              
 866                              // We can't overflow when we add the next digit
 867                              Uint64 newDigit = Uint64(_hexCharToNumeric(*p++));
 868                              if (PEGASUS_ULLONG_MAX - x < newDigit)
 869                              {
 870                                  return false;
 871                              }
 872                              x = x + newDigit;
 873 kumpf   1.41             }
 874              
 875                          // If we found a non-hexadecimal digit, report an error
 876                          if (*p)
 877                              return false;
 878 mike    1.23 
 879 kumpf   1.41             return true;
 880                      }
 881                      else
 882                      {
 883                          // A decimal string that starts with '0' must be exactly "0".
 884              	    return p[1] == '\0';
 885                      }
 886                  }
 887 mike    1.23 
 888 kumpf   1.41     // Expect a positive decimal digit:
 889 mike    1.23 
 890 kumpf   1.41     // Add on each digit, checking for overflow errors
 891 mike    1.23     while (isdigit(*p))
 892 kumpf   1.37     {
 893 kumpf   1.41         // Make sure we won't overflow when we multiply by 10
 894 kumpf   1.39         if (x > PEGASUS_ULLONG_MAX/10)
 895 kumpf   1.37         {
 896                          return false;
 897                      }
 898                      x = 10 * x;
 899 kumpf   1.41 
 900                      // Make sure we won't overflow when we add the next digit
 901                      Uint64 newDigit = (*p++ - '0');
 902 kumpf   1.39         if (PEGASUS_ULLONG_MAX - x < newDigit)
 903 kumpf   1.37         {
 904                          return false;
 905                      }
 906 kumpf   1.41         x = x + newDigit;
 907 kumpf   1.37     }
 908 kumpf   1.41 
 909                  // If we found a non-decimal digit, report an error
 910                  if (*p)
 911              	return false;
 912 mike    1.23 
 913                  return true;
 914              }
 915              
 916              //------------------------------------------------------------------------------
 917              //
 918              // stringToValue()
 919              //
 920 karl    1.35 // Return: CIMValue. If the string input is zero length creates a CIMValue
 921              //         with value defined by the type.  Else the value is inserted.
 922              //         
 923              //         Note that this does not set the CIMValue Null if the string is empty.
 924              //
 925 mike    1.23 //------------------------------------------------------------------------------
 926              
 927              CIMValue XmlReader::stringToValue(
 928                  Uint32 lineNumber, 
 929                  const char* valueString, 
 930                  CIMType type)
 931              {
 932                  // ATTN-B: accepting only UTF-8 for now! (affects string and char16):
 933              
 934 karl    1.35     // Create value per type
 935 mike    1.23     switch (type)
 936                  {
 937 kumpf   1.61 	case CIMTYPE_BOOLEAN:
 938 mike    1.23 	{
 939              	    if (CompareNoCase(valueString, "TRUE") == 0)
 940              		return CIMValue(true);
 941              	    else if (CompareNoCase(valueString, "FALSE") == 0)
 942              		return CIMValue(false);
 943              	    else
 944              		throw XmlSemanticError(
 945 kumpf   1.66 		    lineNumber, "Invalid boolean value");
 946 mike    1.23 	}
 947              
 948 kumpf   1.61 	case CIMTYPE_STRING:
 949 mike    1.23 	{
 950 kumpf   1.60 	    return CIMValue(String(valueString));
 951 mike    1.23 	}
 952              
 953 kumpf   1.61 	case CIMTYPE_CHAR16:
 954 mike    1.23 	{
 955              	    if (strlen(valueString) != 1)
 956 kumpf   1.66 		throw XmlSemanticError(lineNumber, "Invalid char16 value");
 957 mike    1.23 
 958              	    return CIMValue(Char16(valueString[0]));
 959              	}
 960              
 961 kumpf   1.61 	case CIMTYPE_UINT8:
 962              	case CIMTYPE_UINT16:
 963              	case CIMTYPE_UINT32:
 964              	case CIMTYPE_UINT64:
 965 mike    1.23 	{
 966              	    Uint64 x;
 967              
 968              	    if (!stringToUnsignedInteger(valueString, x))
 969              	    {
 970              		throw XmlSemanticError(
 971 kumpf   1.66 		    lineNumber, "Invalid unsigned integer value");
 972 mike    1.23 	    }
 973              
 974              	    switch (type)
 975              	    {
 976 kumpf   1.61 		case CIMTYPE_UINT8:
 977 kumpf   1.37                 {
 978                                  if (x >= (Uint64(1)<<8))
 979              		    {
 980              			throw XmlSemanticError(
 981              			    lineNumber, "Uint8 value out of range");
 982              		    }
 983              		    return CIMValue(Uint8(x));
 984                              }
 985 kumpf   1.61 		case CIMTYPE_UINT16:
 986 kumpf   1.37                 {
 987                                  if (x >= (Uint64(1)<<16))
 988              		    {
 989              			throw XmlSemanticError(
 990              			    lineNumber, "Uint16 value out of range");
 991              		    }
 992              		    return CIMValue(Uint16(x));
 993                              }
 994 kumpf   1.61 		case CIMTYPE_UINT32:
 995 kumpf   1.37                 {
 996                                  if (x >= (Uint64(1)<<32))
 997              		    {
 998              			throw XmlSemanticError(
 999              			    lineNumber, "Uint32 value out of range");
1000              		    }
1001              		    return CIMValue(Uint32(x));
1002                              }
1003 kumpf   1.61 		case CIMTYPE_UINT64: return CIMValue(Uint64(x));
1004 mike    1.23 		default: break;
1005              	    }
1006              	}
1007              
1008 kumpf   1.61 	case CIMTYPE_SINT8:
1009              	case CIMTYPE_SINT16:
1010              	case CIMTYPE_SINT32:
1011              	case CIMTYPE_SINT64:
1012 mike    1.23 	{
1013              	    Sint64 x;
1014              
1015              	    if (!stringToSignedInteger(valueString, x))
1016              	    {
1017              		throw XmlSemanticError(
1018 kumpf   1.66 		    lineNumber, "Invalid signed integer value");
1019 mike    1.23 	    }
1020              
1021              	    switch (type)
1022              	    {
1023 kumpf   1.61 		case CIMTYPE_SINT8:
1024 kumpf   1.37                 {
1025                                  if(  (x >= (Sint64(1)<<7)) || (x < (-(Sint64(1)<<7))) )
1026              		    {
1027              			throw XmlSemanticError(
1028              			    lineNumber, "Sint8 value out of range");
1029              		    }
1030              		    return CIMValue(Sint8(x));
1031                              }
1032 kumpf   1.61 		case CIMTYPE_SINT16:
1033 kumpf   1.37                 {
1034                                  if(  (x >= (Sint64(1)<<15)) || (x < (-(Sint64(1)<<15))) )
1035              		    {
1036              			throw XmlSemanticError(
1037              			    lineNumber, "Sint16 value out of range");
1038              		    }
1039              		    return CIMValue(Sint16(x));
1040                              }
1041 kumpf   1.61 		case CIMTYPE_SINT32:
1042 kumpf   1.37                 {
1043                                  if(  (x >= (Sint64(1)<<31)) || (x < (-(Sint64(1)<<31))) )
1044              		    {
1045              			throw XmlSemanticError(
1046              			    lineNumber, "Sint32 value out of range");
1047              		    }
1048              		    return CIMValue(Sint32(x));
1049                              }
1050 kumpf   1.61 		case CIMTYPE_SINT64: return CIMValue(Sint64(x));
1051 mike    1.23 		default: break;
1052              	    }
1053              	}
1054              
1055 kumpf   1.61 	case CIMTYPE_DATETIME:
1056 mike    1.23 	{
1057              	    CIMDateTime tmp;
1058              
1059              	    try
1060              	    {
1061              		tmp.set(valueString);
1062              	    }
1063 kumpf   1.66 	    catch (InvalidDateTimeFormatException&)
1064 mike    1.23 	    {
1065 kumpf   1.66 		throw XmlSemanticError(lineNumber, "Invalid datetime value");
1066 mike    1.23 	    }
1067              
1068              	    return CIMValue(tmp);
1069              	}
1070              
1071 kumpf   1.61 	case CIMTYPE_REAL32:
1072 mike    1.23 	{
1073              	    Real64 x;
1074              
1075              	    if (!stringToReal(valueString, x))
1076 kumpf   1.66 		throw XmlSemanticError(lineNumber, "Invalid real number value");
1077 mike    1.23 
1078              	    return CIMValue(Real32(x));
1079              	}
1080              
1081 kumpf   1.61 	case CIMTYPE_REAL64:
1082 mike    1.23 	{
1083              	    Real64 x;
1084              
1085              	    if (!stringToReal(valueString, x))
1086 kumpf   1.66 		throw XmlSemanticError(lineNumber, "Invalid real number value");
1087 mike    1.23 
1088              	    return CIMValue(x);
1089              	}
1090              
1091              	default:
1092              	    break;
1093                  }
1094              
1095                  throw XmlSemanticError(lineNumber, "malformed XML");
1096                  return false;
1097              }
1098              
1099              //------------------------------------------------------------------------------
1100              //
1101              // getValueElement()
1102              //
1103              //     <!ELEMENT VALUE (#PCDATA)>
1104              //
1105 karl    1.35 // Return: false if no value element.
1106              //
1107 mike    1.23 //------------------------------------------------------------------------------
1108              
1109              Boolean XmlReader::getValueElement(
1110                  XmlParser& parser, 
1111                  CIMType type, 
1112                  CIMValue& value)
1113              {
1114 karl    1.35     // Get VALUE start tag: Return false if no VALUE start Tag
1115 mike    1.23 
1116                  XmlEntry entry;
1117                  if (!testStartTagOrEmptyTag(parser, entry, "VALUE"))
1118              	return false;
1119              
1120                  Boolean empty = entry.type == XmlEntry::EMPTY_TAG;
1121              
1122                  const char* valueString = "";
1123              
1124                  if (!empty)
1125                  {
1126              	if (testContentOrCData(parser, entry))
1127              	    valueString = entry.text;
1128              
1129              	expectEndTag(parser, "VALUE");
1130                  }
1131              
1132                  value = stringToValue(parser.getLine(), valueString,type);
1133 karl    1.33     
1134 mike    1.23     return true;
1135              }
1136              
1137              //------------------------------------------------------------------------------
1138              //
1139              // getStringValueElement()
1140              //
1141              //     <!ELEMENT VALUE (#PCDATA)>
1142              //
1143              //------------------------------------------------------------------------------
1144              
1145              Boolean XmlReader::getStringValueElement(
1146                  XmlParser& parser, 
1147                  String& str,
1148                  Boolean required)
1149              {
1150                  XmlEntry entry;
1151              
1152                  if (!testStartTagOrEmptyTag(parser, entry, "VALUE"))
1153                  {
1154              	if (required)
1155 mike    1.23 	    throw XmlValidationError(parser.getLine(),"Expected VALUE element");
1156              	return false;
1157                  }
1158              
1159                  Boolean empty = entry.type == XmlEntry::EMPTY_TAG;
1160              
1161                  const char* valueString = "";
1162              
1163                  if (!empty)
1164                  {
1165              	if (testContentOrCData(parser, entry))
1166              	    valueString = entry.text;
1167              
1168              	expectEndTag(parser, "VALUE");
1169                  }
1170              
1171                  str = valueString;
1172                  return true;
1173              }
1174              
1175              //----------------------------------------------------------------------------
1176 mike    1.23 //
1177              // getPropertyValue
1178 kumpf   1.30 //     Use: Decode property value from SetProperty request and
1179              //     GetProperty response.
1180 mike    1.23 //
1181 kumpf   1.30 //     PropertyValue is one of:
1182 mike    1.23 //
1183              //
1184 karl    1.33 //	<!ELEMENT VALUE.ARRAY (VALUE*)>
1185              //
1186              //	<!ELEMENT VALUE.REFERENCE (CLASSPATH|LOCALCLASSPATH|CLASSNAME|
1187 kumpf   1.30 //         <!ELEMENT VALUE.ARRAY (VALUE*)>
1188              //
1189              //         <!ELEMENT VALUE.REFERENCE (CLASSPATH|LOCALCLASSPATH|CLASSNAME|
1190 mike    1.23 //                           INSTANCEPATH|LOCALINSTANCEPATH|INSTANCENAME)>
1191              //
1192 kumpf   1.30 //         <!ELEMENT VALUE.REFARRAY (VALUE.REFERENCE*)>
1193              //
1194 mike    1.23 //----------------------------------------------------------------------------
1195              Boolean XmlReader::getPropertyValue(
1196                  XmlParser& parser, 
1197                  CIMValue& cimValue)
1198              {
1199 kumpf   1.30     // Can not test for value type, so assume String
1200 kumpf   1.61     const CIMType type = CIMTYPE_STRING;
1201 mike    1.23 
1202 kumpf   1.30     // Test for VALUE element
1203 mike    1.23     if (XmlReader::getValueElement(parser, type, cimValue))
1204                  {
1205              	return true;
1206                  }
1207              
1208 kumpf   1.30     // Test for VALUE.ARRAY element
1209                  if (XmlReader::getValueArrayElement(parser, type, cimValue))
1210                  {
1211 mike    1.23        return true;
1212 kumpf   1.30     }
1213 mike    1.23 
1214 kumpf   1.30     // Test for VALUE.REFERENCE element
1215 kumpf   1.54     CIMObjectPath reference;
1216 kumpf   1.30     if (XmlReader::getValueReferenceElement(parser, reference))
1217 mike    1.25     {
1218                      cimValue.set(reference);
1219                      return true;
1220                  }
1221 mike    1.23 
1222 kumpf   1.30     // Test for VALUE.REFARRAY element
1223                  if (XmlReader::getValueReferenceArrayElement(parser, cimValue))
1224                  {
1225                     return true;
1226                  }
1227              
1228                  return false;
1229 mike    1.23 }
1230              
1231              //------------------------------------------------------------------------------
1232              //
1233              // stringArrayToValue()
1234              //
1235              //------------------------------------------------------------------------------
1236              
1237              template<class T>
1238              CIMValue StringArrayToValueAux(
1239                  Uint32 lineNumber, 
1240                  const Array<const char*>& stringArray,
1241                  CIMType type,
1242                  T*)
1243              {
1244                  Array<T> array;
1245              
1246                  for (Uint32 i = 0, n = stringArray.size(); i < n; i++)
1247                  {
1248              	CIMValue value = XmlReader::stringToValue(
1249              	    lineNumber, stringArray[i], type);
1250 mike    1.23 
1251              	T x;
1252              	value.get(x);
1253              	array.append(x);
1254                  }
1255              
1256                  return CIMValue(array);
1257              }
1258              
1259              CIMValue XmlReader::stringArrayToValue(
1260                  Uint32 lineNumber, 
1261                  const Array<const char*>& array, 
1262                  CIMType type)
1263              {
1264                  switch (type)
1265                  {
1266 kumpf   1.61 	case CIMTYPE_BOOLEAN: 
1267 mike    1.23 	    return StringArrayToValueAux(lineNumber, array, type, (Boolean*)0);
1268              
1269 kumpf   1.61 	case CIMTYPE_STRING:
1270 mike    1.23 	    return StringArrayToValueAux(lineNumber, array, type, (String*)0);
1271              
1272 kumpf   1.61 	case CIMTYPE_CHAR16:
1273 mike    1.23 	    return StringArrayToValueAux(lineNumber, array, type, (Char16*)0);
1274              
1275 kumpf   1.61 	case CIMTYPE_UINT8:
1276 mike    1.23 	    return StringArrayToValueAux(lineNumber, array, type, (Uint8*)0);
1277              
1278 kumpf   1.61 	case CIMTYPE_UINT16:
1279 mike    1.23 	    return StringArrayToValueAux(lineNumber, array, type, (Uint16*)0);
1280              
1281 kumpf   1.61 	case CIMTYPE_UINT32:
1282 mike    1.23 	    return StringArrayToValueAux(lineNumber, array, type, (Uint32*)0);
1283              
1284 kumpf   1.61 	case CIMTYPE_UINT64:
1285 mike    1.23 	    return StringArrayToValueAux(lineNumber, array, type, (Uint64*)0);
1286              
1287 kumpf   1.61 	case CIMTYPE_SINT8:
1288 mike    1.23 	    return StringArrayToValueAux(lineNumber, array, type, (Sint8*)0);
1289              
1290 kumpf   1.61 	case CIMTYPE_SINT16:
1291 mike    1.23 	    return StringArrayToValueAux(lineNumber, array, type, (Sint16*)0);
1292              
1293 kumpf   1.61 	case CIMTYPE_SINT32:
1294 mike    1.23 	    return StringArrayToValueAux(lineNumber, array, type, (Sint32*)0);
1295              
1296 kumpf   1.61 	case CIMTYPE_SINT64:
1297 mike    1.23 	    return StringArrayToValueAux(lineNumber, array, type, (Sint64*)0);
1298              
1299 kumpf   1.61 	case CIMTYPE_DATETIME:
1300 mike    1.23 	    return StringArrayToValueAux(lineNumber, array, type, (CIMDateTime*)0);
1301              
1302 kumpf   1.61 	case CIMTYPE_REAL32:
1303 mike    1.23 	    return StringArrayToValueAux(lineNumber, array, type, (Real32*)0);
1304              
1305 kumpf   1.61 	case CIMTYPE_REAL64:
1306 mike    1.23 	    return StringArrayToValueAux(lineNumber, array, type, (Real64*)0);
1307              
1308              	default:
1309              	    break;
1310                  }
1311              
1312                  // Unreachable:
1313                  return CIMValue();
1314              }
1315              
1316              //------------------------------------------------------------------------------
1317              //
1318              // getValueArrayElement()
1319              //
1320              //     <!ELEMENT VALUE.ARRAY (VALUE*)>
1321              //
1322 karl    1.35 //  Return: Boolean. Returns false if there is no VALUE.ARRAY start element
1323              //
1324 mike    1.23 //------------------------------------------------------------------------------
1325              
1326              Boolean XmlReader::getValueArrayElement(
1327                  XmlParser& parser, 
1328                  CIMType type, 
1329                  CIMValue& value)
1330              {
1331 karl    1.35     // Clears any values from the Array. Assumes this is array CIMValue
1332 mike    1.23     value.clear();
1333              
1334                  // Get VALUE.ARRAY open tag:
1335              
1336                  XmlEntry entry;
1337 kumpf   1.32     Array<const char*> stringArray;
1338 mike    1.23 
1339 karl    1.35     // If no VALUE.ARRAY start tag, return false
1340 mike    1.23     if (!testStartTagOrEmptyTag(parser, entry, "VALUE.ARRAY"))
1341              	return false;
1342 karl    1.33 
1343 kumpf   1.32     if (entry.type != XmlEntry::EMPTY_TAG)
1344                  {
1345                      // For each VALUE element:
1346 mike    1.23 
1347 kumpf   1.32         while (testStartTagOrEmptyTag(parser, entry, "VALUE"))
1348                      {
1349              	    if (entry.type == XmlEntry::EMPTY_TAG)
1350              	    {
1351              	        stringArray.append("");
1352              	        continue;
1353              	    }
1354 mike    1.23 
1355 kumpf   1.32 	    if (testContentOrCData(parser, entry))
1356              	        stringArray.append(entry.text);
1357              	    else
1358              	        stringArray.append("");
1359 mike    1.23 
1360 kumpf   1.32 	    expectEndTag(parser, "VALUE");
1361                      }
1362 mike    1.23 
1363 kumpf   1.32         expectEndTag(parser, "VALUE.ARRAY");
1364 mike    1.23     }
1365              
1366                  value = stringArrayToValue(parser.getLine(), stringArray, type);
1367                  return true;
1368              }
1369              
1370              //------------------------------------------------------------------------------
1371              //
1372              // getFlavor()
1373              //
1374              //     <!ENTITY % QualifierFlavor 
1375              //         "OVERRIDABLE (true|false) 'true'
1376              //         TOSUBCLASS (true|false) 'true'
1377              //         TOINSTANCE (true|false)  'false'
1378              //         TRANSLATABLE (true|false)  'false'">
1379              //
1380              //------------------------------------------------------------------------------
1381              
1382 kumpf   1.64 CIMFlavor XmlReader::getFlavor(
1383 mike    1.23     XmlEntry& entry, 
1384                  Uint32 lineNumber, 
1385                  const char* tagName)
1386              {
1387                  // Get QUALIFIER.OVERRIDABLE
1388              
1389                  Boolean overridable = getCimBooleanAttribute(
1390              	lineNumber, entry, tagName, "OVERRIDABLE", true, false);
1391              
1392                  // Get QUALIFIER.TOSUBCLASS
1393              
1394                  Boolean toSubClass = getCimBooleanAttribute(
1395              	lineNumber, entry, tagName, "TOSUBCLASS", true, false);
1396              
1397                  // Get QUALIFIER.TOINSTANCE
1398              
1399                  Boolean toInstance = getCimBooleanAttribute(
1400              	lineNumber, entry, tagName, "TOINSTANCE", false, false);
1401              
1402                  // Get QUALIFIER.TRANSLATABLE
1403              
1404 mike    1.23     Boolean translatable = getCimBooleanAttribute(
1405              	lineNumber, entry, tagName, "TRANSLATABLE", false, false);
1406              
1407 kumpf   1.44     // Start with CIMFlavor::NONE.  Defaults are specified in the
1408                  // getCimBooleanAttribute() calls above.
1409 kumpf   1.64     CIMFlavor flavor = CIMFlavor (CIMFlavor::NONE);
1410 mike    1.23 
1411                  if (overridable)
1412 kumpf   1.64         flavor.addFlavor (CIMFlavor::OVERRIDABLE);
1413                  else
1414                      flavor.addFlavor (CIMFlavor::DISABLEOVERRIDE);
1415 mike    1.23 
1416                  if (toSubClass)
1417 kumpf   1.64         flavor.addFlavor (CIMFlavor::TOSUBCLASS);
1418                  else
1419                      flavor.addFlavor (CIMFlavor::RESTRICTED);
1420 mike    1.23 
1421                  if (toInstance)
1422 kumpf   1.64         flavor.addFlavor (CIMFlavor::TOINSTANCE);
1423 mike    1.23 
1424                  if (translatable)
1425 kumpf   1.64         flavor.addFlavor (CIMFlavor::TRANSLATABLE);
1426 mike    1.23 
1427                  return flavor;
1428              }
1429              
1430              //------------------------------------------------------------------------------
1431              //
1432              // getOptionalScope()
1433              //
1434              //     DTD:
1435              //         <!ELEMENT SCOPE EMPTY>
1436              //         <!ATTLIST SCOPE 
1437              //              CLASS (true|false) 'false'
1438              //              ASSOCIATION (true|false) 'false'
1439              //              REFERENCE (true|false) 'false'
1440              //              PROPERTY (true|false) 'false'
1441              //              METHOD (true|false) 'false'
1442              //              PARAMETER (true|false) 'false'
1443              //              INDICATION (true|false) 'false'>
1444              //
1445              //------------------------------------------------------------------------------
1446              
1447 kumpf   1.63 CIMScope XmlReader::getOptionalScope(XmlParser& parser)
1448 mike    1.23 {
1449                  XmlEntry entry;
1450 kumpf   1.65     CIMScope scope;
1451 mike    1.23 
1452                  if (!parser.next(entry))
1453 kumpf   1.65 	return scope;    // No SCOPE element found; return the empty scope
1454 mike    1.23 
1455                  Boolean isEmptyTag = entry.type == XmlEntry::EMPTY_TAG;
1456              
1457                  if ((!isEmptyTag && 
1458              	entry.type != XmlEntry::START_TAG) ||
1459              	strcmp(entry.text, "SCOPE") != 0)
1460                  {
1461 kumpf   1.65 	// No SCOPE element found; return the empty scope
1462 mike    1.23 	parser.putBack(entry);
1463 kumpf   1.65 	return scope;
1464 mike    1.23     }
1465              
1466                  Uint32 line = parser.getLine();
1467              
1468                  if (getCimBooleanAttribute(line, entry, "SCOPE", "CLASS", false, false))
1469 kumpf   1.63 	scope.addScope (CIMScope::CLASS);
1470 mike    1.23 
1471                  if (getCimBooleanAttribute(
1472              	line, entry, "SCOPE", "ASSOCIATION", false, false))
1473 kumpf   1.63 	scope.addScope (CIMScope::ASSOCIATION);
1474 mike    1.23 
1475                  if (getCimBooleanAttribute(
1476              	line, entry, "SCOPE", "REFERENCE", false, false))
1477 kumpf   1.63 	scope.addScope (CIMScope::REFERENCE);
1478 mike    1.23 
1479                  if (getCimBooleanAttribute(line, entry, "SCOPE", "PROPERTY", false, false))
1480 kumpf   1.63 	scope.addScope (CIMScope::PROPERTY);
1481 mike    1.23 
1482                  if (getCimBooleanAttribute(line, entry, "SCOPE", "METHOD", false, false))
1483 kumpf   1.63 	scope.addScope (CIMScope::METHOD);
1484 mike    1.23 
1485                  if (getCimBooleanAttribute(line, entry, "SCOPE", "PARAMETER", false, false))
1486 kumpf   1.63 	scope.addScope (CIMScope::PARAMETER);
1487 mike    1.23 
1488                  if (getCimBooleanAttribute(line, entry, "SCOPE", "INDICATION",false, false))
1489 kumpf   1.63 	scope.addScope (CIMScope::INDICATION);
1490 mike    1.23 
1491                  if (!isEmptyTag)
1492              	expectEndTag(parser, "SCOPE");
1493              
1494                  return scope;
1495              }
1496              
1497              //------------------------------------------------------------------------------
1498              //
1499              // getQualifierElement()
1500              //
1501 kumpf   1.52 //     <!ELEMENT QUALIFIER (VALUE|VALUE.ARRAY)?>
1502 mike    1.23 //     <!ATTLIST QUALIFIER
1503              //         %CIMName;
1504              //         %CIMType; #REQUIRED
1505              //         %Propagated;
1506              //         %QualifierFlavor;>
1507              //
1508              //------------------------------------------------------------------------------
1509              
1510              Boolean XmlReader::getQualifierElement(
1511                  XmlParser& parser, 
1512                  CIMQualifier& qualifier)
1513              {
1514                  // Get QUALIFIER element:
1515              
1516                  XmlEntry entry;
1517                  if (!testStartTag(parser, entry, "QUALIFIER"))
1518              	return false;
1519              
1520                  // Get QUALIFIER.NAME attribute:
1521              
1522                  String name = getCimNameAttribute(parser.getLine(), entry, "QUALIFIER");
1523 mike    1.23 
1524                  // Get QUALIFIER.TYPE attribute:
1525              
1526 kumpf   1.67     CIMType type;
1527                  getCimTypeAttribute(parser.getLine(), entry, type, "QUALIFIER");
1528 mike    1.23 
1529                  // Get QUALIFIER.PROPAGATED
1530              
1531                  Boolean propagated = getCimBooleanAttribute(
1532              	parser.getLine(), entry, "QUALIFIER", "PROPAGATED", false, false);
1533              
1534                  // Get flavor oriented attributes:
1535              
1536 kumpf   1.64     CIMFlavor flavor = getFlavor(entry, parser.getLine(), "QUALIFIER");
1537 mike    1.23 
1538                  // Get VALUE or VALUE.ARRAY element:
1539              
1540                  CIMValue value;
1541              
1542                  if (!getValueElement(parser, type, value) &&
1543              	!getValueArrayElement(parser, type, value))
1544                  {
1545 kumpf   1.52         value.setNullValue(type, false);
1546 mike    1.23     }
1547              
1548                  // Expect </QUALIFIER>:
1549              
1550                  expectEndTag(parser, "QUALIFIER");
1551              
1552                  // Build qualifier:
1553              
1554                  qualifier = CIMQualifier(name, value, flavor, propagated);
1555                  return true;
1556              }
1557              
1558              //------------------------------------------------------------------------------
1559              //
1560              // getQualifierElements()
1561              //
1562              //------------------------------------------------------------------------------
1563              
1564              template<class CONTAINER>
1565              void getQualifierElements(XmlParser& parser, CONTAINER& container)
1566              {
1567 mike    1.23     CIMQualifier qualifier;
1568              
1569                  while (XmlReader::getQualifierElement(parser, qualifier))
1570                  {
1571              	try
1572              	{
1573              	    container.addQualifier(qualifier);
1574              	}
1575 kumpf   1.66 	catch (AlreadyExistsException&)
1576 mike    1.23 	{
1577              	    throw XmlSemanticError(parser.getLine(), "duplicate qualifier");
1578              	}
1579                  }
1580              }
1581              
1582              //------------------------------------------------------------------------------
1583              //
1584              // getPropertyElement()
1585              //
1586              //     <!ELEMENT PROPERTY (QUALIFIER*,VALUE?)>
1587              //     <!ATTLIST PROPERTY
1588              //         %CIMName;
1589              //         %ClassOrigin;
1590              //         %Propagated;
1591              //         %CIMType; #REQUIRED>
1592              //
1593              //------------------------------------------------------------------------------
1594              
1595              Boolean XmlReader::getPropertyElement(XmlParser& parser, CIMProperty& property)
1596              {
1597 mike    1.23     XmlEntry entry;
1598              
1599                  if (!testStartTagOrEmptyTag(parser, entry, "PROPERTY"))
1600              	return false;
1601              
1602                  Boolean empty = entry.type == XmlEntry::EMPTY_TAG;
1603              
1604                  // Get PROPERTY.NAME attribute:
1605              
1606                  String name = getCimNameAttribute(parser.getLine(), entry, "PROPERTY");
1607              
1608                  // Get PROPERTY.CLASSORIGIN attribute:
1609              
1610 kumpf   1.62     CIMName classOrigin = 
1611 mike    1.23 	getClassOriginAttribute(parser.getLine(), entry, "PROPERTY");
1612              
1613                  // Get PROPERTY.PROPAGATED
1614              
1615                  Boolean propagated = getCimBooleanAttribute(
1616              	parser.getLine(), entry, "PROPERTY", "PROPAGATED", false, false);
1617              
1618                  // Get PROPERTY.TYPE attribute:
1619              
1620 kumpf   1.67     CIMType type;
1621                  getCimTypeAttribute(parser.getLine(), entry, type, "PROPERTY");
1622 mike    1.23 
1623 karl    1.35     // Create property: Sets type and !isarray
1624 mike    1.23 
1625 kumpf   1.56     CIMValue value(type, false);
1626 kumpf   1.62     property = CIMProperty(name, value, 0, CIMName(), classOrigin, propagated);
1627 mike    1.23 
1628                  if (!empty)
1629                  {
1630              	// Get qualifiers:
1631              
1632              	getQualifierElements(parser, property);
1633              
1634 karl    1.35 	// Get value:  Insert value if getValueElement exists (returns True)
1635 mike    1.23 
1636              	if (getValueElement(parser, type, value))
1637              	    property.setValue(value);
1638              
1639              	expectEndTag(parser, "PROPERTY");
1640                  }
1641              
1642                  return true;
1643              }
1644              
1645              //------------------------------------------------------------------------------
1646              //
1647              // getArraySizeAttribute()
1648              //
1649              //     Returns true if able to get array-size. Note that array size will
1650              //     always be a positive integer.
1651              //
1652              //     <!ENTITY % ArraySize "ARRAYSIZE CDATA #IMPLIED">
1653              //
1654              //------------------------------------------------------------------------------
1655              
1656 mike    1.23 Boolean XmlReader::getArraySizeAttribute(
1657                  Uint32 lineNumber,
1658                  const XmlEntry& entry,
1659                  const char* tagName,
1660                  Uint32& value)
1661              {
1662                  const char* tmp;
1663              
1664                  if (!entry.getAttributeValue("ARRAYSIZE", tmp))
1665              	return false;
1666              
1667                  Uint64 arraySize;
1668              
1669                  if (!stringToUnsignedInteger(tmp, arraySize) || arraySize == 0)
1670                  {
1671              	char message[128];
1672              	sprintf(message, "Illegal value for %s.%s", tagName, "ARRAYSIZE");
1673              	throw XmlSemanticError(lineNumber, message);
1674                  }
1675              
1676                  value = Uint32(arraySize);
1677 mike    1.23     return true;
1678              }
1679              
1680              //------------------------------------------------------------------------------
1681              //
1682              // getPropertyArrayElement()
1683              //
1684              //     <!ELEMENT PROPERTY.ARRAY (QUALIFIER*,VALUE.ARRAY?)>
1685              //     <!ATTLIST PROPERTY.ARRAY
1686              //             %CIMName;
1687              //             %CIMType; #REQUIRED
1688              //             %ArraySize;
1689              //             %ClassOrigin;
1690              //             %Propagated;>
1691              //
1692              //------------------------------------------------------------------------------
1693              
1694              Boolean XmlReader::getPropertyArrayElement(
1695                  XmlParser& parser, 
1696                  CIMProperty& property)
1697              {
1698 mike    1.23     // Get PROPERTY element:
1699              
1700                  XmlEntry entry;
1701              
1702                  if (!testStartTagOrEmptyTag(parser, entry, "PROPERTY.ARRAY"))
1703              	return false;
1704              
1705                  Boolean empty = entry.type == XmlEntry::EMPTY_TAG;
1706              
1707                  // Get PROPERTY.NAME attribute:
1708              
1709                  String name = 
1710              	getCimNameAttribute(parser.getLine(), entry, "PROPERTY.ARRAY");
1711              
1712                  // Get PROPERTY.TYPE attribute:
1713              
1714 kumpf   1.67     CIMType type;
1715                  getCimTypeAttribute(parser.getLine(), entry, type, "PROPERTY.ARRAY");
1716 mike    1.23 
1717                  // Get PROPERTY.ARRAYSIZE attribute:
1718              
1719                  Uint32 arraySize = 0;
1720                  getArraySizeAttribute(parser.getLine(), entry, "PROPERTY.ARRAY", arraySize);
1721              
1722                  // Get PROPERTY.CLASSORIGIN attribute:
1723              
1724 kumpf   1.62     CIMName classOrigin 
1725 mike    1.23 	= getClassOriginAttribute(parser.getLine(), entry, "PROPERTY.ARRAY");
1726              
1727                  // Get PROPERTY.ARRAY.PROPAGATED
1728              
1729                  Boolean propagated = getCimBooleanAttribute(
1730              	parser.getLine(), entry, "PROPERTY.ARRAY", "PROPAGATED", false, false);
1731              
1732                  // Create property:
1733              
1734 kumpf   1.56     CIMValue value(type, true, arraySize);
1735 mike    1.23     property = CIMProperty(
1736 kumpf   1.62 	name, value, arraySize, CIMName(), classOrigin, propagated);
1737 mike    1.23 
1738                  if (!empty)
1739                  {
1740              	// Get qualifiers:
1741              
1742              	getQualifierElements(parser, property);
1743              
1744              	// Get value:
1745              
1746              	if (getValueArrayElement(parser, type, value))
1747              	{
1748              	    if (arraySize && arraySize != value.getArraySize())
1749              	    {
1750              		throw XmlSemanticError(parser.getLine(),
1751              		    "ARRAYSIZE attribute and value-array size are different");
1752              	    }
1753              
1754              	    property.setValue(value);
1755              	}
1756              
1757              	expectEndTag(parser, "PROPERTY.ARRAY");
1758 mike    1.23     }
1759              
1760                  return true;
1761              }
1762              
1763              //------------------------------------------------------------------------------
1764              //
1765              // getHostElement()
1766              //
1767              //     <!ELEMENT HOST (#PCDATA)>
1768              //
1769              //------------------------------------------------------------------------------
1770              
1771              Boolean XmlReader::getHostElement(
1772                  XmlParser& parser,
1773                  String& host)
1774              {
1775                  XmlEntry entry;
1776              
1777                  if (!testStartTag(parser, entry, "HOST"))
1778              	return false;
1779 mike    1.23 
1780                  if (!parser.next(entry) || entry.type != XmlEntry::CONTENT)
1781                  {
1782              	throw XmlValidationError(parser.getLine(),
1783              	    "expected content of HOST element");
1784                  }
1785              
1786                  host = entry.text;
1787              
1788                  expectEndTag(parser, "HOST");
1789                  return true;
1790              }
1791              
1792              //------------------------------------------------------------------------------
1793              //
1794              // getNameSpaceElement()
1795              //     
1796              //     <!ELEMENT NAMESPACE EMPTY>
1797              //     <!ATTLIST NAMESPACE %CIMName;>
1798              //
1799              //------------------------------------------------------------------------------
1800 mike    1.23 
1801              Boolean XmlReader::getNameSpaceElement(
1802                  XmlParser& parser,
1803                  String& nameSpaceComponent)
1804              {
1805                  XmlEntry entry;
1806              
1807                  if (!testStartTagOrEmptyTag(parser, entry, "NAMESPACE"))
1808              	return false;
1809              
1810                  Boolean empty = entry.type == XmlEntry::EMPTY_TAG;
1811              
1812                  nameSpaceComponent = getCimNameAttribute(
1813              	parser.getLine(), entry, "NAMESPACE");
1814              
1815                  if (!empty)
1816              	expectEndTag(parser, "NAMESPACE");
1817              
1818                  return true;
1819              }
1820              
1821 mike    1.23 //------------------------------------------------------------------------------
1822              //
1823              // getLocalNameSpacePathElement()
1824              //     
1825              //     <!ELEMENT LOCALNAMESPACEPATH (NAMESPACE+)>
1826              //
1827              //------------------------------------------------------------------------------
1828              
1829              Boolean XmlReader::getLocalNameSpacePathElement(
1830                  XmlParser& parser,
1831                  String& nameSpace)
1832              {
1833                  XmlEntry entry;
1834              
1835                  if (!testStartTag(parser, entry, "LOCALNAMESPACEPATH"))
1836              	return false;
1837              
1838                  String nameSpaceComponent;
1839              
1840                  while (getNameSpaceElement(parser, nameSpaceComponent))
1841                  {
1842 mike    1.23 	if (nameSpace.size())
1843              	    nameSpace += '/';
1844              
1845              	nameSpace += nameSpaceComponent;
1846                  }
1847              
1848                  if (!nameSpace.size())
1849                  {
1850              	throw XmlValidationError(parser.getLine(),
1851              	    "Expected one or more NAMESPACE elements within "
1852              	    "LOCALNAMESPACEPATH element");
1853                  }
1854              
1855                  expectEndTag(parser, "LOCALNAMESPACEPATH");
1856                  return true;
1857              }
1858              
1859              //------------------------------------------------------------------------------
1860              //
1861              // getNameSpacePathElement()
1862              //
1863 mike    1.23 //     <!ELEMENT NAMESPACEPATH (HOST,LOCALNAMESPACEPATH)>
1864              //
1865              //------------------------------------------------------------------------------
1866              
1867              Boolean XmlReader::getNameSpacePathElement(
1868                  XmlParser& parser,
1869                  String& host,
1870                  String& nameSpace)
1871              {
1872                  host.clear();
1873                  nameSpace.clear();
1874              
1875                  XmlEntry entry;
1876              
1877                  if (!testStartTag(parser, entry, "NAMESPACEPATH"))
1878              	return false;
1879              
1880                  if (!getHostElement(parser, host))
1881              	throw XmlValidationError(parser.getLine(), "expected HOST element");
1882              
1883                  if (!getLocalNameSpacePathElement(parser, nameSpace))
1884 mike    1.23     {
1885              	throw XmlValidationError(parser.getLine(), 
1886              	    "expected LOCALNAMESPACEPATH element");
1887                  }
1888              
1889                  expectEndTag(parser, "NAMESPACEPATH");
1890              
1891                  return true;
1892              }
1893              
1894              //------------------------------------------------------------------------------
1895              //
1896              // getClassNameElement()
1897              //
1898              //     <!ELEMENT CLASSNAME EMPTY>
1899              //     <!ATTLIST CLASSNAME %CIMName;>
1900              //
1901              //------------------------------------------------------------------------------
1902              
1903              Boolean XmlReader::getClassNameElement(
1904                  XmlParser& parser,
1905 mike    1.23     String& className,
1906                  Boolean required)
1907              {
1908                  XmlEntry entry;
1909              
1910                  if (!testStartTagOrEmptyTag(parser, entry, "CLASSNAME"))
1911                  {
1912              	if (required)
1913              	{
1914              	    throw XmlValidationError(parser.getLine(),
1915              		"expected CLASSNAME element");
1916              	}
1917              	else
1918              	    return false;
1919                  }
1920              
1921                  Boolean empty = entry.type == XmlEntry::EMPTY_TAG;
1922              
1923                  className = getCimNameAttribute(
1924              	parser.getLine(), entry, "CLASSNAME", true);
1925              
1926 mike    1.23     if (!empty)
1927              	expectEndTag(parser, "CLASSNAME");
1928              
1929                  return true;
1930              }
1931              
1932              //------------------------------------------------------------------------------
1933              //
1934              // getValueTypeAttribute()
1935              //
1936              //     VALUETYPE (string|boolean|numeric) 'string'
1937              //
1938              //------------------------------------------------------------------------------
1939              
1940              KeyBinding::Type XmlReader::getValueTypeAttribute(
1941                  Uint32 lineNumber, 
1942                  const XmlEntry& entry,
1943                  const char* elementName)
1944              {
1945                  String tmp;
1946              
1947 mike    1.23     if (!entry.getAttributeValue("VALUETYPE", tmp))
1948              	return KeyBinding::STRING;
1949              
1950                  if (String::equal(tmp, "string"))
1951              	return KeyBinding::STRING;
1952                  else if (String::equal(tmp, "boolean"))
1953              	return KeyBinding::BOOLEAN;
1954                  else if (String::equal(tmp, "numeric"))
1955              	return KeyBinding::NUMERIC;
1956              
1957                  char buffer[MESSAGE_SIZE];
1958              
1959                  sprintf(buffer, 
1960              	"Illegal value for %s.VALUETYPE attribute; "
1961              	"CIMValue must be one of \"string\", \"boolean\", or \"numeric\"",
1962              	elementName);
1963              
1964                  throw XmlSemanticError(lineNumber, buffer);
1965                  return KeyBinding::BOOLEAN;
1966              }
1967              
1968 mike    1.23 //------------------------------------------------------------------------------
1969              //
1970              // getKeyValueElement()
1971              //
1972              //     <!ELEMENT KEYVALUE (#PCDATA)>
1973              //     <!ATTLIST KEYVALUE
1974              //         VALUETYPE (string|boolean|numeric)  'string'>
1975              //
1976              //------------------------------------------------------------------------------
1977              
1978              Boolean XmlReader::getKeyValueElement(
1979                  XmlParser& parser,
1980                  KeyBinding::Type& type,
1981                  String& value)
1982              {
1983                  XmlEntry entry;
1984              
1985                  if (!testStartTagOrEmptyTag(parser, entry, "KEYVALUE"))
1986              	return false;
1987              
1988                  Boolean empty = entry.type == XmlEntry::EMPTY_TAG;
1989 mike    1.23 
1990                  type = getValueTypeAttribute(parser.getLine(), entry, "KEYVALUE");
1991              
1992                  value.clear();
1993              
1994                  if (!empty)
1995                  {
1996              	if (!parser.next(entry))
1997              	    throw XmlException(XmlException::UNCLOSED_TAGS, parser.getLine());
1998              
1999              	if (entry.type == XmlEntry::CONTENT)
2000              	    value = entry.text;
2001              	else
2002              	    parser.putBack(entry);
2003              
2004              	expectEndTag(parser, "KEYVALUE");
2005                  }
2006              
2007                  return true;
2008              }
2009              
2010 mike    1.23 //------------------------------------------------------------------------------
2011              //
2012              // getKeyBindingElement()
2013              //
2014              //     <!ELEMENT KEYBINDING (KEYVALUE|VALUE.REFERENCE)>
2015              //     <!ATTLIST KEYBINDING
2016              //         %CIMName;>
2017              //
2018              //------------------------------------------------------------------------------
2019              
2020              Boolean XmlReader::getKeyBindingElement(
2021                  XmlParser& parser,
2022                  String& name,
2023                  String& value,
2024                  KeyBinding::Type& type)
2025              {
2026                  XmlEntry entry;
2027              
2028                  if (!testStartTag(parser, entry, "KEYBINDING"))
2029              	return false;
2030              
2031 mike    1.23     name = getCimNameAttribute(parser.getLine(), entry, "KEYBINDING");
2032              
2033                  if (!getKeyValueElement(parser, type, value))
2034 mike    1.25     {
2035 kumpf   1.54         CIMObjectPath reference;
2036 mike    1.25 
2037                      if (!getValueReferenceElement(parser, reference))
2038                      {
2039              	    throw XmlValidationError(parser.getLine(),
2040                                    "Expected KEYVALUE or VALUE.REFERENCE element");
2041                      }
2042              
2043                      type = KeyBinding::REFERENCE;
2044                      value = reference.toString();
2045                  }
2046 mike    1.23 
2047                  expectEndTag(parser, "KEYBINDING");
2048                  return true;
2049              }
2050              
2051              //------------------------------------------------------------------------------
2052              //
2053              // getInstanceNameElement()
2054              //
2055              //     <!ELEMENT INSTANCENAME (KEYBINDING*|KEYVALUE?|VALUE.REFERENCE?)>
2056              //     <!ATTLIST INSTANCENAME
2057              //         %ClassName;>
2058              //
2059 mike    1.25 // Note: An empty key name is used in the keyBinding when the INSTANCENAME is
2060              // specified using a KEYVALUE or a VALUE.REFERENCE.
2061 mike    1.23 //
2062              //------------------------------------------------------------------------------
2063              
2064              Boolean XmlReader::getInstanceNameElement(
2065                  XmlParser& parser,
2066                  String& className,
2067                  Array<KeyBinding>& keyBindings)
2068              {
2069                  className.clear();
2070                  keyBindings.clear();
2071              
2072                  XmlEntry entry;
2073              
2074                  if (!testStartTagOrEmptyTag(parser, entry, "INSTANCENAME"))
2075              	return false;
2076              
2077                  Boolean empty = entry.type == XmlEntry::EMPTY_TAG;
2078              
2079                  className = getClassNameAttribute(parser.getLine(), entry, "INSTANCENAME");
2080              
2081 mike    1.25     if (empty)
2082 mike    1.23     {
2083 mike    1.25         return true;
2084                  }
2085 mike    1.23 
2086 mike    1.25     String name;
2087                  KeyBinding::Type type;
2088                  String value;
2089 kumpf   1.54     CIMObjectPath reference;
2090 mike    1.25 
2091                  if (getKeyValueElement(parser, type, value))
2092                  {
2093                      // Use empty key name because none was specified
2094                      keyBindings.append(KeyBinding(name, value, type));
2095                  }
2096                  else if (getValueReferenceElement(parser, reference))
2097                  {
2098                      // Use empty key name because none was specified
2099                      type = KeyBinding::REFERENCE;
2100                      value = reference.toString();
2101                      keyBindings.append(KeyBinding(name, value, type));
2102                  }
2103                  else
2104                  {
2105 mike    1.23 	while (getKeyBindingElement(parser, name, value, type))
2106              	    keyBindings.append(KeyBinding(name, value, type));
2107 mike    1.25     }
2108 mike    1.23 
2109 mike    1.25     expectEndTag(parser, "INSTANCENAME");
2110 mike    1.23 
2111                  return true;
2112              }
2113              
2114              Boolean XmlReader::getInstanceNameElement(
2115                  XmlParser& parser,
2116 kumpf   1.54     CIMObjectPath& instanceName)
2117 mike    1.23 {
2118                  String className;
2119                  Array<KeyBinding> keyBindings;
2120              
2121                  if (!XmlReader::getInstanceNameElement(parser, className, keyBindings))
2122              	return false;
2123              
2124 kumpf   1.62     instanceName.set(String(), CIMNamespaceName(), className, keyBindings);
2125 mike    1.23     return true;
2126              }
2127              
2128              //------------------------------------------------------------------------------
2129              //
2130              // getInstancePathElement()
2131              //
2132              //     <!ELEMENT INSTANCEPATH (NAMESPACEPATH,INSTANCENAME)>
2133              //
2134              //------------------------------------------------------------------------------
2135              
2136              Boolean XmlReader::getInstancePathElement(
2137                  XmlParser& parser,
2138 kumpf   1.54     CIMObjectPath& reference)
2139 mike    1.23 {
2140                  XmlEntry entry;
2141              
2142                  if (!testStartTag(parser, entry, "INSTANCEPATH"))
2143              	return false;
2144              
2145                  String host;
2146                  String nameSpace;
2147              
2148                  if (!getNameSpacePathElement(parser, host, nameSpace))
2149                  {
2150              	throw XmlValidationError(parser.getLine(),
2151              	    "expected NAMESPACEPATH element");
2152                  }
2153              
2154                  String className;
2155                  Array<KeyBinding> keyBindings;
2156              
2157                  if (!getInstanceNameElement(parser, className, keyBindings))
2158                  {
2159              	throw XmlValidationError(parser.getLine(), 
2160 mike    1.23 	    "expected INSTANCENAME element");
2161                  }
2162              
2163                  reference.set(host, nameSpace, className, keyBindings);
2164              
2165                  expectEndTag(parser, "INSTANCEPATH");
2166                  return true;
2167              }
2168              
2169              //------------------------------------------------------------------------------
2170              //
2171              // getLocalInstancePathElement()
2172              //
2173              //     <!ELEMENT LOCALINSTANCEPATH (NAMESPACEPATH,INSTANCENAME)>
2174              //
2175              //------------------------------------------------------------------------------
2176              
2177              Boolean XmlReader::getLocalInstancePathElement(
2178                  XmlParser& parser,
2179 kumpf   1.54     CIMObjectPath& reference)
2180 mike    1.23 {
2181                  XmlEntry entry;
2182              
2183                  if (!testStartTag(parser, entry, "LOCALINSTANCEPATH"))
2184              	return false;
2185              
2186                  String nameSpace;
2187              
2188                  if (!getLocalNameSpacePathElement(parser, nameSpace))
2189                  {
2190              	throw XmlValidationError(parser.getLine(),
2191              	    "expected LOCALNAMESPACEPATH element");
2192                  }
2193              
2194                  String className;
2195                  Array<KeyBinding> keyBindings;
2196              
2197                  if (!getInstanceNameElement(parser, className, keyBindings))
2198                  {
2199              	throw XmlValidationError(parser.getLine(), 
2200              	    "expected INSTANCENAME element");
2201 mike    1.23     }
2202              
2203                  reference.set(String(), nameSpace, className, keyBindings);
2204              
2205                  expectEndTag(parser, "LOCALINSTANCEPATH");
2206                  return true;
2207              }
2208              
2209              //------------------------------------------------------------------------------
2210              //
2211              // getClassPathElement()
2212              //
2213              //     <!ELEMENT CLASSPATH (NAMESPACEPATH,CLASSNAME)>
2214              //
2215              //------------------------------------------------------------------------------
2216              
2217              Boolean XmlReader::getClassPathElement(
2218                  XmlParser& parser,
2219 kumpf   1.54     CIMObjectPath& reference)
2220 mike    1.23 {
2221                  XmlEntry entry;
2222              
2223                  if (!testStartTag(parser, entry, "CLASSPATH"))
2224              	return false;
2225              
2226                  String host;
2227                  String nameSpace;
2228              
2229                  if (!getNameSpacePathElement(parser, host, nameSpace))
2230                  {
2231              	throw XmlValidationError(parser.getLine(),
2232              	    "expected NAMESPACEPATH element");
2233                  }
2234              
2235                  String className;
2236              
2237                  if (!getClassNameElement(parser, className))
2238                  {
2239              	throw XmlValidationError(parser.getLine(), 
2240              	    "expected CLASSNAME element");
2241 mike    1.23     }
2242              
2243                  reference.set(host, nameSpace, className);
2244              
2245                  expectEndTag(parser, "CLASSPATH");
2246                  return true;
2247              }
2248              
2249              //------------------------------------------------------------------------------
2250              //
2251              // getLocalClassPathElement()
2252              //
2253              //     <!ELEMENT LOCALCLASSPATH (LOCALNAMESPACEPATH,CLASSNAME)>
2254              //
2255              //------------------------------------------------------------------------------
2256              
2257              Boolean XmlReader::getLocalClassPathElement(
2258                  XmlParser& parser,
2259 kumpf   1.54     CIMObjectPath& reference)
2260 mike    1.23 {
2261                  XmlEntry entry;
2262              
2263                  if (!testStartTag(parser, entry, "LOCALCLASSPATH"))
2264              	return false;
2265              
2266                  String nameSpace;
2267              
2268                  if (!getLocalNameSpacePathElement(parser, nameSpace))
2269                  {
2270              	throw XmlValidationError(parser.getLine(),
2271              	    "expected LOCALNAMESPACEPATH element");
2272                  }
2273              
2274                  String className;
2275              
2276                  if (!getClassNameElement(parser, className))
2277                  {
2278              	throw XmlValidationError(parser.getLine(), 
2279              	    "expected CLASSNAME element");
2280                  }
2281 mike    1.23 
2282                  reference.set(String(), nameSpace, className);
2283              
2284                  expectEndTag(parser, "LOCALCLASSPATH");
2285              
2286                  return true;
2287              }
2288              
2289              //------------------------------------------------------------------------------
2290              //
2291              // getValueReferenceElement()
2292              //
2293              //     <!ELEMENT VALUE.REFERENCE (CLASSPATH|LOCALCLASSPATH|CLASSNAME|
2294              //         INSTANCEPATH|LOCALINSTANCEPATH|INSTANCENAME)>
2295              //
2296              //
2297              //------------------------------------------------------------------------------
2298              
2299              Boolean XmlReader::getValueReferenceElement(
2300                  XmlParser& parser,
2301 kumpf   1.54     CIMObjectPath& reference)
2302 mike    1.23 {
2303                  XmlEntry entry;
2304              
2305                  if (!testStartTag(parser, entry, "VALUE.REFERENCE"))
2306              	return false;
2307              
2308                  if (!parser.next(entry))
2309              	throw XmlException(XmlException::UNCLOSED_TAGS, parser.getLine());
2310              
2311                  if (entry.type != XmlEntry::START_TAG && 
2312              	entry.type != XmlEntry::EMPTY_TAG)
2313                  {
2314              	throw XmlValidationError(parser.getLine(), 
2315              	    "Expected one of the following start tags: "
2316              	    "CLASSPATH, LOCALCLASSPATH, CLASSNAME, INSTANCEPATH, "
2317              	    "LOCALINSTANCEPATH, INSTANCENAME");
2318                  }
2319              
2320                  if (strcmp(entry.text, "CLASSPATH") == 0)
2321                  {
2322              	parser.putBack(entry);
2323 mike    1.23 	getClassPathElement(parser, reference);
2324                  }
2325                  else if (strcmp(entry.text, "LOCALCLASSPATH") == 0)
2326                  {
2327              	parser.putBack(entry);
2328              	getLocalClassPathElement(parser, reference);
2329                  }
2330                  else if (strcmp(entry.text, "CLASSNAME") == 0)
2331                  {
2332              	parser.putBack(entry);
2333              	String className;
2334              	getClassNameElement(parser, className);
2335 kumpf   1.62 	reference.set(String(), CIMNamespaceName(), className);
2336 mike    1.23     }
2337                  else if (strcmp(entry.text, "INSTANCEPATH") == 0)
2338                  {
2339              	parser.putBack(entry);
2340              	getInstancePathElement(parser, reference);
2341                  }
2342                  else if (strcmp(entry.text, "LOCALINSTANCEPATH") == 0)
2343                  {
2344              	parser.putBack(entry);
2345              	getLocalInstancePathElement(parser, reference);
2346                  }
2347                  else if (strcmp(entry.text, "INSTANCENAME") == 0)
2348                  {
2349              	parser.putBack(entry);
2350              	String className;
2351              	Array<KeyBinding> keyBindings;
2352              	getInstanceNameElement(parser, className, keyBindings);
2353 kumpf   1.62 	reference.set(String(), CIMNamespaceName(), className, keyBindings);
2354 mike    1.23     }
2355              
2356                  expectEndTag(parser, "VALUE.REFERENCE");
2357                  return true;
2358              }
2359              
2360              //------------------------------------------------------------------------------
2361              //
2362 kumpf   1.28 // getValueReferenceArrayElement()
2363              //
2364              //     <!ELEMENT VALUE.REFARRAY (VALUE.REFERENCE*)>
2365              //
2366              //------------------------------------------------------------------------------
2367              
2368              Boolean XmlReader::getValueReferenceArrayElement(
2369                  XmlParser& parser, 
2370                  CIMValue& value)
2371              {
2372                  XmlEntry entry;
2373 kumpf   1.54     Array<CIMObjectPath> referenceArray;
2374                  CIMObjectPath reference;
2375 kumpf   1.28 
2376                  value.clear();
2377              
2378                  // Get VALUE.REFARRAY open tag:
2379              
2380                  if (!testStartTagOrEmptyTag(parser, entry, "VALUE.REFARRAY"))
2381              	return false;
2382              
2383 kumpf   1.32     if (entry.type != XmlEntry::EMPTY_TAG)
2384                  {
2385                      // For each VALUE.REFERENCE element:
2386 kumpf   1.28 
2387 kumpf   1.32         while (getValueReferenceElement(parser, reference))
2388                      {
2389              	    referenceArray.append(reference);
2390                      }
2391 kumpf   1.28 
2392 kumpf   1.32         expectEndTag(parser, "VALUE.REFARRAY");
2393 kumpf   1.28     }
2394              
2395                  value.set(referenceArray);
2396                  return true;
2397              }
2398              
2399              //------------------------------------------------------------------------------
2400              //
2401 mike    1.23 // getPropertyReferenceElement()
2402              //
2403              //     <!ELEMENT PROPERTY.REFERENCE (QUALIFIER*,(VALUE.REFERENCE)?)>
2404              //     <!ATTLIST PROPERTY.REFERENCE
2405              //         %CIMName;
2406              //         %ReferenceClass;
2407              //         %ClassOrigin;
2408              //         %Propagated;>
2409              //
2410              //------------------------------------------------------------------------------
2411              
2412              Boolean XmlReader::getPropertyReferenceElement(
2413                  XmlParser& parser, 
2414                  CIMProperty& property)
2415              {
2416                  XmlEntry entry;
2417              
2418                  if (!testStartTagOrEmptyTag(parser, entry, "PROPERTY.REFERENCE"))
2419              	return false;
2420              
2421                  Boolean empty = entry.type == XmlEntry::EMPTY_TAG;
2422 mike    1.23 
2423                  // Get PROPERTY.NAME attribute:
2424              
2425                  String name = getCimNameAttribute(
2426              	parser.getLine(), entry, "PROPERTY.REFERENCE");
2427              
2428                  // Get PROPERTY.REFERENCECLASS attribute:
2429              
2430 kumpf   1.62     CIMName referenceClass = getReferenceClassAttribute(
2431 mike    1.23 	parser.getLine(), entry, "PROPERTY.REFERENCE");
2432              
2433                  // Get PROPERTY.CLASSORIGIN attribute:
2434              
2435 kumpf   1.62     CIMName classOrigin = 
2436 mike    1.23 	getClassOriginAttribute(parser.getLine(), entry, "PROPERTY.REFERENCE");
2437              
2438                  // Get PROPERTY.PROPAGATED
2439              
2440                  Boolean propagated = getCimBooleanAttribute(parser.getLine(), entry, 
2441              	"PROPERTY.REFERENCE", "PROPAGATED", false, false);
2442              
2443                  // Create property:
2444              
2445 kumpf   1.61     CIMValue value = CIMValue(CIMTYPE_REFERENCE, false, 0);
2446 kumpf   1.54 //    value.set(CIMObjectPath());
2447 mike    1.23     property = CIMProperty(
2448              	name, value, 0, referenceClass, classOrigin, propagated);
2449              
2450                  if (!empty)
2451                  {
2452              	getQualifierElements(parser, property);
2453              
2454 kumpf   1.54 	CIMObjectPath reference;
2455 mike    1.23 
2456              	if (getValueReferenceElement(parser, reference))
2457              	    property.setValue(reference);
2458              
2459              	expectEndTag(parser, "PROPERTY.REFERENCE");
2460                  }
2461              
2462                  return true;
2463              }
2464              
2465              //------------------------------------------------------------------------------
2466              //
2467              // GetPropertyElements()
2468              //
2469              //------------------------------------------------------------------------------
2470              
2471              template<class CONTAINER>
2472              void GetPropertyElements(XmlParser& parser, CONTAINER& container)
2473              {
2474                  CIMProperty property;
2475              
2476 mike    1.23     while (XmlReader::getPropertyElement(parser, property) ||
2477              	XmlReader::getPropertyArrayElement(parser, property) ||
2478              	XmlReader::getPropertyReferenceElement(parser, property))
2479                  {
2480              	try
2481              	{
2482              	    container.addProperty(property);
2483              	}
2484 kumpf   1.66 	catch (AlreadyExistsException&)
2485 mike    1.23 	{
2486              	    throw XmlSemanticError(parser.getLine(), "duplicate property");
2487              	}
2488                  }
2489              }
2490              
2491              //------------------------------------------------------------------------------
2492              //
2493              // getParameterElement()
2494              //
2495              //     <!ELEMENT PARAMETER (QUALIFIER*)>
2496              //     <!ATTLIST PARAMETER
2497              //         %CIMName;
2498              //         %CIMType; #REQUIRED>
2499              //
2500              //------------------------------------------------------------------------------
2501              
2502              Boolean XmlReader::getParameterElement(
2503                  XmlParser& parser, 
2504                  CIMParameter& parameter)
2505              {
2506 mike    1.23     XmlEntry entry;
2507              
2508                  if (!testStartTagOrEmptyTag(parser, entry, "PARAMETER"))
2509              	return false;
2510              
2511                  Boolean empty = entry.type == XmlEntry::EMPTY_TAG;
2512              
2513                  // Get PARAMETER.NAME attribute:
2514              
2515                  String name = getCimNameAttribute(parser.getLine(), entry, "PARAMETER");
2516              
2517                  // Get PARAMETER.TYPE attribute:
2518              
2519 kumpf   1.67     CIMType type;
2520                  getCimTypeAttribute(parser.getLine(), entry, type, "PARAMETER");
2521 mike    1.23 
2522                  // Create parameter:
2523              
2524                  parameter = CIMParameter(name, type);
2525              
2526                  if (!empty)
2527                  {
2528              	getQualifierElements(parser, parameter);
2529              
2530              	expectEndTag(parser, "PARAMETER");
2531                  }
2532              
2533                  return true;
2534              }
2535              
2536              //------------------------------------------------------------------------------
2537              //
2538              // getParameterArrayElement()
2539              //
2540              //     <!ELEMENT PARAMETER.ARRAY (QUALIFIER*)>
2541              //     <!ATTLIST PARAMETER.ARRAY
2542 mike    1.23 //         %CIMName;
2543              //         %CIMType; #REQUIRED
2544              //         %ArraySize;>
2545              //
2546              //------------------------------------------------------------------------------
2547              
2548              Boolean XmlReader::getParameterArrayElement(
2549                  XmlParser& parser, 
2550                  CIMParameter& parameter)
2551              {
2552                  XmlEntry entry;
2553              
2554                  if (!testStartTagOrEmptyTag(parser, entry, "PARAMETER.ARRAY"))
2555              	return false;
2556              
2557                  Boolean empty = entry.type == XmlEntry::EMPTY_TAG;
2558              
2559                  // Get PARAMETER.ARRAY.NAME attribute:
2560              
2561                  String name = getCimNameAttribute(
2562              	parser.getLine(), entry, "PARAMETER.ARRAY");
2563 mike    1.23 
2564                  // Get PARAMETER.ARRAY.TYPE attribute:
2565              
2566 kumpf   1.67     CIMType type;
2567                  getCimTypeAttribute(parser.getLine(), entry, type, "PARAMETER.ARRAY");
2568 mike    1.23 
2569                  // Get PARAMETER.ARRAYSIZE attribute:
2570              
2571                  Uint32 arraySize = 0;
2572                  getArraySizeAttribute(parser.getLine(), entry, "PARAMETER.ARRAY",arraySize);
2573              
2574                  // Create parameter:
2575              
2576                  parameter = CIMParameter(name, type, true, arraySize);
2577              
2578                  if (!empty)
2579                  {
2580              	getQualifierElements(parser, parameter);
2581              
2582              	expectEndTag(parser, "PARAMETER.ARRAY");
2583                  }
2584              
2585                  return true;
2586              }
2587              
2588              //------------------------------------------------------------------------------
2589 mike    1.23 //
2590              // getParameterReferenceElement()
2591              //
2592              //     <!ELEMENT PARAMETER.REFERENCE (QUALIFIER*)>
2593              //     <!ATTLIST PARAMETER.REFERENCE
2594              //         %CIMName;
2595              //         %ReferenceClass;>
2596              //
2597              //------------------------------------------------------------------------------
2598              
2599              Boolean XmlReader::getParameterReferenceElement(
2600                  XmlParser& parser, 
2601                  CIMParameter& parameter)
2602              {
2603                  XmlEntry entry;
2604              
2605                  if (!testStartTagOrEmptyTag(parser, entry, "PARAMETER.REFERENCE"))
2606              	return false;
2607              
2608                  Boolean empty = entry.type == XmlEntry::EMPTY_TAG;
2609              
2610 mike    1.23     // Get PARAMETER.NAME attribute:
2611              
2612                  String name = getCimNameAttribute(
2613              	parser.getLine(), entry, "PARAMETER.REFERENCE");
2614              
2615                  // Get PARAMETER.REFERENCECLASS attribute:
2616              
2617 kumpf   1.62     CIMName referenceClass = getReferenceClassAttribute(
2618 mike    1.23 	parser.getLine(), entry, "PARAMETER.REFERENCE");
2619              
2620                  // Create parameter:
2621              
2622 kumpf   1.61     parameter = CIMParameter(name, CIMTYPE_REFERENCE, false, 0, referenceClass);
2623 mike    1.23 
2624                  if (!empty)
2625                  {
2626              	getQualifierElements(parser, parameter);
2627              	expectEndTag(parser, "PARAMETER.REFERENCE");
2628                  }
2629              
2630                  return true;
2631              }
2632              
2633              //------------------------------------------------------------------------------
2634              //
2635 kumpf   1.26 // getParameterReferenceArrayElement()
2636              //
2637              //     <!ELEMENT PARAMETER.REFARRAY (QUALIFIER*)>
2638              //     <!ATTLIST PARAMETER.REFARRAY
2639              //         %CIMName;
2640              //         %ReferenceClass;
2641              //         %ArraySize;>
2642              //
2643              //------------------------------------------------------------------------------
2644              
2645              Boolean XmlReader::getParameterReferenceArrayElement(
2646                  XmlParser& parser, 
2647                  CIMParameter& parameter)
2648              {
2649                  XmlEntry entry;
2650              
2651                  if (!testStartTagOrEmptyTag(parser, entry, "PARAMETER.REFARRAY"))
2652              	return false;
2653              
2654                  Boolean empty = entry.type == XmlEntry::EMPTY_TAG;
2655              
2656 kumpf   1.26     // Get PARAMETER.NAME attribute:
2657              
2658                  String name = getCimNameAttribute(
2659              	parser.getLine(), entry, "PARAMETER.REFARRAY");
2660              
2661                  // Get PARAMETER.REFERENCECLASS attribute:
2662              
2663 kumpf   1.62     CIMName referenceClass = getReferenceClassAttribute(
2664 kumpf   1.26 	parser.getLine(), entry, "PARAMETER.REFARRAY");
2665              
2666                  // Get PARAMETER.ARRAYSIZE attribute:
2667              
2668                  Uint32 arraySize = 0;
2669                  getArraySizeAttribute(parser.getLine(), entry, "PARAMETER.REFARRAY",
2670              			  arraySize);
2671              
2672                  // Create parameter:
2673              
2674 kumpf   1.61     parameter = CIMParameter(name, CIMTYPE_REFERENCE, true, arraySize,
2675 kumpf   1.26 			     referenceClass);
2676              
2677                  if (!empty)
2678                  {
2679              	getQualifierElements(parser, parameter);
2680              	expectEndTag(parser, "PARAMETER.REFARRAY");
2681                  }
2682              
2683                  return true;
2684              }
2685              
2686              //------------------------------------------------------------------------------
2687              //
2688 mike    1.23 // GetParameterElements()
2689              //
2690              //------------------------------------------------------------------------------
2691              
2692              template<class CONTAINER>
2693              void GetParameterElements(XmlParser& parser, CONTAINER& container)
2694              {
2695                  CIMParameter parameter;
2696              
2697                  while (XmlReader::getParameterElement(parser, parameter) ||
2698              	XmlReader::getParameterArrayElement(parser, parameter) ||
2699 kumpf   1.26 	XmlReader::getParameterReferenceElement(parser, parameter) ||
2700              	XmlReader::getParameterReferenceArrayElement(parser, parameter))
2701 mike    1.23     {
2702              	try
2703              	{
2704              	    container.addParameter(parameter);
2705              	}
2706 kumpf   1.66 	catch (AlreadyExistsException&)
2707 mike    1.23 	{
2708              	    throw XmlSemanticError(parser.getLine(), "duplicate parameter");
2709              	}
2710                  }
2711              }
2712              
2713              //------------------------------------------------------------------------------
2714              //
2715              // getQualifierDeclElement()
2716              //
2717              //     <!ELEMENT QUALIFIER.DECLARATION (SCOPE?,(VALUE|VALUE.ARRAY)?)>
2718              //     <!ATTLIST QUALIFIER.DECLARATION 
2719              //         %CIMName;               
2720              //         %CIMType; #REQUIRED
2721              //         ISARRAY (true|false) #IMPLIED
2722              //         %ArraySize;
2723              //         %QualifierFlavor;>
2724              //         
2725              //------------------------------------------------------------------------------
2726              
2727              Boolean XmlReader::getQualifierDeclElement(
2728 mike    1.23     XmlParser& parser, 
2729                  CIMQualifierDecl& qualifierDecl)
2730              {
2731                  XmlEntry entry;
2732              
2733                  if (!testStartTagOrEmptyTag(parser, entry, "QUALIFIER.DECLARATION"))
2734              	return false;
2735              
2736                  Boolean empty = entry.type == XmlEntry::EMPTY_TAG;
2737              
2738                  // Get NAME attribute:
2739              
2740                  String name = getCimNameAttribute(
2741              	parser.getLine(), entry, "QUALIFIER.DECLARATION");
2742              
2743                  // Get TYPE attribute:
2744              
2745 kumpf   1.67     CIMType type;
2746                  getCimTypeAttribute(parser.getLine(), entry, type, "QUALIFIER.DECLARATION");
2747 mike    1.23 
2748                  // Get ISARRAY attribute:
2749              
2750 mike    1.25     Boolean isArray = getCimBooleanAttribute(
2751                      parser.getLine(), entry, "QUALIFIER.DECLARATION", "ISARRAY",
2752                      false, false); 
2753 mike    1.23 
2754                  // Get ARRAYSIZE attribute:
2755              
2756                  Uint32 arraySize = 0;
2757                  Boolean gotArraySize = getArraySizeAttribute(parser.getLine(),
2758              	entry, "QUALIFIER.DECLARATION", arraySize);
2759              
2760                  // Get flavor oriented attributes:
2761              
2762 kumpf   1.64     CIMFlavor flavor = getFlavor (entry, parser.getLine (), 
2763                      "QUALIFIER.DECLARATION");
2764 mike    1.23 
2765                  // No need to look for interior elements if empty tag:
2766              
2767 kumpf   1.63     CIMScope scope = CIMScope ();
2768 mike    1.23     CIMValue value;
2769 kumpf   1.67     Boolean gotValue = false;
2770 mike    1.23 
2771                  if (!empty)
2772                  {
2773              	// Get the option SCOPE element:
2774              
2775              	scope = getOptionalScope(parser);
2776              
2777              	// Get VALUE or VALUE.ARRAY element:
2778              
2779              	if (getValueArrayElement(parser, type, value))
2780              	{
2781              	    if (!isArray)
2782              	    {
2783              		throw XmlSemanticError(parser.getLine(),
2784              		    "VALUE.ARRAY element encountered without "
2785              		    "ISARRAY attribute");
2786              	    }
2787              
2788              	    if (arraySize && arraySize != value.getArraySize())
2789              	    {
2790              		throw XmlSemanticError(parser.getLine(),
2791 mike    1.23 		    "VALUE.ARRAY size is not the same as "
2792              		    "ARRAYSIZE attribute");
2793              	    }
2794 kumpf   1.67 
2795                          gotValue = true;
2796 mike    1.23 	}
2797              	else if (getValueElement(parser, type, value))
2798              	{
2799              	    if (isArray)
2800              	    {
2801              		throw XmlSemanticError(parser.getLine(),
2802              		    "ISARRAY attribute used but VALUE element encountered");
2803              	    }
2804 kumpf   1.67 
2805                          gotValue = true;
2806 mike    1.23 	}
2807              
2808              	// Now get the closing tag:
2809              
2810              	expectEndTag(parser, "QUALIFIER.DECLARATION");
2811                  }
2812              
2813 kumpf   1.67     if (!gotValue)
2814 mike    1.23     {
2815              	if (isArray)
2816              	    value.setNullValue(type, true, arraySize);
2817              	else
2818              	    value.setNullValue(type, false);
2819                  }
2820              
2821                  CIMQualifierDecl tmp(name, value, scope, flavor, arraySize);
2822                  qualifierDecl = CIMQualifierDecl(name, value, scope, flavor, arraySize);
2823                  return true;
2824              }
2825              
2826              //------------------------------------------------------------------------------
2827              // getMethodElement()
2828              //
2829              //     <!ELEMENT METHOD (QUALIFIER*,(PARAMETER|PARAMETER.REFERENCE|
2830              //         PARAMETER.ARRAY|PARAMETER.REFARRAY)*)>
2831              //     <!ATTLIST METHOD
2832              //         %CIMName;
2833              //         %CIMType; #IMPLIED
2834              //         %ClassOrigin;
2835 mike    1.23 //         %Propagated;>
2836              //
2837              //------------------------------------------------------------------------------
2838              
2839              Boolean XmlReader::getMethodElement(XmlParser& parser, CIMMethod& method)
2840              {
2841                  XmlEntry entry;
2842              
2843                  if (!testStartTagOrEmptyTag(parser, entry, "METHOD"))
2844              	return false;
2845              
2846                  Boolean empty = entry.type == XmlEntry::EMPTY_TAG;
2847              
2848                  String name = getCimNameAttribute(parser.getLine(), entry, "PROPERTY");
2849              
2850 kumpf   1.67     CIMType type;
2851                  getCimTypeAttribute(parser.getLine(), entry, type, "PROPERTY");
2852 mike    1.23 
2853 kumpf   1.62     CIMName classOrigin = 
2854 mike    1.23 	getClassOriginAttribute(parser.getLine(), entry, "PROPERTY");
2855              
2856                  Boolean propagated = getCimBooleanAttribute(
2857              	parser.getLine(), entry, "PROPERTY", "PROPAGATED", false, false);
2858              
2859                  method = CIMMethod(name, type, classOrigin, propagated);
2860              
2861                  if (!empty)
2862                  {
2863 kumpf   1.26         // ATTN-RK-P2-20020219: Decoding algorithm must not depend on the
2864                      // ordering of qualifiers and parameters.
2865 mike    1.23 	getQualifierElements(parser, method);
2866              
2867              	GetParameterElements(parser, method);
2868              
2869              	expectEndTag(parser, "METHOD");
2870                  }
2871              
2872                  return true;
2873              }
2874              
2875              //------------------------------------------------------------------------------
2876              // getClassElement()
2877              //
2878              //     <!ELEMENT CLASS (QUALIFIER*,
2879              //         (PROPERTY|PROPERTY.ARRAY|PROPERTY.REFERENCE)*,METHOD*)>
2880              //     <!ATTLIST CLASS %CIMName; %SuperClass;>
2881              //
2882              //------------------------------------------------------------------------------
2883              
2884              Boolean XmlReader::getClassElement(XmlParser& parser, CIMClass& cimClass)
2885              {
2886 mike    1.23     XmlEntry entry;
2887              
2888                  if (!testStartTag(parser, entry, "CLASS"))
2889              	return false;
2890              
2891                  String name = getCimNameAttribute(parser.getLine(), entry, "CLASS");
2892              
2893 kumpf   1.62     CIMName superClass = getSuperClassAttribute(parser.getLine(), entry,"CLASS");
2894 mike    1.23 
2895                  cimClass = CIMClass(name, superClass);
2896              
2897                  // Get QUALIFIER elements:
2898              
2899                  getQualifierElements(parser, cimClass);
2900              
2901                  // Get PROPERTY elements:
2902              
2903                  GetPropertyElements(parser, cimClass);
2904              
2905                  // Get METHOD elements:
2906              
2907                  CIMMethod method;
2908              
2909                  while (getMethodElement(parser, method))
2910              	cimClass.addMethod(method);	
2911              
2912                  // Get CLASS end tag:
2913              
2914                  expectEndTag(parser, "CLASS");
2915 mike    1.23 
2916                  return true;
2917              }
2918              
2919              //------------------------------------------------------------------------------
2920              // getInstanceElement()
2921              //
2922              //     <!ELEMENT INSTANCE (QUALIFIER*,
2923              //         (PROPERTY|PROPERTY.ARRAY|PROPERTY.REFERENCE)*) >
2924              //     <!ATTLIST INSTANCE
2925              //         %ClassName;>
2926              //
2927              //------------------------------------------------------------------------------
2928              
2929              Boolean XmlReader::getInstanceElement(
2930                  XmlParser& parser, 
2931                  CIMInstance& cimInstance)
2932              {
2933                  XmlEntry entry;
2934              
2935                  if (!testStartTag(parser, entry, "INSTANCE"))
2936 mike    1.23 	return false;
2937              
2938                  String className = getClassNameAttribute(
2939              	parser.getLine(), entry, "INSTANCE");
2940              
2941                  cimInstance = CIMInstance(className);
2942              
2943                  // Get QUALIFIER elements:
2944              
2945                  getQualifierElements(parser, cimInstance);
2946              
2947                  // Get PROPERTY elements:
2948              
2949                  GetPropertyElements(parser, cimInstance);
2950              
2951                  // Get INSTANCE end tag:
2952              
2953                  expectEndTag(parser, "INSTANCE");
2954              
2955                  return true;
2956              }
2957 mike    1.23 
2958              //------------------------------------------------------------------------------
2959 mike    1.25 // getNamedInstanceElement()
2960              //
2961              //     <!ELEMENT VALUE.NAMEDINSTANCE (INSTANCENAME,INSTANCE)>
2962              //
2963              //------------------------------------------------------------------------------
2964              
2965              Boolean XmlReader::getNamedInstanceElement(
2966                  XmlParser& parser, 
2967 kumpf   1.55     CIMInstance& namedInstance)
2968 mike    1.25 {
2969                  XmlEntry entry;
2970              
2971                  if (!testStartTag(parser, entry, "VALUE.NAMEDINSTANCE"))
2972              	return false;
2973              
2974 kumpf   1.54     CIMObjectPath instanceName;
2975 mike    1.25 
2976                  // Get INSTANCENAME elements:
2977              
2978                  if (!getInstanceNameElement(parser, instanceName))
2979                  {
2980              	throw XmlValidationError(parser.getLine(), 
2981              	    "expected INSTANCENAME element");
2982                  }
2983              
2984                  // Get INSTANCE elements:
2985              
2986 kumpf   1.55     if (!getInstanceElement(parser, namedInstance))
2987 mike    1.25     {
2988              	throw XmlValidationError(parser.getLine(),
2989              	    "expected INSTANCE element");
2990                  }
2991              
2992                  // Get VALUE.NAMEDINSTANCE end tag:
2993              
2994                  expectEndTag(parser, "VALUE.NAMEDINSTANCE");
2995              
2996 kumpf   1.55     namedInstance.setPath (instanceName);
2997 mike    1.25 
2998                  return true;
2999              }
3000              
3001              //------------------------------------------------------------------------------
3002 mike    1.23 //
3003              // getObject()
3004              //
3005              //------------------------------------------------------------------------------
3006              
3007              void XmlReader::getObject(XmlParser& parser, CIMClass& x)
3008              {
3009                  if (!getClassElement(parser, x))
3010                  {
3011              	throw XmlValidationError(parser.getLine(),
3012              	    "expected CLASS element");
3013                  }
3014              }
3015              
3016              //------------------------------------------------------------------------------
3017              //
3018              // getObject()
3019              //
3020              //------------------------------------------------------------------------------
3021              
3022              void XmlReader::getObject(XmlParser& parser, CIMInstance& x)
3023 mike    1.23 {
3024                  if (!getInstanceElement(parser, x))
3025                  {
3026              	throw XmlValidationError(parser.getLine(),
3027              	    "expected INSTANCE element");
3028                  }
3029              }
3030              
3031              //------------------------------------------------------------------------------
3032              //
3033              // getObject()
3034              //
3035              //------------------------------------------------------------------------------
3036              
3037              void XmlReader::getObject(XmlParser& parser, CIMQualifierDecl& x)
3038              {
3039                  if (!getQualifierDeclElement(parser, x))
3040                  {
3041              	throw XmlValidationError(parser.getLine(),
3042              	    "expected QUALIFIER.DECLARATION element");
3043                  }
3044 mike    1.23 }
3045              
3046              //------------------------------------------------------------------------------
3047              //
3048              // getMessageStartTag()
3049              //
3050              //------------------------------------------------------------------------------
3051              
3052              Boolean XmlReader::getMessageStartTag(
3053                  XmlParser& parser, 
3054                  String& id,
3055 kumpf   1.34     String& protocolVersion)
3056 mike    1.23 {
3057                  XmlEntry entry;
3058              
3059                  if (!testStartTag(parser, entry, "MESSAGE"))
3060              	return false;
3061              
3062                  // Get MESSAGE.ID:
3063              
3064                  if (!entry.getAttributeValue("ID", id))
3065              	throw XmlValidationError(parser.getLine(), 
3066 kumpf   1.66 	    "Invalid or missing MESSAGE.ID attribute");
3067 mike    1.23 
3068                  // Get MESSAGE.PROTOCOLVERSION:
3069              
3070                  if (!entry.getAttributeValue("PROTOCOLVERSION", protocolVersion))
3071              	throw XmlValidationError(parser.getLine(),
3072 kumpf   1.66 	    "Invalid or missing MESSAGE.PROTOCOLVERSION attribute");
3073 mike    1.23 
3074                  return true;
3075              }
3076              
3077              //------------------------------------------------------------------------------
3078              //
3079              // getIMethodCallStartTag()
3080              //
3081              //------------------------------------------------------------------------------
3082              
3083              Boolean XmlReader::getIMethodCallStartTag(
3084                  XmlParser& parser, 
3085                  const char*& name)
3086              {
3087                  XmlEntry entry;
3088              
3089                  if (!testStartTag(parser, entry, "IMETHODCALL"))
3090              	return false;
3091              
3092                  // Get IMETHODCALL.NAME attribute:
3093              
3094 mike    1.23     if (!entry.getAttributeValue("NAME", name))
3095              	throw XmlValidationError(parser.getLine(),
3096              	    "Missing IMETHODCALL.NAME attribute");
3097              
3098                  return true;
3099              }
3100              
3101              //------------------------------------------------------------------------------
3102              //
3103              // getIMethodResponseStartTag()
3104              //
3105              //------------------------------------------------------------------------------
3106              
3107              Boolean XmlReader::getIMethodResponseStartTag(
3108                  XmlParser& parser, 
3109                  const char*& name)
3110              {
3111                  XmlEntry entry;
3112              
3113                  if (!testStartTag(parser, entry, "IMETHODRESPONSE"))
3114              	return false;
3115 mike    1.23 
3116                  // Get IMETHODRESPONSE.NAME attribute:
3117              
3118                  if (!entry.getAttributeValue("NAME", name))
3119              	throw XmlValidationError(parser.getLine(),
3120              	    "Missing IMETHODRESPONSE.NAME attribute");
3121              
3122                  return true;
3123              }
3124              
3125              //------------------------------------------------------------------------------
3126              //
3127              // getIParamValueTag()
3128              //
3129              //------------------------------------------------------------------------------
3130              
3131              Boolean XmlReader::getIParamValueTag(
3132                  XmlParser& parser, 
3133                  const char*& name)
3134              {
3135                  XmlEntry entry;
3136 mike    1.23 
3137                  if (!testStartTag(parser, entry, "IPARAMVALUE"))
3138              	return false;
3139              
3140                  // Get IPARAMVALUE.NAME attribute:
3141              
3142                  if (!entry.getAttributeValue("NAME", name))
3143              	throw XmlValidationError(parser.getLine(),
3144              	    "Missing IPARAMVALUE.NAME attribute");
3145              
3146                  return true;
3147              }
3148              
3149              //------------------------------------------------------------------------------
3150              //
3151              // getBooleanValueElement()
3152              //
3153              //     Get an elements like: "<VALUE>FALSE</VALUE>"
3154              //
3155              //------------------------------------------------------------------------------
3156              
3157 mike    1.23 Boolean XmlReader::getBooleanValueElement(
3158                  XmlParser& parser, 
3159                  Boolean& result,
3160                  Boolean required)
3161              {
3162                  XmlEntry entry;
3163              
3164                  if (!testStartTag(parser, entry, "VALUE"))
3165                  {
3166              	if (required)
3167              	{
3168              	    throw XmlValidationError(parser.getLine(),
3169              		"Expected VALUE element");
3170              	}
3171              	return false;
3172                  }
3173              
3174                  expectContentOrCData(parser, entry);
3175              
3176 mike    1.25     if (CompareNoCase(entry.text, "TRUE") == 0)
3177 mike    1.23 	result = true;
3178 mike    1.25     else if (CompareNoCase(entry.text, "FALSE") == 0)
3179 mike    1.23 	result = false;
3180                  else
3181              	throw XmlSemanticError(parser.getLine(), 
3182 kumpf   1.66 	    "Invalid value for VALUE element: must be \"TRUE\" or \"FALSE\"");
3183 mike    1.23 
3184                  expectEndTag(parser, "VALUE");
3185              
3186                  return true;
3187              }
3188              
3189              //------------------------------------------------------------------------------
3190              //
3191              // getErrorElement()
3192              //
3193              //     <!ELEMENT ERROR EMPTY>
3194              //     <!ATTLIST ERROR 
3195              //         CODE CDATA #REQUIRED
3196              //         DESCRIPTION CDATA #IMPLIED>
3197              //
3198              //------------------------------------------------------------------------------
3199              
3200              Boolean XmlReader::getErrorElement(
3201                  XmlParser& parser, 
3202 kumpf   1.50     CIMException& cimException,
3203 mike    1.23     Boolean required)
3204              {
3205                  XmlEntry entry;
3206              
3207                  if (!testStartTagOrEmptyTag(parser, entry, "ERROR"))
3208                  {
3209              	if (required)
3210              	    throw XmlValidationError(parser.getLine(),"Expected ERROR element");
3211              	return false;
3212                  }
3213              
3214                  Boolean empty = entry.type == XmlEntry::EMPTY_TAG;
3215              
3216                  // Get ERROR.CODE
3217              
3218                  Uint32 tmpCode;
3219              
3220                  if (!entry.getAttributeValue("CODE", tmpCode))
3221              	throw XmlValidationError(
3222              	    parser.getLine(), "missing ERROR.CODE attribute");
3223              
3224 kumpf   1.50     // Get ERROR.DESCRIPTION:
3225 mike    1.23 
3226 kumpf   1.50     String tmpDescription;
3227 mike    1.23 
3228 kumpf   1.50     entry.getAttributeValue("DESCRIPTION", tmpDescription);
3229 mike    1.23 
3230                  if (!empty)
3231              	expectEndTag(parser, "ERROR");
3232              
3233 kumpf   1.50     cimException = PEGASUS_CIM_EXCEPTION(CIMStatusCode(tmpCode), tmpDescription);
3234 mike    1.23     return true;
3235              }
3236              
3237              
3238              //------------------------------------------------------------------------------
3239 kumpf   1.48 // getValueObjectElement()
3240              //
3241              // <!ELEMENT VALUE.OBJECT (CLASS|INSTANCE)>
3242              //
3243              //------------------------------------------------------------------------------
3244              
3245              Boolean XmlReader::getValueObjectElement(
3246                  XmlParser& parser, 
3247                  CIMObject& object)
3248              {
3249                  XmlEntry entry;
3250              
3251                  if (!testStartTag(parser, entry, "VALUE.OBJECT"))
3252              	return false;
3253              
3254                  CIMInstance cimInstance;
3255                  CIMClass cimClass;
3256              
3257                  if (XmlReader::getInstanceElement(parser, cimInstance))
3258                  {
3259              	object = CIMObject(cimInstance);
3260 kumpf   1.48     }
3261                  else if (!XmlReader::getClassElement(parser, cimClass))
3262                  {
3263              	object = CIMObject(cimClass);
3264                  }
3265                  else
3266                  {
3267                      throw XmlValidationError(parser.getLine(),
3268                          "Expected INSTANCE or CLASS element");
3269                  }
3270              
3271                  expectEndTag(parser, "VALUE.OBJECT");
3272              
3273                  return true;
3274              }
3275              
3276              //------------------------------------------------------------------------------
3277              // getValueObjectWithPathElement()
3278 mike    1.23 //
3279              // <!ELEMENT VALUE.OBJECTWITHPATH ((CLASSPATH,CLASS)|(INSTANCEPATH,INSTANCE))>
3280              //
3281              //------------------------------------------------------------------------------
3282              
3283 kumpf   1.48 Boolean XmlReader::getValueObjectWithPathElement(
3284 mike    1.23     XmlParser& parser, 
3285 kumpf   1.57     CIMObject& objectWithPath)
3286 mike    1.23 {
3287                  XmlEntry entry;
3288              
3289                  if (!testStartTag(parser, entry, "VALUE.OBJECTWITHPATH"))
3290              	return false;
3291              
3292 kumpf   1.54     CIMObjectPath reference;
3293 mike    1.23     Boolean isInstance = false;
3294              
3295                  if (XmlReader::getInstancePathElement(parser, reference))
3296              	isInstance = true;
3297                  else if (!XmlReader::getClassPathElement(parser, reference))
3298                  {
3299 kumpf   1.48         throw XmlValidationError(parser.getLine(),
3300                          "Expected INSTANCEPATH or CLASSPATH element");
3301 mike    1.23     }
3302              
3303                  if (isInstance)
3304                  {
3305              	CIMInstance cimInstance;
3306              
3307              	if (!XmlReader::getInstanceElement(parser, cimInstance))
3308              	{
3309              	    throw XmlValidationError(parser.getLine(),
3310 kumpf   1.48 	        "Expected INSTANCE element");
3311 mike    1.23 	}
3312 kumpf   1.57 	objectWithPath = CIMObject (cimInstance);
3313                      objectWithPath.setPath (reference);
3314 mike    1.23     }
3315                  else
3316                  {
3317              	CIMClass cimClass;
3318              
3319              	if (!XmlReader::getClassElement(parser, cimClass))
3320              	{
3321              	    throw XmlValidationError(parser.getLine(),
3322              		"Expected CLASS element");
3323              	}
3324 kumpf   1.57 	objectWithPath = CIMObject (cimClass);
3325                      objectWithPath.setPath (reference);
3326 mike    1.23     }
3327              
3328                  expectEndTag(parser, "VALUE.OBJECTWITHPATH");
3329              
3330                  return true;
3331 kumpf   1.48 }
3332              
3333              //------------------------------------------------------------------------------
3334              // getValueObjectWithLocalPathElement()
3335              //
3336              // <!ELEMENT VALUE.OBJECTWITHLOCALPATH
3337              //     ((LOCALCLASSPATH,CLASS)|(LOCALINSTANCEPATH,INSTANCE))>
3338              //
3339              //------------------------------------------------------------------------------
3340              
3341              Boolean XmlReader::getValueObjectWithLocalPathElement(
3342                  XmlParser& parser, 
3343 kumpf   1.57     CIMObject& objectWithPath)
3344 kumpf   1.48 {
3345                  XmlEntry entry;
3346              
3347                  if (!testStartTag(parser, entry, "VALUE.OBJECTWITHLOCALPATH"))
3348              	return false;
3349              
3350 kumpf   1.54     CIMObjectPath reference;
3351 kumpf   1.48     Boolean isInstance = false;
3352              
3353                  if (XmlReader::getLocalInstancePathElement(parser, reference))
3354              	isInstance = true;
3355                  else if (!XmlReader::getLocalClassPathElement(parser, reference))
3356                  {
3357                      throw XmlValidationError(parser.getLine(),
3358              	    "Expected LOCALINSTANCEPATH or LOCALCLASSPATH element");
3359                  }
3360              
3361                  if (isInstance)
3362                  {
3363              	CIMInstance cimInstance;
3364              
3365              	if (!XmlReader::getInstanceElement(parser, cimInstance))
3366              	{
3367              	    throw XmlValidationError(parser.getLine(),
3368              	        "Expected INSTANCE element");
3369              	}
3370 kumpf   1.57 	objectWithPath = CIMObject (cimInstance);
3371              	objectWithPath.setPath (reference);
3372 kumpf   1.48     }
3373                  else
3374                  {
3375              	CIMClass cimClass;
3376              
3377              	if (!XmlReader::getClassElement(parser, cimClass))
3378              	{
3379              	    throw XmlValidationError(parser.getLine(),
3380              		"Expected CLASS element");
3381              	}
3382 kumpf   1.57 	objectWithPath = CIMObject (cimClass);
3383              	objectWithPath.setPath (reference);
3384 kumpf   1.48     }
3385              
3386                  expectEndTag(parser, "VALUE.OBJECTWITHLOCALPATH");
3387              
3388                  return true;
3389              }
3390              
3391              //------------------------------------------------------------------------------
3392              // getObjectArray()
3393              //
3394              // <object>
3395              //     (VALUE.OBJECT|VALUE.OBJECTWITHLOCALPATH|VALUE.OBJECTWITHPATH)
3396              //
3397              //------------------------------------------------------------------------------
3398              
3399              void XmlReader::getObjectArray(
3400                  XmlParser& parser, 
3401 kumpf   1.57     Array<CIMObject>& objectArray)
3402 kumpf   1.48 {
3403                  CIMObject object;
3404 kumpf   1.57     CIMObject objectWithPath;
3405 kumpf   1.48 
3406                  objectArray.clear();
3407              
3408                  if (getValueObjectElement(parser, object))
3409                  {
3410 kumpf   1.57         objectArray.append(object);
3411 kumpf   1.48         while (getValueObjectElement(parser, object))
3412 kumpf   1.57             objectArray.append(object);
3413 kumpf   1.48     }
3414                  else if (getValueObjectWithPathElement(parser, objectWithPath))
3415                  {
3416                      objectArray.append(objectWithPath);
3417                      while (getValueObjectWithPathElement(parser, objectWithPath))
3418                          objectArray.append(objectWithPath);
3419                  }
3420                  else if (getValueObjectWithLocalPathElement(parser, objectWithPath))
3421                  {
3422                      objectArray.append(objectWithPath);
3423                      while (getValueObjectWithLocalPathElement(parser, objectWithPath))
3424                          objectArray.append(objectWithPath);
3425                  }
3426 mike    1.23 }
3427              
3428              //------------------------------------------------------------------------------
3429              //
3430              // <objectName>: (CLASSNAME|INSTANCENAME)
3431              //
3432              //------------------------------------------------------------------------------
3433              
3434              Boolean XmlReader::getObjectNameElement(
3435                  XmlParser& parser, 
3436 kumpf   1.54     CIMObjectPath& objectName)
3437 mike    1.23 {
3438                  String className;
3439              
3440                  if (getClassNameElement(parser, className, false))
3441                  {
3442 kumpf   1.62 	objectName.set(String(), CIMNamespaceName(), className);
3443 mike    1.23 	return true;
3444                  }
3445                  else if (getInstanceNameElement(parser, objectName))
3446              	return true;
3447                  else
3448                  {
3449              	throw XmlValidationError(parser.getLine(),
3450              	    "expected CLASSNAME or INSTANCENAME element");
3451                  }
3452              
3453                  return false;
3454              }
3455              
3456              //------------------------------------------------------------------------------
3457              //
3458              // <!ELEMENT OBJECTPATH (INSTANCEPATH|CLASSPATH)>
3459              //
3460              //------------------------------------------------------------------------------
3461              
3462              Boolean XmlReader::getObjectPathElement(
3463                  XmlParser& parser, 
3464 kumpf   1.54     CIMObjectPath& objectPath)
3465 mike    1.23 {
3466                  XmlEntry entry;
3467              
3468                  if (!testStartTag(parser, entry, "OBJECTPATH"))
3469              	return false;
3470              
3471                  if (getClassPathElement(parser, objectPath))
3472                  {
3473              	expectEndTag(parser, "OBJECTPATH");
3474              	return true;
3475                  }
3476                  else if (getInstancePathElement(parser, objectPath))
3477                  {
3478              	expectEndTag(parser, "OBJECTPATH");
3479              	return true;
3480                  }
3481                  else
3482                  {
3483              	throw XmlValidationError(parser.getLine(),
3484              	    "expected INSTANCEPATH or CLASSPATH element");
3485                  }
3486 mike    1.23 
3487 mike    1.24     PEGASUS_UNREACHABLE ( return false; )
3488 mike    1.25 }
3489              
3490              //------------------------------------------------------------------------------
3491              //
3492              // getEMethodCallStartTag()
3493              //
3494              //------------------------------------------------------------------------------
3495              
3496              Boolean XmlReader::getEMethodCallStartTag(
3497                  XmlParser& parser, 
3498                  const char*& name)
3499              {
3500                  XmlEntry entry;
3501              
3502                  if (!testStartTag(parser, entry, "EXPMETHODCALL"))
3503              	return false;
3504              
3505                  // Get EXPMETHODCALL.NAME attribute:
3506              
3507                  if (!entry.getAttributeValue("NAME", name))
3508              	throw XmlValidationError(parser.getLine(),
3509 mike    1.25 	    "Missing EXPMETHODCALL.NAME attribute");
3510              
3511                  return true;
3512              }
3513              
3514              //------------------------------------------------------------------------------
3515              //
3516              // getEMethodResponseStartTag()
3517              //
3518              //------------------------------------------------------------------------------
3519              
3520              Boolean XmlReader::getEMethodResponseStartTag(
3521                  XmlParser& parser, 
3522                  const char*& name)
3523              {
3524                  XmlEntry entry;
3525              
3526                  if (!testStartTag(parser, entry, "EXPMETHODRESPONSE"))
3527              	return false;
3528              
3529                  // Get EXPMETHODRESPONSE.NAME attribute:
3530 mike    1.25 
3531                  if (!entry.getAttributeValue("NAME", name))
3532              	throw XmlValidationError(parser.getLine(),
3533              	    "Missing EXPMETHODRESPONSE.NAME attribute");
3534              
3535                  return true;
3536              }
3537              
3538              //------------------------------------------------------------------------------
3539              //
3540              // getMethodCallStartTag()
3541              //
3542              //------------------------------------------------------------------------------
3543              
3544              Boolean XmlReader::getMethodCallStartTag(
3545                  XmlParser& parser, 
3546                  const char*& name)
3547              {
3548                  XmlEntry entry;
3549              
3550                  if (!testStartTag(parser, entry, "METHODCALL"))
3551 mike    1.25 	return false;
3552              
3553                  // Get METHODCALL.NAME attribute:
3554              
3555                  if (!entry.getAttributeValue("NAME", name))
3556              	throw XmlValidationError(parser.getLine(),
3557              	    "Missing METHODCALL.NAME attribute");
3558              
3559                  return true;
3560              }
3561              
3562              //------------------------------------------------------------------------------
3563              //
3564              // getMethodResponseStartTag()
3565              //
3566              //------------------------------------------------------------------------------
3567              
3568              Boolean XmlReader::getMethodResponseStartTag(
3569                  XmlParser& parser, 
3570                  const char*& name)
3571              {
3572 mike    1.25     XmlEntry entry;
3573              
3574                  if (!testStartTag(parser, entry, "METHODRESPONSE"))
3575              	return false;
3576              
3577                  // Get METHODRESPONSE.NAME attribute:
3578              
3579                  if (!entry.getAttributeValue("NAME", name))
3580              	throw XmlValidationError(parser.getLine(),
3581              	    "Missing METHODRESPONSE.NAME attribute");
3582              
3583                  return true;
3584              }
3585              
3586              //------------------------------------------------------------------------------
3587              //
3588 kumpf   1.26 // getParamValueElement()
3589              //
3590              // <!ELEMENT PARAMVALUE (VALUE|VALUE.REFERENCE|VALUE.ARRAY|VALUE.REFARRAY)?>
3591              // <!ATTLIST PARAMVALUE
3592              //      %CIMName;
3593              //      %ParamType;>
3594 mike    1.25 //
3595              //------------------------------------------------------------------------------
3596              
3597 kumpf   1.26 Boolean XmlReader::getParamValueElement(
3598 mike    1.25     XmlParser& parser, 
3599 kumpf   1.26     CIMParamValue& paramValue)
3600 mike    1.25 {
3601                  XmlEntry entry;
3602 kumpf   1.26     const char* name;
3603                  CIMType type;
3604                  CIMValue value;
3605 mike    1.25 
3606 kumpf   1.26     if (!testStartTagOrEmptyTag(parser, entry, "PARAMVALUE"))
3607 mike    1.25 	return false;
3608              
3609 kumpf   1.26     Boolean empty = entry.type == XmlEntry::EMPTY_TAG;
3610              
3611                  // Get PARAMVALUE.NAME attribute:
3612 mike    1.25 
3613                  if (!entry.getAttributeValue("NAME", name))
3614              	throw XmlValidationError(parser.getLine(),
3615              	    "Missing PARAMVALUE.NAME attribute");
3616 kumpf   1.26 
3617                  // Get PARAMVALUE.PARAMTYPE attribute:
3618              
3619 kumpf   1.67     Boolean gotType = getCimTypeAttribute(parser.getLine(), entry, type,
3620                                                        "PARAMVALUE", "PARAMTYPE", false);
3621 kumpf   1.26 
3622                  if (!empty)
3623                  {
3624                      // Parse VALUE.REFERENCE and VALUE.REFARRAY type
3625 kumpf   1.67         if ( (type == CIMTYPE_REFERENCE) || !gotType )
3626 kumpf   1.26         {
3627 kumpf   1.54 	    CIMObjectPath reference;
3628 kumpf   1.26 	    if (XmlReader::getValueReferenceElement(parser, reference))
3629              	    {
3630              	        value.set(reference);
3631 kumpf   1.61 	        type = CIMTYPE_REFERENCE;
3632 kumpf   1.67                 gotType = true;
3633 kumpf   1.26 	    }
3634 kumpf   1.28             else if (XmlReader::getValueReferenceArrayElement(parser, value))
3635              	    {
3636 kumpf   1.61 	        type = CIMTYPE_REFERENCE;
3637 kumpf   1.67                 gotType = true;
3638 kumpf   1.28 	    }
3639 kumpf   1.27             // If type==reference but no VALUE.REFERENCE found, use null value
3640 kumpf   1.26         }
3641              
3642                      // Parse non-reference value
3643 kumpf   1.61         if ( type != CIMTYPE_REFERENCE )
3644 kumpf   1.26         {
3645 kumpf   1.67             CIMType effectiveType;
3646                          if (!gotType)
3647 kumpf   1.26 	    {
3648 kumpf   1.67 	        // If we don't know what type the value is, read it as a String
3649 kumpf   1.61 		effectiveType = CIMTYPE_STRING;
3650 kumpf   1.26 	    }
3651 kumpf   1.67             else
3652              	    {
3653              		effectiveType = type;
3654              	    }
3655 kumpf   1.26 
3656                          if ( !XmlReader::getValueArrayElement(parser, effectiveType, value) &&
3657              	         !XmlReader::getValueElement(parser, effectiveType, value) )
3658              	    {
3659              	        value.clear();    // Isn't necessary; should already be cleared
3660              	    }
3661                      }
3662              
3663                      expectEndTag(parser, "PARAMVALUE");
3664                  }
3665              
3666 kumpf   1.67     paramValue = CIMParamValue(name, value, gotType);
3667 kumpf   1.27 
3668                  return true;
3669              }
3670              
3671              //------------------------------------------------------------------------------
3672              //
3673              // getReturnValueElement()
3674              //
3675              // <!ELEMENT RETURNVALUE (VALUE|VALUE.REFERENCE)>
3676              // <!ATTLIST RETURNVALUE
3677              //      %ParamType;>
3678              //
3679              //------------------------------------------------------------------------------
3680              
3681              Boolean XmlReader::getReturnValueElement(
3682                  XmlParser& parser, 
3683                  CIMValue& returnValue)
3684              {
3685                  XmlEntry entry;
3686                  CIMType type;
3687                  CIMValue value;
3688 kumpf   1.27 
3689                  if (!testStartTag(parser, entry, "RETURNVALUE"))
3690              	return false;
3691              
3692                  // Get RETURNVALUE.PARAMTYPE attribute:
3693                  // NOTE: Array type return values are not allowed (2/20/02)
3694              
3695 kumpf   1.67     Boolean gotType = getCimTypeAttribute(parser.getLine(), entry, type,
3696                                                        "RETURNVALUE", "PARAMTYPE", false);
3697 kumpf   1.27 
3698                  // Parse VALUE.REFERENCE type
3699 kumpf   1.67     if ( (type == CIMTYPE_REFERENCE) || !gotType )
3700 kumpf   1.27     {
3701 kumpf   1.54         CIMObjectPath reference;
3702 kumpf   1.27         if (XmlReader::getValueReferenceElement(parser, reference))
3703                      {
3704                          returnValue.set(reference);
3705 kumpf   1.61             type = CIMTYPE_REFERENCE;
3706 kumpf   1.67             gotType = true;
3707 kumpf   1.27         }
3708 kumpf   1.61         else if (type == CIMTYPE_REFERENCE)
3709 kumpf   1.27         {
3710                          throw XmlValidationError(parser.getLine(),
3711                              "expected VALUE.REFERENCE element");
3712                      }
3713                  }
3714              
3715                  // Parse non-reference return value
3716 kumpf   1.61     if ( type != CIMTYPE_REFERENCE )
3717 kumpf   1.27     {
3718 kumpf   1.67         if (!gotType)
3719 kumpf   1.27         {
3720 kumpf   1.67             // If we don't know what type the value is, read it as a String
3721 kumpf   1.61             type = CIMTYPE_STRING;
3722 kumpf   1.27         }
3723              
3724                      if ( !XmlReader::getValueElement(parser, type, returnValue) )
3725                      {
3726                          throw XmlValidationError(parser.getLine(),
3727                              "expected VALUE element");
3728                      }
3729                  }
3730              
3731                  expectEndTag(parser, "RETURNVALUE");
3732 mike    1.25 
3733                  return true;
3734 mike    1.23 }
3735              
3736              PEGASUS_NAMESPACE_END

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2