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

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2