(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              
1447                  if (!parser.next(entry))
1448              	return false;
1449              
1450                  Boolean isEmptyTag = entry.type == XmlEntry::EMPTY_TAG;
1451              
1452                  if ((!isEmptyTag && 
1453              	entry.type != XmlEntry::START_TAG) ||
1454              	strcmp(entry.text, "SCOPE") != 0)
1455                  {
1456              	parser.putBack(entry);
1457              	return 0;
1458                  }
1459              
1460                  Uint32 line = parser.getLine();
1461 kumpf   1.63     CIMScope scope = CIMScope ();
1462 mike    1.23 
1463                  if (getCimBooleanAttribute(line, entry, "SCOPE", "CLASS", false, false))
1464 kumpf   1.63 	scope.addScope (CIMScope::CLASS);
1465 mike    1.23 
1466                  if (getCimBooleanAttribute(
1467              	line, entry, "SCOPE", "ASSOCIATION", false, false))
1468 kumpf   1.63 	scope.addScope (CIMScope::ASSOCIATION);
1469 mike    1.23 
1470                  if (getCimBooleanAttribute(
1471              	line, entry, "SCOPE", "REFERENCE", false, false))
1472 kumpf   1.63 	scope.addScope (CIMScope::REFERENCE);
1473 mike    1.23 
1474                  if (getCimBooleanAttribute(line, entry, "SCOPE", "PROPERTY", false, false))
1475 kumpf   1.63 	scope.addScope (CIMScope::PROPERTY);
1476 mike    1.23 
1477                  if (getCimBooleanAttribute(line, entry, "SCOPE", "METHOD", false, false))
1478 kumpf   1.63 	scope.addScope (CIMScope::METHOD);
1479 mike    1.23 
1480                  if (getCimBooleanAttribute(line, entry, "SCOPE", "PARAMETER", false, false))
1481 kumpf   1.63 	scope.addScope (CIMScope::PARAMETER);
1482 mike    1.23 
1483                  if (getCimBooleanAttribute(line, entry, "SCOPE", "INDICATION",false, false))
1484 kumpf   1.63 	scope.addScope (CIMScope::INDICATION);
1485 mike    1.23 
1486                  if (!isEmptyTag)
1487              	expectEndTag(parser, "SCOPE");
1488              
1489                  return scope;
1490              }
1491              
1492              //------------------------------------------------------------------------------
1493              //
1494              // getQualifierElement()
1495              //
1496 kumpf   1.52 //     <!ELEMENT QUALIFIER (VALUE|VALUE.ARRAY)?>
1497 mike    1.23 //     <!ATTLIST QUALIFIER
1498              //         %CIMName;
1499              //         %CIMType; #REQUIRED
1500              //         %Propagated;
1501              //         %QualifierFlavor;>
1502              //
1503              //------------------------------------------------------------------------------
1504              
1505              Boolean XmlReader::getQualifierElement(
1506                  XmlParser& parser, 
1507                  CIMQualifier& qualifier)
1508              {
1509                  // Get QUALIFIER element:
1510              
1511                  XmlEntry entry;
1512                  if (!testStartTag(parser, entry, "QUALIFIER"))
1513              	return false;
1514              
1515                  // Get QUALIFIER.NAME attribute:
1516              
1517                  String name = getCimNameAttribute(parser.getLine(), entry, "QUALIFIER");
1518 mike    1.23 
1519                  // Get QUALIFIER.TYPE attribute:
1520              
1521                  CIMType type = getCimTypeAttribute(parser.getLine(), entry, "QUALIFIER");
1522              
1523                  // Get QUALIFIER.PROPAGATED
1524              
1525                  Boolean propagated = getCimBooleanAttribute(
1526              	parser.getLine(), entry, "QUALIFIER", "PROPAGATED", false, false);
1527              
1528                  // Get flavor oriented attributes:
1529              
1530 kumpf   1.64     CIMFlavor flavor = getFlavor(entry, parser.getLine(), "QUALIFIER");
1531 mike    1.23 
1532                  // Get VALUE or VALUE.ARRAY element:
1533              
1534                  CIMValue value;
1535              
1536                  if (!getValueElement(parser, type, value) &&
1537              	!getValueArrayElement(parser, type, value))
1538                  {
1539 kumpf   1.52         value.setNullValue(type, false);
1540 mike    1.23     }
1541              
1542                  // Expect </QUALIFIER>:
1543              
1544                  expectEndTag(parser, "QUALIFIER");
1545              
1546                  // Build qualifier:
1547              
1548                  qualifier = CIMQualifier(name, value, flavor, propagated);
1549                  return true;
1550              }
1551              
1552              //------------------------------------------------------------------------------
1553              //
1554              // getQualifierElements()
1555              //
1556              //------------------------------------------------------------------------------
1557              
1558              template<class CONTAINER>
1559              void getQualifierElements(XmlParser& parser, CONTAINER& container)
1560              {
1561 mike    1.23     CIMQualifier qualifier;
1562              
1563                  while (XmlReader::getQualifierElement(parser, qualifier))
1564                  {
1565              	try
1566              	{
1567              	    container.addQualifier(qualifier);
1568              	}
1569              	catch (AlreadyExists&)
1570              	{
1571              	    throw XmlSemanticError(parser.getLine(), "duplicate qualifier");
1572              	}
1573                  }
1574              }
1575              
1576              //------------------------------------------------------------------------------
1577              //
1578              // getPropertyElement()
1579              //
1580              //     <!ELEMENT PROPERTY (QUALIFIER*,VALUE?)>
1581              //     <!ATTLIST PROPERTY
1582 mike    1.23 //         %CIMName;
1583              //         %ClassOrigin;
1584              //         %Propagated;
1585              //         %CIMType; #REQUIRED>
1586              //
1587              //------------------------------------------------------------------------------
1588              
1589              Boolean XmlReader::getPropertyElement(XmlParser& parser, CIMProperty& property)
1590              {
1591                  XmlEntry entry;
1592              
1593                  if (!testStartTagOrEmptyTag(parser, entry, "PROPERTY"))
1594              	return false;
1595              
1596                  Boolean empty = entry.type == XmlEntry::EMPTY_TAG;
1597              
1598                  // Get PROPERTY.NAME attribute:
1599              
1600                  String name = getCimNameAttribute(parser.getLine(), entry, "PROPERTY");
1601              
1602                  // Get PROPERTY.CLASSORIGIN attribute:
1603 mike    1.23 
1604 kumpf   1.62     CIMName classOrigin = 
1605 mike    1.23 	getClassOriginAttribute(parser.getLine(), entry, "PROPERTY");
1606              
1607                  // Get PROPERTY.PROPAGATED
1608              
1609                  Boolean propagated = getCimBooleanAttribute(
1610              	parser.getLine(), entry, "PROPERTY", "PROPAGATED", false, false);
1611              
1612                  // Get PROPERTY.TYPE attribute:
1613              
1614                  CIMType type = getCimTypeAttribute(parser.getLine(), entry, "PROPERTY");
1615              
1616 karl    1.35     // Create property: Sets type and !isarray
1617 mike    1.23 
1618 kumpf   1.56     CIMValue value(type, false);
1619 kumpf   1.62     property = CIMProperty(name, value, 0, CIMName(), classOrigin, propagated);
1620 mike    1.23 
1621                  if (!empty)
1622                  {
1623              	// Get qualifiers:
1624              
1625              	getQualifierElements(parser, property);
1626              
1627 karl    1.35 	// Get value:  Insert value if getValueElement exists (returns True)
1628 mike    1.23 
1629              	if (getValueElement(parser, type, value))
1630              	    property.setValue(value);
1631              
1632              	expectEndTag(parser, "PROPERTY");
1633                  }
1634              
1635                  return true;
1636              }
1637              
1638              //------------------------------------------------------------------------------
1639              //
1640              // getArraySizeAttribute()
1641              //
1642              //     Returns true if able to get array-size. Note that array size will
1643              //     always be a positive integer.
1644              //
1645              //     <!ENTITY % ArraySize "ARRAYSIZE CDATA #IMPLIED">
1646              //
1647              //------------------------------------------------------------------------------
1648              
1649 mike    1.23 Boolean XmlReader::getArraySizeAttribute(
1650                  Uint32 lineNumber,
1651                  const XmlEntry& entry,
1652                  const char* tagName,
1653                  Uint32& value)
1654              {
1655                  const char* tmp;
1656              
1657                  if (!entry.getAttributeValue("ARRAYSIZE", tmp))
1658              	return false;
1659              
1660                  Uint64 arraySize;
1661              
1662                  if (!stringToUnsignedInteger(tmp, arraySize) || arraySize == 0)
1663                  {
1664              	char message[128];
1665              	sprintf(message, "Illegal value for %s.%s", tagName, "ARRAYSIZE");
1666              	throw XmlSemanticError(lineNumber, message);
1667                  }
1668              
1669                  value = Uint32(arraySize);
1670 mike    1.23     return true;
1671              }
1672              
1673              //------------------------------------------------------------------------------
1674              //
1675              // getPropertyArrayElement()
1676              //
1677              //     <!ELEMENT PROPERTY.ARRAY (QUALIFIER*,VALUE.ARRAY?)>
1678              //     <!ATTLIST PROPERTY.ARRAY
1679              //             %CIMName;
1680              //             %CIMType; #REQUIRED
1681              //             %ArraySize;
1682              //             %ClassOrigin;
1683              //             %Propagated;>
1684              //
1685              //------------------------------------------------------------------------------
1686              
1687              Boolean XmlReader::getPropertyArrayElement(
1688                  XmlParser& parser, 
1689                  CIMProperty& property)
1690              {
1691 mike    1.23     // Get PROPERTY element:
1692              
1693                  XmlEntry entry;
1694              
1695                  if (!testStartTagOrEmptyTag(parser, entry, "PROPERTY.ARRAY"))
1696              	return false;
1697              
1698                  Boolean empty = entry.type == XmlEntry::EMPTY_TAG;
1699              
1700                  // Get PROPERTY.NAME attribute:
1701              
1702                  String name = 
1703              	getCimNameAttribute(parser.getLine(), entry, "PROPERTY.ARRAY");
1704              
1705                  // Get PROPERTY.TYPE attribute:
1706              
1707                  CIMType type = getCimTypeAttribute(parser.getLine(), entry, "PROPERTY.ARRAY");
1708              
1709                  // Get PROPERTY.ARRAYSIZE attribute:
1710              
1711                  Uint32 arraySize = 0;
1712 mike    1.23     getArraySizeAttribute(parser.getLine(), entry, "PROPERTY.ARRAY", arraySize);
1713              
1714                  // Get PROPERTY.CLASSORIGIN attribute:
1715              
1716 kumpf   1.62     CIMName classOrigin 
1717 mike    1.23 	= getClassOriginAttribute(parser.getLine(), entry, "PROPERTY.ARRAY");
1718              
1719                  // Get PROPERTY.ARRAY.PROPAGATED
1720              
1721                  Boolean propagated = getCimBooleanAttribute(
1722              	parser.getLine(), entry, "PROPERTY.ARRAY", "PROPAGATED", false, false);
1723              
1724                  // Create property:
1725              
1726 kumpf   1.56     CIMValue value(type, true, arraySize);
1727 mike    1.23     property = CIMProperty(
1728 kumpf   1.62 	name, value, arraySize, CIMName(), classOrigin, propagated);
1729 mike    1.23 
1730                  if (!empty)
1731                  {
1732              	// Get qualifiers:
1733              
1734              	getQualifierElements(parser, property);
1735              
1736              	// Get value:
1737              
1738              	if (getValueArrayElement(parser, type, value))
1739              	{
1740              	    if (arraySize && arraySize != value.getArraySize())
1741              	    {
1742              		throw XmlSemanticError(parser.getLine(),
1743              		    "ARRAYSIZE attribute and value-array size are different");
1744              	    }
1745              
1746              	    property.setValue(value);
1747              	}
1748              
1749              	expectEndTag(parser, "PROPERTY.ARRAY");
1750 mike    1.23     }
1751              
1752                  return true;
1753              }
1754              
1755              //------------------------------------------------------------------------------
1756              //
1757              // getHostElement()
1758              //
1759              //     <!ELEMENT HOST (#PCDATA)>
1760              //
1761              //------------------------------------------------------------------------------
1762              
1763              Boolean XmlReader::getHostElement(
1764                  XmlParser& parser,
1765                  String& host)
1766              {
1767                  XmlEntry entry;
1768              
1769                  if (!testStartTag(parser, entry, "HOST"))
1770              	return false;
1771 mike    1.23 
1772                  if (!parser.next(entry) || entry.type != XmlEntry::CONTENT)
1773                  {
1774              	throw XmlValidationError(parser.getLine(),
1775              	    "expected content of HOST element");
1776                  }
1777              
1778                  host = entry.text;
1779              
1780                  expectEndTag(parser, "HOST");
1781                  return true;
1782              }
1783              
1784              //------------------------------------------------------------------------------
1785              //
1786              // getNameSpaceElement()
1787              //     
1788              //     <!ELEMENT NAMESPACE EMPTY>
1789              //     <!ATTLIST NAMESPACE %CIMName;>
1790              //
1791              //------------------------------------------------------------------------------
1792 mike    1.23 
1793              Boolean XmlReader::getNameSpaceElement(
1794                  XmlParser& parser,
1795                  String& nameSpaceComponent)
1796              {
1797                  XmlEntry entry;
1798              
1799                  if (!testStartTagOrEmptyTag(parser, entry, "NAMESPACE"))
1800              	return false;
1801              
1802                  Boolean empty = entry.type == XmlEntry::EMPTY_TAG;
1803              
1804                  nameSpaceComponent = getCimNameAttribute(
1805              	parser.getLine(), entry, "NAMESPACE");
1806              
1807                  if (!empty)
1808              	expectEndTag(parser, "NAMESPACE");
1809              
1810                  return true;
1811              }
1812              
1813 mike    1.23 //------------------------------------------------------------------------------
1814              //
1815              // getLocalNameSpacePathElement()
1816              //     
1817              //     <!ELEMENT LOCALNAMESPACEPATH (NAMESPACE+)>
1818              //
1819              //------------------------------------------------------------------------------
1820              
1821              Boolean XmlReader::getLocalNameSpacePathElement(
1822                  XmlParser& parser,
1823                  String& nameSpace)
1824              {
1825                  XmlEntry entry;
1826              
1827                  if (!testStartTag(parser, entry, "LOCALNAMESPACEPATH"))
1828              	return false;
1829              
1830                  String nameSpaceComponent;
1831              
1832                  while (getNameSpaceElement(parser, nameSpaceComponent))
1833                  {
1834 mike    1.23 	if (nameSpace.size())
1835              	    nameSpace += '/';
1836              
1837              	nameSpace += nameSpaceComponent;
1838                  }
1839              
1840                  if (!nameSpace.size())
1841                  {
1842              	throw XmlValidationError(parser.getLine(),
1843              	    "Expected one or more NAMESPACE elements within "
1844              	    "LOCALNAMESPACEPATH element");
1845                  }
1846              
1847                  expectEndTag(parser, "LOCALNAMESPACEPATH");
1848                  return true;
1849              }
1850              
1851              //------------------------------------------------------------------------------
1852              //
1853              // getNameSpacePathElement()
1854              //
1855 mike    1.23 //     <!ELEMENT NAMESPACEPATH (HOST,LOCALNAMESPACEPATH)>
1856              //
1857              //------------------------------------------------------------------------------
1858              
1859              Boolean XmlReader::getNameSpacePathElement(
1860                  XmlParser& parser,
1861                  String& host,
1862                  String& nameSpace)
1863              {
1864                  host.clear();
1865                  nameSpace.clear();
1866              
1867                  XmlEntry entry;
1868              
1869                  if (!testStartTag(parser, entry, "NAMESPACEPATH"))
1870              	return false;
1871              
1872                  if (!getHostElement(parser, host))
1873              	throw XmlValidationError(parser.getLine(), "expected HOST element");
1874              
1875                  if (!getLocalNameSpacePathElement(parser, nameSpace))
1876 mike    1.23     {
1877              	throw XmlValidationError(parser.getLine(), 
1878              	    "expected LOCALNAMESPACEPATH element");
1879                  }
1880              
1881                  expectEndTag(parser, "NAMESPACEPATH");
1882              
1883                  return true;
1884              }
1885              
1886              //------------------------------------------------------------------------------
1887              //
1888              // getClassNameElement()
1889              //
1890              //     <!ELEMENT CLASSNAME EMPTY>
1891              //     <!ATTLIST CLASSNAME %CIMName;>
1892              //
1893              //------------------------------------------------------------------------------
1894              
1895              Boolean XmlReader::getClassNameElement(
1896                  XmlParser& parser,
1897 mike    1.23     String& className,
1898                  Boolean required)
1899              {
1900                  XmlEntry entry;
1901              
1902                  if (!testStartTagOrEmptyTag(parser, entry, "CLASSNAME"))
1903                  {
1904              	if (required)
1905              	{
1906              	    throw XmlValidationError(parser.getLine(),
1907              		"expected CLASSNAME element");
1908              	}
1909              	else
1910              	    return false;
1911                  }
1912              
1913                  Boolean empty = entry.type == XmlEntry::EMPTY_TAG;
1914              
1915                  className = getCimNameAttribute(
1916              	parser.getLine(), entry, "CLASSNAME", true);
1917              
1918 mike    1.23     if (!empty)
1919              	expectEndTag(parser, "CLASSNAME");
1920              
1921                  return true;
1922              }
1923              
1924              //------------------------------------------------------------------------------
1925              //
1926              // getValueTypeAttribute()
1927              //
1928              //     VALUETYPE (string|boolean|numeric) 'string'
1929              //
1930              //------------------------------------------------------------------------------
1931              
1932              KeyBinding::Type XmlReader::getValueTypeAttribute(
1933                  Uint32 lineNumber, 
1934                  const XmlEntry& entry,
1935                  const char* elementName)
1936              {
1937                  String tmp;
1938              
1939 mike    1.23     if (!entry.getAttributeValue("VALUETYPE", tmp))
1940              	return KeyBinding::STRING;
1941              
1942                  if (String::equal(tmp, "string"))
1943              	return KeyBinding::STRING;
1944                  else if (String::equal(tmp, "boolean"))
1945              	return KeyBinding::BOOLEAN;
1946                  else if (String::equal(tmp, "numeric"))
1947              	return KeyBinding::NUMERIC;
1948              
1949                  char buffer[MESSAGE_SIZE];
1950              
1951                  sprintf(buffer, 
1952              	"Illegal value for %s.VALUETYPE attribute; "
1953              	"CIMValue must be one of \"string\", \"boolean\", or \"numeric\"",
1954              	elementName);
1955              
1956                  throw XmlSemanticError(lineNumber, buffer);
1957                  return KeyBinding::BOOLEAN;
1958              }
1959              
1960 mike    1.23 //------------------------------------------------------------------------------
1961              //
1962              // getKeyValueElement()
1963              //
1964              //     <!ELEMENT KEYVALUE (#PCDATA)>
1965              //     <!ATTLIST KEYVALUE
1966              //         VALUETYPE (string|boolean|numeric)  'string'>
1967              //
1968              //------------------------------------------------------------------------------
1969              
1970              Boolean XmlReader::getKeyValueElement(
1971                  XmlParser& parser,
1972                  KeyBinding::Type& type,
1973                  String& value)
1974              {
1975                  XmlEntry entry;
1976              
1977                  if (!testStartTagOrEmptyTag(parser, entry, "KEYVALUE"))
1978              	return false;
1979              
1980                  Boolean empty = entry.type == XmlEntry::EMPTY_TAG;
1981 mike    1.23 
1982                  type = getValueTypeAttribute(parser.getLine(), entry, "KEYVALUE");
1983              
1984                  value.clear();
1985              
1986                  if (!empty)
1987                  {
1988              	if (!parser.next(entry))
1989              	    throw XmlException(XmlException::UNCLOSED_TAGS, parser.getLine());
1990              
1991              	if (entry.type == XmlEntry::CONTENT)
1992              	    value = entry.text;
1993              	else
1994              	    parser.putBack(entry);
1995              
1996              	expectEndTag(parser, "KEYVALUE");
1997                  }
1998              
1999                  return true;
2000              }
2001              
2002 mike    1.23 //------------------------------------------------------------------------------
2003              //
2004              // getKeyBindingElement()
2005              //
2006              //     <!ELEMENT KEYBINDING (KEYVALUE|VALUE.REFERENCE)>
2007              //     <!ATTLIST KEYBINDING
2008              //         %CIMName;>
2009              //
2010              //------------------------------------------------------------------------------
2011              
2012              Boolean XmlReader::getKeyBindingElement(
2013                  XmlParser& parser,
2014                  String& name,
2015                  String& value,
2016                  KeyBinding::Type& type)
2017              {
2018                  XmlEntry entry;
2019              
2020                  if (!testStartTag(parser, entry, "KEYBINDING"))
2021              	return false;
2022              
2023 mike    1.23     name = getCimNameAttribute(parser.getLine(), entry, "KEYBINDING");
2024              
2025                  if (!getKeyValueElement(parser, type, value))
2026 mike    1.25     {
2027 kumpf   1.54         CIMObjectPath reference;
2028 mike    1.25 
2029                      if (!getValueReferenceElement(parser, reference))
2030                      {
2031              	    throw XmlValidationError(parser.getLine(),
2032                                    "Expected KEYVALUE or VALUE.REFERENCE element");
2033                      }
2034              
2035                      type = KeyBinding::REFERENCE;
2036                      value = reference.toString();
2037                  }
2038 mike    1.23 
2039                  expectEndTag(parser, "KEYBINDING");
2040                  return true;
2041              }
2042              
2043              //------------------------------------------------------------------------------
2044              //
2045              // getInstanceNameElement()
2046              //
2047              //     <!ELEMENT INSTANCENAME (KEYBINDING*|KEYVALUE?|VALUE.REFERENCE?)>
2048              //     <!ATTLIST INSTANCENAME
2049              //         %ClassName;>
2050              //
2051 mike    1.25 // Note: An empty key name is used in the keyBinding when the INSTANCENAME is
2052              // specified using a KEYVALUE or a VALUE.REFERENCE.
2053 mike    1.23 //
2054              //------------------------------------------------------------------------------
2055              
2056              Boolean XmlReader::getInstanceNameElement(
2057                  XmlParser& parser,
2058                  String& className,
2059                  Array<KeyBinding>& keyBindings)
2060              {
2061                  className.clear();
2062                  keyBindings.clear();
2063              
2064                  XmlEntry entry;
2065              
2066                  if (!testStartTagOrEmptyTag(parser, entry, "INSTANCENAME"))
2067              	return false;
2068              
2069                  Boolean empty = entry.type == XmlEntry::EMPTY_TAG;
2070              
2071                  className = getClassNameAttribute(parser.getLine(), entry, "INSTANCENAME");
2072              
2073 mike    1.25     if (empty)
2074 mike    1.23     {
2075 mike    1.25         return true;
2076                  }
2077 mike    1.23 
2078 mike    1.25     String name;
2079                  KeyBinding::Type type;
2080                  String value;
2081 kumpf   1.54     CIMObjectPath reference;
2082 mike    1.25 
2083                  if (getKeyValueElement(parser, type, value))
2084                  {
2085                      // Use empty key name because none was specified
2086                      keyBindings.append(KeyBinding(name, value, type));
2087                  }
2088                  else if (getValueReferenceElement(parser, reference))
2089                  {
2090                      // Use empty key name because none was specified
2091                      type = KeyBinding::REFERENCE;
2092                      value = reference.toString();
2093                      keyBindings.append(KeyBinding(name, value, type));
2094                  }
2095                  else
2096                  {
2097 mike    1.23 	while (getKeyBindingElement(parser, name, value, type))
2098              	    keyBindings.append(KeyBinding(name, value, type));
2099 mike    1.25     }
2100 mike    1.23 
2101 mike    1.25     expectEndTag(parser, "INSTANCENAME");
2102 mike    1.23 
2103                  return true;
2104              }
2105              
2106              Boolean XmlReader::getInstanceNameElement(
2107                  XmlParser& parser,
2108 kumpf   1.54     CIMObjectPath& instanceName)
2109 mike    1.23 {
2110                  String className;
2111                  Array<KeyBinding> keyBindings;
2112              
2113                  if (!XmlReader::getInstanceNameElement(parser, className, keyBindings))
2114              	return false;
2115              
2116 kumpf   1.62     instanceName.set(String(), CIMNamespaceName(), className, keyBindings);
2117 mike    1.23     return true;
2118              }
2119              
2120              //------------------------------------------------------------------------------
2121              //
2122              // getInstancePathElement()
2123              //
2124              //     <!ELEMENT INSTANCEPATH (NAMESPACEPATH,INSTANCENAME)>
2125              //
2126              //------------------------------------------------------------------------------
2127              
2128              Boolean XmlReader::getInstancePathElement(
2129                  XmlParser& parser,
2130 kumpf   1.54     CIMObjectPath& reference)
2131 mike    1.23 {
2132                  XmlEntry entry;
2133              
2134                  if (!testStartTag(parser, entry, "INSTANCEPATH"))
2135              	return false;
2136              
2137                  String host;
2138                  String nameSpace;
2139              
2140                  if (!getNameSpacePathElement(parser, host, nameSpace))
2141                  {
2142              	throw XmlValidationError(parser.getLine(),
2143              	    "expected NAMESPACEPATH element");
2144                  }
2145              
2146                  String className;
2147                  Array<KeyBinding> keyBindings;
2148              
2149                  if (!getInstanceNameElement(parser, className, keyBindings))
2150                  {
2151              	throw XmlValidationError(parser.getLine(), 
2152 mike    1.23 	    "expected INSTANCENAME element");
2153                  }
2154              
2155                  reference.set(host, nameSpace, className, keyBindings);
2156              
2157                  expectEndTag(parser, "INSTANCEPATH");
2158                  return true;
2159              }
2160              
2161              //------------------------------------------------------------------------------
2162              //
2163              // getLocalInstancePathElement()
2164              //
2165              //     <!ELEMENT LOCALINSTANCEPATH (NAMESPACEPATH,INSTANCENAME)>
2166              //
2167              //------------------------------------------------------------------------------
2168              
2169              Boolean XmlReader::getLocalInstancePathElement(
2170                  XmlParser& parser,
2171 kumpf   1.54     CIMObjectPath& reference)
2172 mike    1.23 {
2173                  XmlEntry entry;
2174              
2175                  if (!testStartTag(parser, entry, "LOCALINSTANCEPATH"))
2176              	return false;
2177              
2178                  String nameSpace;
2179              
2180                  if (!getLocalNameSpacePathElement(parser, nameSpace))
2181                  {
2182              	throw XmlValidationError(parser.getLine(),
2183              	    "expected LOCALNAMESPACEPATH element");
2184                  }
2185              
2186                  String className;
2187                  Array<KeyBinding> keyBindings;
2188              
2189                  if (!getInstanceNameElement(parser, className, keyBindings))
2190                  {
2191              	throw XmlValidationError(parser.getLine(), 
2192              	    "expected INSTANCENAME element");
2193 mike    1.23     }
2194              
2195                  reference.set(String(), nameSpace, className, keyBindings);
2196              
2197                  expectEndTag(parser, "LOCALINSTANCEPATH");
2198                  return true;
2199              }
2200              
2201              //------------------------------------------------------------------------------
2202              //
2203              // getClassPathElement()
2204              //
2205              //     <!ELEMENT CLASSPATH (NAMESPACEPATH,CLASSNAME)>
2206              //
2207              //------------------------------------------------------------------------------
2208              
2209              Boolean XmlReader::getClassPathElement(
2210                  XmlParser& parser,
2211 kumpf   1.54     CIMObjectPath& reference)
2212 mike    1.23 {
2213                  XmlEntry entry;
2214              
2215                  if (!testStartTag(parser, entry, "CLASSPATH"))
2216              	return false;
2217              
2218                  String host;
2219                  String nameSpace;
2220              
2221                  if (!getNameSpacePathElement(parser, host, nameSpace))
2222                  {
2223              	throw XmlValidationError(parser.getLine(),
2224              	    "expected NAMESPACEPATH element");
2225                  }
2226              
2227                  String className;
2228              
2229                  if (!getClassNameElement(parser, className))
2230                  {
2231              	throw XmlValidationError(parser.getLine(), 
2232              	    "expected CLASSNAME element");
2233 mike    1.23     }
2234              
2235                  reference.set(host, nameSpace, className);
2236              
2237                  expectEndTag(parser, "CLASSPATH");
2238                  return true;
2239              }
2240              
2241              //------------------------------------------------------------------------------
2242              //
2243              // getLocalClassPathElement()
2244              //
2245              //     <!ELEMENT LOCALCLASSPATH (LOCALNAMESPACEPATH,CLASSNAME)>
2246              //
2247              //------------------------------------------------------------------------------
2248              
2249              Boolean XmlReader::getLocalClassPathElement(
2250                  XmlParser& parser,
2251 kumpf   1.54     CIMObjectPath& reference)
2252 mike    1.23 {
2253                  XmlEntry entry;
2254              
2255                  if (!testStartTag(parser, entry, "LOCALCLASSPATH"))
2256              	return false;
2257              
2258                  String nameSpace;
2259              
2260                  if (!getLocalNameSpacePathElement(parser, nameSpace))
2261                  {
2262              	throw XmlValidationError(parser.getLine(),
2263              	    "expected LOCALNAMESPACEPATH element");
2264                  }
2265              
2266                  String className;
2267              
2268                  if (!getClassNameElement(parser, className))
2269                  {
2270              	throw XmlValidationError(parser.getLine(), 
2271              	    "expected CLASSNAME element");
2272                  }
2273 mike    1.23 
2274                  reference.set(String(), nameSpace, className);
2275              
2276                  expectEndTag(parser, "LOCALCLASSPATH");
2277              
2278                  return true;
2279              }
2280              
2281              //------------------------------------------------------------------------------
2282              //
2283              // getValueReferenceElement()
2284              //
2285              //     <!ELEMENT VALUE.REFERENCE (CLASSPATH|LOCALCLASSPATH|CLASSNAME|
2286              //         INSTANCEPATH|LOCALINSTANCEPATH|INSTANCENAME)>
2287              //
2288              //
2289              //------------------------------------------------------------------------------
2290              
2291              Boolean XmlReader::getValueReferenceElement(
2292                  XmlParser& parser,
2293 kumpf   1.54     CIMObjectPath& reference)
2294 mike    1.23 {
2295                  XmlEntry entry;
2296              
2297                  if (!testStartTag(parser, entry, "VALUE.REFERENCE"))
2298              	return false;
2299              
2300                  if (!parser.next(entry))
2301              	throw XmlException(XmlException::UNCLOSED_TAGS, parser.getLine());
2302              
2303                  if (entry.type != XmlEntry::START_TAG && 
2304              	entry.type != XmlEntry::EMPTY_TAG)
2305                  {
2306              	throw XmlValidationError(parser.getLine(), 
2307              	    "Expected one of the following start tags: "
2308              	    "CLASSPATH, LOCALCLASSPATH, CLASSNAME, INSTANCEPATH, "
2309              	    "LOCALINSTANCEPATH, INSTANCENAME");
2310                  }
2311              
2312                  if (strcmp(entry.text, "CLASSPATH") == 0)
2313                  {
2314              	parser.putBack(entry);
2315 mike    1.23 	getClassPathElement(parser, reference);
2316                  }
2317                  else if (strcmp(entry.text, "LOCALCLASSPATH") == 0)
2318                  {
2319              	parser.putBack(entry);
2320              	getLocalClassPathElement(parser, reference);
2321                  }
2322                  else if (strcmp(entry.text, "CLASSNAME") == 0)
2323                  {
2324              	parser.putBack(entry);
2325              	String className;
2326              	getClassNameElement(parser, className);
2327 kumpf   1.62 	reference.set(String(), CIMNamespaceName(), className);
2328 mike    1.23     }
2329                  else if (strcmp(entry.text, "INSTANCEPATH") == 0)
2330                  {
2331              	parser.putBack(entry);
2332              	getInstancePathElement(parser, reference);
2333                  }
2334                  else if (strcmp(entry.text, "LOCALINSTANCEPATH") == 0)
2335                  {
2336              	parser.putBack(entry);
2337              	getLocalInstancePathElement(parser, reference);
2338                  }
2339                  else if (strcmp(entry.text, "INSTANCENAME") == 0)
2340                  {
2341              	parser.putBack(entry);
2342              	String className;
2343              	Array<KeyBinding> keyBindings;
2344              	getInstanceNameElement(parser, className, keyBindings);
2345 kumpf   1.62 	reference.set(String(), CIMNamespaceName(), className, keyBindings);
2346 mike    1.23     }
2347              
2348                  expectEndTag(parser, "VALUE.REFERENCE");
2349                  return true;
2350              }
2351              
2352              //------------------------------------------------------------------------------
2353              //
2354 kumpf   1.28 // getValueReferenceArrayElement()
2355              //
2356              //     <!ELEMENT VALUE.REFARRAY (VALUE.REFERENCE*)>
2357              //
2358              //------------------------------------------------------------------------------
2359              
2360              Boolean XmlReader::getValueReferenceArrayElement(
2361                  XmlParser& parser, 
2362                  CIMValue& value)
2363              {
2364                  XmlEntry entry;
2365 kumpf   1.54     Array<CIMObjectPath> referenceArray;
2366                  CIMObjectPath reference;
2367 kumpf   1.28 
2368                  value.clear();
2369              
2370                  // Get VALUE.REFARRAY open tag:
2371              
2372                  if (!testStartTagOrEmptyTag(parser, entry, "VALUE.REFARRAY"))
2373              	return false;
2374              
2375 kumpf   1.32     if (entry.type != XmlEntry::EMPTY_TAG)
2376                  {
2377                      // For each VALUE.REFERENCE element:
2378 kumpf   1.28 
2379 kumpf   1.32         while (getValueReferenceElement(parser, reference))
2380                      {
2381              	    referenceArray.append(reference);
2382                      }
2383 kumpf   1.28 
2384 kumpf   1.32         expectEndTag(parser, "VALUE.REFARRAY");
2385 kumpf   1.28     }
2386              
2387                  value.set(referenceArray);
2388                  return true;
2389              }
2390              
2391              //------------------------------------------------------------------------------
2392              //
2393 mike    1.23 // getPropertyReferenceElement()
2394              //
2395              //     <!ELEMENT PROPERTY.REFERENCE (QUALIFIER*,(VALUE.REFERENCE)?)>
2396              //     <!ATTLIST PROPERTY.REFERENCE
2397              //         %CIMName;
2398              //         %ReferenceClass;
2399              //         %ClassOrigin;
2400              //         %Propagated;>
2401              //
2402              //------------------------------------------------------------------------------
2403              
2404              Boolean XmlReader::getPropertyReferenceElement(
2405                  XmlParser& parser, 
2406                  CIMProperty& property)
2407              {
2408                  XmlEntry entry;
2409              
2410                  if (!testStartTagOrEmptyTag(parser, entry, "PROPERTY.REFERENCE"))
2411              	return false;
2412              
2413                  Boolean empty = entry.type == XmlEntry::EMPTY_TAG;
2414 mike    1.23 
2415                  // Get PROPERTY.NAME attribute:
2416              
2417                  String name = getCimNameAttribute(
2418              	parser.getLine(), entry, "PROPERTY.REFERENCE");
2419              
2420                  // Get PROPERTY.REFERENCECLASS attribute:
2421              
2422 kumpf   1.62     CIMName referenceClass = getReferenceClassAttribute(
2423 mike    1.23 	parser.getLine(), entry, "PROPERTY.REFERENCE");
2424              
2425                  // Get PROPERTY.CLASSORIGIN attribute:
2426              
2427 kumpf   1.62     CIMName classOrigin = 
2428 mike    1.23 	getClassOriginAttribute(parser.getLine(), entry, "PROPERTY.REFERENCE");
2429              
2430                  // Get PROPERTY.PROPAGATED
2431              
2432                  Boolean propagated = getCimBooleanAttribute(parser.getLine(), entry, 
2433              	"PROPERTY.REFERENCE", "PROPAGATED", false, false);
2434              
2435                  // Create property:
2436              
2437 kumpf   1.61     CIMValue value = CIMValue(CIMTYPE_REFERENCE, false, 0);
2438 kumpf   1.54 //    value.set(CIMObjectPath());
2439 mike    1.23     property = CIMProperty(
2440              	name, value, 0, referenceClass, classOrigin, propagated);
2441              
2442                  if (!empty)
2443                  {
2444              	getQualifierElements(parser, property);
2445              
2446 kumpf   1.54 	CIMObjectPath reference;
2447 mike    1.23 
2448              	if (getValueReferenceElement(parser, reference))
2449              	    property.setValue(reference);
2450              
2451              	expectEndTag(parser, "PROPERTY.REFERENCE");
2452                  }
2453              
2454                  return true;
2455              }
2456              
2457              //------------------------------------------------------------------------------
2458              //
2459              // GetPropertyElements()
2460              //
2461              //------------------------------------------------------------------------------
2462              
2463              template<class CONTAINER>
2464              void GetPropertyElements(XmlParser& parser, CONTAINER& container)
2465              {
2466                  CIMProperty property;
2467              
2468 mike    1.23     while (XmlReader::getPropertyElement(parser, property) ||
2469              	XmlReader::getPropertyArrayElement(parser, property) ||
2470              	XmlReader::getPropertyReferenceElement(parser, property))
2471                  {
2472              	try
2473              	{
2474              	    container.addProperty(property);
2475              	}
2476              	catch (AlreadyExists&)
2477              	{
2478              	    throw XmlSemanticError(parser.getLine(), "duplicate property");
2479              	}
2480                  }
2481              }
2482              
2483              //------------------------------------------------------------------------------
2484              //
2485              // getParameterElement()
2486              //
2487              //     <!ELEMENT PARAMETER (QUALIFIER*)>
2488              //     <!ATTLIST PARAMETER
2489 mike    1.23 //         %CIMName;
2490              //         %CIMType; #REQUIRED>
2491              //
2492              //------------------------------------------------------------------------------
2493              
2494              Boolean XmlReader::getParameterElement(
2495                  XmlParser& parser, 
2496                  CIMParameter& parameter)
2497              {
2498                  XmlEntry entry;
2499              
2500                  if (!testStartTagOrEmptyTag(parser, entry, "PARAMETER"))
2501              	return false;
2502              
2503                  Boolean empty = entry.type == XmlEntry::EMPTY_TAG;
2504              
2505                  // Get PARAMETER.NAME attribute:
2506              
2507                  String name = getCimNameAttribute(parser.getLine(), entry, "PARAMETER");
2508              
2509                  // Get PARAMETER.TYPE attribute:
2510 mike    1.23 
2511                  CIMType type = getCimTypeAttribute(parser.getLine(), entry, "PARAMETER");
2512              
2513                  // Create parameter:
2514              
2515                  parameter = CIMParameter(name, type);
2516              
2517                  if (!empty)
2518                  {
2519              	getQualifierElements(parser, parameter);
2520              
2521              	expectEndTag(parser, "PARAMETER");
2522                  }
2523              
2524                  return true;
2525              }
2526              
2527              //------------------------------------------------------------------------------
2528              //
2529              // getParameterArrayElement()
2530              //
2531 mike    1.23 //     <!ELEMENT PARAMETER.ARRAY (QUALIFIER*)>
2532              //     <!ATTLIST PARAMETER.ARRAY
2533              //         %CIMName;
2534              //         %CIMType; #REQUIRED
2535              //         %ArraySize;>
2536              //
2537              //------------------------------------------------------------------------------
2538              
2539              Boolean XmlReader::getParameterArrayElement(
2540                  XmlParser& parser, 
2541                  CIMParameter& parameter)
2542              {
2543                  XmlEntry entry;
2544              
2545                  if (!testStartTagOrEmptyTag(parser, entry, "PARAMETER.ARRAY"))
2546              	return false;
2547              
2548                  Boolean empty = entry.type == XmlEntry::EMPTY_TAG;
2549              
2550                  // Get PARAMETER.ARRAY.NAME attribute:
2551              
2552 mike    1.23     String name = getCimNameAttribute(
2553              	parser.getLine(), entry, "PARAMETER.ARRAY");
2554              
2555                  // Get PARAMETER.ARRAY.TYPE attribute:
2556              
2557                  CIMType type = getCimTypeAttribute(parser.getLine(), entry, "PARAMETER.ARRAY");
2558              
2559                  // Get PARAMETER.ARRAYSIZE attribute:
2560              
2561                  Uint32 arraySize = 0;
2562                  getArraySizeAttribute(parser.getLine(), entry, "PARAMETER.ARRAY",arraySize);
2563              
2564                  // Create parameter:
2565              
2566                  parameter = CIMParameter(name, type, true, arraySize);
2567              
2568                  if (!empty)
2569                  {
2570              	getQualifierElements(parser, parameter);
2571              
2572              	expectEndTag(parser, "PARAMETER.ARRAY");
2573 mike    1.23     }
2574              
2575                  return true;
2576              }
2577              
2578              //------------------------------------------------------------------------------
2579              //
2580              // getParameterReferenceElement()
2581              //
2582              //     <!ELEMENT PARAMETER.REFERENCE (QUALIFIER*)>
2583              //     <!ATTLIST PARAMETER.REFERENCE
2584              //         %CIMName;
2585              //         %ReferenceClass;>
2586              //
2587              //------------------------------------------------------------------------------
2588              
2589              Boolean XmlReader::getParameterReferenceElement(
2590                  XmlParser& parser, 
2591                  CIMParameter& parameter)
2592              {
2593                  XmlEntry entry;
2594 mike    1.23 
2595                  if (!testStartTagOrEmptyTag(parser, entry, "PARAMETER.REFERENCE"))
2596              	return false;
2597              
2598                  Boolean empty = entry.type == XmlEntry::EMPTY_TAG;
2599              
2600                  // Get PARAMETER.NAME attribute:
2601              
2602                  String name = getCimNameAttribute(
2603              	parser.getLine(), entry, "PARAMETER.REFERENCE");
2604              
2605                  // Get PARAMETER.REFERENCECLASS attribute:
2606              
2607 kumpf   1.62     CIMName referenceClass = getReferenceClassAttribute(
2608 mike    1.23 	parser.getLine(), entry, "PARAMETER.REFERENCE");
2609              
2610                  // Create parameter:
2611              
2612 kumpf   1.61     parameter = CIMParameter(name, CIMTYPE_REFERENCE, false, 0, referenceClass);
2613 mike    1.23 
2614                  if (!empty)
2615                  {
2616              	getQualifierElements(parser, parameter);
2617              	expectEndTag(parser, "PARAMETER.REFERENCE");
2618                  }
2619              
2620                  return true;
2621              }
2622              
2623              //------------------------------------------------------------------------------
2624              //
2625 kumpf   1.26 // getParameterReferenceArrayElement()
2626              //
2627              //     <!ELEMENT PARAMETER.REFARRAY (QUALIFIER*)>
2628              //     <!ATTLIST PARAMETER.REFARRAY
2629              //         %CIMName;
2630              //         %ReferenceClass;
2631              //         %ArraySize;>
2632              //
2633              //------------------------------------------------------------------------------
2634              
2635              Boolean XmlReader::getParameterReferenceArrayElement(
2636                  XmlParser& parser, 
2637                  CIMParameter& parameter)
2638              {
2639                  XmlEntry entry;
2640              
2641                  if (!testStartTagOrEmptyTag(parser, entry, "PARAMETER.REFARRAY"))
2642              	return false;
2643              
2644                  Boolean empty = entry.type == XmlEntry::EMPTY_TAG;
2645              
2646 kumpf   1.26     // Get PARAMETER.NAME attribute:
2647              
2648                  String name = getCimNameAttribute(
2649              	parser.getLine(), entry, "PARAMETER.REFARRAY");
2650              
2651                  // Get PARAMETER.REFERENCECLASS attribute:
2652              
2653 kumpf   1.62     CIMName referenceClass = getReferenceClassAttribute(
2654 kumpf   1.26 	parser.getLine(), entry, "PARAMETER.REFARRAY");
2655              
2656                  // Get PARAMETER.ARRAYSIZE attribute:
2657              
2658                  Uint32 arraySize = 0;
2659                  getArraySizeAttribute(parser.getLine(), entry, "PARAMETER.REFARRAY",
2660              			  arraySize);
2661              
2662                  // Create parameter:
2663              
2664 kumpf   1.61     parameter = CIMParameter(name, CIMTYPE_REFERENCE, true, arraySize,
2665 kumpf   1.26 			     referenceClass);
2666              
2667                  if (!empty)
2668                  {
2669              	getQualifierElements(parser, parameter);
2670              	expectEndTag(parser, "PARAMETER.REFARRAY");
2671                  }
2672              
2673                  return true;
2674              }
2675              
2676              //------------------------------------------------------------------------------
2677              //
2678 mike    1.23 // GetParameterElements()
2679              //
2680              //------------------------------------------------------------------------------
2681              
2682              template<class CONTAINER>
2683              void GetParameterElements(XmlParser& parser, CONTAINER& container)
2684              {
2685                  CIMParameter parameter;
2686              
2687                  while (XmlReader::getParameterElement(parser, parameter) ||
2688              	XmlReader::getParameterArrayElement(parser, parameter) ||
2689 kumpf   1.26 	XmlReader::getParameterReferenceElement(parser, parameter) ||
2690              	XmlReader::getParameterReferenceArrayElement(parser, parameter))
2691 mike    1.23     {
2692              	try
2693              	{
2694              	    container.addParameter(parameter);
2695              	}
2696              	catch (AlreadyExists&)
2697              	{
2698              	    throw XmlSemanticError(parser.getLine(), "duplicate parameter");
2699              	}
2700                  }
2701              }
2702              
2703              //------------------------------------------------------------------------------
2704              //
2705              // getQualifierDeclElement()
2706              //
2707              //     <!ELEMENT QUALIFIER.DECLARATION (SCOPE?,(VALUE|VALUE.ARRAY)?)>
2708              //     <!ATTLIST QUALIFIER.DECLARATION 
2709              //         %CIMName;               
2710              //         %CIMType; #REQUIRED
2711              //         ISARRAY (true|false) #IMPLIED
2712 mike    1.23 //         %ArraySize;
2713              //         %QualifierFlavor;>
2714              //         
2715              //------------------------------------------------------------------------------
2716              
2717              Boolean XmlReader::getQualifierDeclElement(
2718                  XmlParser& parser, 
2719                  CIMQualifierDecl& qualifierDecl)
2720              {
2721                  XmlEntry entry;
2722              
2723                  if (!testStartTagOrEmptyTag(parser, entry, "QUALIFIER.DECLARATION"))
2724              	return false;
2725              
2726                  Boolean empty = entry.type == XmlEntry::EMPTY_TAG;
2727              
2728                  // Get NAME attribute:
2729              
2730                  String name = getCimNameAttribute(
2731              	parser.getLine(), entry, "QUALIFIER.DECLARATION");
2732              
2733 mike    1.23     // Get TYPE attribute:
2734              
2735                  CIMType type = getCimTypeAttribute(
2736              	parser.getLine(), entry, "QUALIFIER.DECLARATION");
2737              
2738                  // Get ISARRAY attribute:
2739              
2740 mike    1.25     Boolean isArray = getCimBooleanAttribute(
2741                      parser.getLine(), entry, "QUALIFIER.DECLARATION", "ISARRAY",
2742                      false, false); 
2743 mike    1.23 
2744                  // Get ARRAYSIZE attribute:
2745              
2746                  Uint32 arraySize = 0;
2747                  Boolean gotArraySize = getArraySizeAttribute(parser.getLine(),
2748              	entry, "QUALIFIER.DECLARATION", arraySize);
2749              
2750                  // Get flavor oriented attributes:
2751              
2752 kumpf   1.64     CIMFlavor flavor = getFlavor (entry, parser.getLine (), 
2753                      "QUALIFIER.DECLARATION");
2754 mike    1.23 
2755                  // No need to look for interior elements if empty tag:
2756              
2757 kumpf   1.63     CIMScope scope = CIMScope ();
2758 mike    1.23     CIMValue value;
2759              
2760                  if (!empty)
2761                  {
2762              	// Get the option SCOPE element:
2763              
2764              	scope = getOptionalScope(parser);
2765              
2766              	// Get VALUE or VALUE.ARRAY element:
2767              
2768              	if (getValueArrayElement(parser, type, value))
2769              	{
2770              	    if (!isArray)
2771              	    {
2772              		throw XmlSemanticError(parser.getLine(),
2773              		    "VALUE.ARRAY element encountered without "
2774              		    "ISARRAY attribute");
2775              	    }
2776              
2777              	    if (arraySize && arraySize != value.getArraySize())
2778              	    {
2779 mike    1.23 		throw XmlSemanticError(parser.getLine(),
2780              		    "VALUE.ARRAY size is not the same as "
2781              		    "ARRAYSIZE attribute");
2782              	    }
2783              	}
2784              	else if (getValueElement(parser, type, value))
2785              	{
2786              	    if (isArray)
2787              	    {
2788              		throw XmlSemanticError(parser.getLine(),
2789              		    "ISARRAY attribute used but VALUE element encountered");
2790              	    }
2791              	}
2792              
2793              	// Now get the closing tag:
2794              
2795              	expectEndTag(parser, "QUALIFIER.DECLARATION");
2796                  }
2797              
2798 kumpf   1.61     if (value.getType() == CIMTYPE_NONE)
2799 mike    1.23     {
2800              	if (isArray)
2801              	    value.setNullValue(type, true, arraySize);
2802              	else
2803              	    value.setNullValue(type, false);
2804                  }
2805              
2806                  CIMQualifierDecl tmp(name, value, scope, flavor, arraySize);
2807                  qualifierDecl = CIMQualifierDecl(name, value, scope, flavor, arraySize);
2808                  return true;
2809              }
2810              
2811              //------------------------------------------------------------------------------
2812              // getMethodElement()
2813              //
2814              //     <!ELEMENT METHOD (QUALIFIER*,(PARAMETER|PARAMETER.REFERENCE|
2815              //         PARAMETER.ARRAY|PARAMETER.REFARRAY)*)>
2816              //     <!ATTLIST METHOD
2817              //         %CIMName;
2818              //         %CIMType; #IMPLIED
2819              //         %ClassOrigin;
2820 mike    1.23 //         %Propagated;>
2821              //
2822              //------------------------------------------------------------------------------
2823              
2824              Boolean XmlReader::getMethodElement(XmlParser& parser, CIMMethod& method)
2825              {
2826                  XmlEntry entry;
2827              
2828                  if (!testStartTagOrEmptyTag(parser, entry, "METHOD"))
2829              	return false;
2830              
2831                  Boolean empty = entry.type == XmlEntry::EMPTY_TAG;
2832              
2833                  String name = getCimNameAttribute(parser.getLine(), entry, "PROPERTY");
2834              
2835                  CIMType type = getCimTypeAttribute(parser.getLine(), entry, "PROPERTY");
2836              
2837 kumpf   1.62     CIMName classOrigin = 
2838 mike    1.23 	getClassOriginAttribute(parser.getLine(), entry, "PROPERTY");
2839              
2840                  Boolean propagated = getCimBooleanAttribute(
2841              	parser.getLine(), entry, "PROPERTY", "PROPAGATED", false, false);
2842              
2843                  method = CIMMethod(name, type, classOrigin, propagated);
2844              
2845                  if (!empty)
2846                  {
2847 kumpf   1.26         // ATTN-RK-P2-20020219: Decoding algorithm must not depend on the
2848                      // ordering of qualifiers and parameters.
2849 mike    1.23 	getQualifierElements(parser, method);
2850              
2851              	GetParameterElements(parser, method);
2852              
2853              	expectEndTag(parser, "METHOD");
2854                  }
2855              
2856                  return true;
2857              }
2858              
2859              //------------------------------------------------------------------------------
2860              // getClassElement()
2861              //
2862              //     <!ELEMENT CLASS (QUALIFIER*,
2863              //         (PROPERTY|PROPERTY.ARRAY|PROPERTY.REFERENCE)*,METHOD*)>
2864              //     <!ATTLIST CLASS %CIMName; %SuperClass;>
2865              //
2866              //------------------------------------------------------------------------------
2867              
2868              Boolean XmlReader::getClassElement(XmlParser& parser, CIMClass& cimClass)
2869              {
2870 mike    1.23     XmlEntry entry;
2871              
2872                  if (!testStartTag(parser, entry, "CLASS"))
2873              	return false;
2874              
2875                  String name = getCimNameAttribute(parser.getLine(), entry, "CLASS");
2876              
2877 kumpf   1.62     CIMName superClass = getSuperClassAttribute(parser.getLine(), entry,"CLASS");
2878 mike    1.23 
2879                  cimClass = CIMClass(name, superClass);
2880              
2881                  // Get QUALIFIER elements:
2882              
2883                  getQualifierElements(parser, cimClass);
2884              
2885                  // Get PROPERTY elements:
2886              
2887                  GetPropertyElements(parser, cimClass);
2888              
2889                  // Get METHOD elements:
2890              
2891                  CIMMethod method;
2892              
2893                  while (getMethodElement(parser, method))
2894              	cimClass.addMethod(method);	
2895              
2896                  // Get CLASS end tag:
2897              
2898                  expectEndTag(parser, "CLASS");
2899 mike    1.23 
2900                  return true;
2901              }
2902              
2903              //------------------------------------------------------------------------------
2904              // getInstanceElement()
2905              //
2906              //     <!ELEMENT INSTANCE (QUALIFIER*,
2907              //         (PROPERTY|PROPERTY.ARRAY|PROPERTY.REFERENCE)*) >
2908              //     <!ATTLIST INSTANCE
2909              //         %ClassName;>
2910              //
2911              //------------------------------------------------------------------------------
2912              
2913              Boolean XmlReader::getInstanceElement(
2914                  XmlParser& parser, 
2915                  CIMInstance& cimInstance)
2916              {
2917                  XmlEntry entry;
2918              
2919                  if (!testStartTag(parser, entry, "INSTANCE"))
2920 mike    1.23 	return false;
2921              
2922                  String className = getClassNameAttribute(
2923              	parser.getLine(), entry, "INSTANCE");
2924              
2925                  cimInstance = CIMInstance(className);
2926              
2927                  // Get QUALIFIER elements:
2928              
2929                  getQualifierElements(parser, cimInstance);
2930              
2931                  // Get PROPERTY elements:
2932              
2933                  GetPropertyElements(parser, cimInstance);
2934              
2935                  // Get INSTANCE end tag:
2936              
2937                  expectEndTag(parser, "INSTANCE");
2938              
2939                  return true;
2940              }
2941 mike    1.23 
2942              //------------------------------------------------------------------------------
2943 mike    1.25 // getNamedInstanceElement()
2944              //
2945              //     <!ELEMENT VALUE.NAMEDINSTANCE (INSTANCENAME,INSTANCE)>
2946              //
2947              //------------------------------------------------------------------------------
2948              
2949              Boolean XmlReader::getNamedInstanceElement(
2950                  XmlParser& parser, 
2951 kumpf   1.55     CIMInstance& namedInstance)
2952 mike    1.25 {
2953                  XmlEntry entry;
2954              
2955                  if (!testStartTag(parser, entry, "VALUE.NAMEDINSTANCE"))
2956              	return false;
2957              
2958 kumpf   1.54     CIMObjectPath instanceName;
2959 mike    1.25 
2960                  // Get INSTANCENAME elements:
2961              
2962                  if (!getInstanceNameElement(parser, instanceName))
2963                  {
2964              	throw XmlValidationError(parser.getLine(), 
2965              	    "expected INSTANCENAME element");
2966                  }
2967              
2968                  // Get INSTANCE elements:
2969              
2970 kumpf   1.55     if (!getInstanceElement(parser, namedInstance))
2971 mike    1.25     {
2972              	throw XmlValidationError(parser.getLine(),
2973              	    "expected INSTANCE element");
2974                  }
2975              
2976                  // Get VALUE.NAMEDINSTANCE end tag:
2977              
2978                  expectEndTag(parser, "VALUE.NAMEDINSTANCE");
2979              
2980 kumpf   1.55     namedInstance.setPath (instanceName);
2981 mike    1.25 
2982                  return true;
2983              }
2984              
2985              //------------------------------------------------------------------------------
2986 mike    1.23 //
2987              // getObject()
2988              //
2989              //------------------------------------------------------------------------------
2990              
2991              void XmlReader::getObject(XmlParser& parser, CIMClass& x)
2992              {
2993                  if (!getClassElement(parser, x))
2994                  {
2995              	throw XmlValidationError(parser.getLine(),
2996              	    "expected CLASS element");
2997                  }
2998              }
2999              
3000              //------------------------------------------------------------------------------
3001              //
3002              // getObject()
3003              //
3004              //------------------------------------------------------------------------------
3005              
3006              void XmlReader::getObject(XmlParser& parser, CIMInstance& x)
3007 mike    1.23 {
3008                  if (!getInstanceElement(parser, x))
3009                  {
3010              	throw XmlValidationError(parser.getLine(),
3011              	    "expected INSTANCE element");
3012                  }
3013              }
3014              
3015              //------------------------------------------------------------------------------
3016              //
3017              // getObject()
3018              //
3019              //------------------------------------------------------------------------------
3020              
3021              void XmlReader::getObject(XmlParser& parser, CIMQualifierDecl& x)
3022              {
3023                  if (!getQualifierDeclElement(parser, x))
3024                  {
3025              	throw XmlValidationError(parser.getLine(),
3026              	    "expected QUALIFIER.DECLARATION element");
3027                  }
3028 mike    1.23 }
3029              
3030              //------------------------------------------------------------------------------
3031              //
3032              // getMessageStartTag()
3033              //
3034              //------------------------------------------------------------------------------
3035              
3036              Boolean XmlReader::getMessageStartTag(
3037                  XmlParser& parser, 
3038                  String& id,
3039 kumpf   1.34     String& protocolVersion)
3040 mike    1.23 {
3041                  XmlEntry entry;
3042              
3043                  if (!testStartTag(parser, entry, "MESSAGE"))
3044              	return false;
3045              
3046                  // Get MESSAGE.ID:
3047              
3048                  if (!entry.getAttributeValue("ID", id))
3049              	throw XmlValidationError(parser.getLine(), 
3050              	    "Bad or missing MESSAGE.ID attribute");
3051              
3052                  // Get MESSAGE.PROTOCOLVERSION:
3053              
3054                  if (!entry.getAttributeValue("PROTOCOLVERSION", protocolVersion))
3055              	throw XmlValidationError(parser.getLine(),
3056              	    "Bad or missing MESSAGE.PROTOCOLVERSION attribute");
3057              
3058                  return true;
3059              }
3060              
3061 mike    1.23 //------------------------------------------------------------------------------
3062              //
3063              // getIMethodCallStartTag()
3064              //
3065              //------------------------------------------------------------------------------
3066              
3067              Boolean XmlReader::getIMethodCallStartTag(
3068                  XmlParser& parser, 
3069                  const char*& name)
3070              {
3071                  XmlEntry entry;
3072              
3073                  if (!testStartTag(parser, entry, "IMETHODCALL"))
3074              	return false;
3075              
3076                  // Get IMETHODCALL.NAME attribute:
3077              
3078                  if (!entry.getAttributeValue("NAME", name))
3079              	throw XmlValidationError(parser.getLine(),
3080              	    "Missing IMETHODCALL.NAME attribute");
3081              
3082 mike    1.23     return true;
3083              }
3084              
3085              //------------------------------------------------------------------------------
3086              //
3087              // getIMethodResponseStartTag()
3088              //
3089              //------------------------------------------------------------------------------
3090              
3091              Boolean XmlReader::getIMethodResponseStartTag(
3092                  XmlParser& parser, 
3093                  const char*& name)
3094              {
3095                  XmlEntry entry;
3096              
3097                  if (!testStartTag(parser, entry, "IMETHODRESPONSE"))
3098              	return false;
3099              
3100                  // Get IMETHODRESPONSE.NAME attribute:
3101              
3102                  if (!entry.getAttributeValue("NAME", name))
3103 mike    1.23 	throw XmlValidationError(parser.getLine(),
3104              	    "Missing IMETHODRESPONSE.NAME attribute");
3105              
3106                  return true;
3107              }
3108              
3109              //------------------------------------------------------------------------------
3110              //
3111              // getIParamValueTag()
3112              //
3113              //------------------------------------------------------------------------------
3114              
3115              Boolean XmlReader::getIParamValueTag(
3116                  XmlParser& parser, 
3117                  const char*& name)
3118              {
3119                  XmlEntry entry;
3120              
3121                  if (!testStartTag(parser, entry, "IPARAMVALUE"))
3122              	return false;
3123              
3124 mike    1.23     // Get IPARAMVALUE.NAME attribute:
3125              
3126                  if (!entry.getAttributeValue("NAME", name))
3127              	throw XmlValidationError(parser.getLine(),
3128              	    "Missing IPARAMVALUE.NAME attribute");
3129              
3130                  return true;
3131              }
3132              
3133              //------------------------------------------------------------------------------
3134              //
3135              // getBooleanValueElement()
3136              //
3137              //     Get an elements like: "<VALUE>FALSE</VALUE>"
3138              //
3139              //------------------------------------------------------------------------------
3140              
3141              Boolean XmlReader::getBooleanValueElement(
3142                  XmlParser& parser, 
3143                  Boolean& result,
3144                  Boolean required)
3145 mike    1.23 {
3146                  XmlEntry entry;
3147              
3148                  if (!testStartTag(parser, entry, "VALUE"))
3149                  {
3150              	if (required)
3151              	{
3152              	    throw XmlValidationError(parser.getLine(),
3153              		"Expected VALUE element");
3154              	}
3155              	return false;
3156                  }
3157              
3158                  expectContentOrCData(parser, entry);
3159              
3160 mike    1.25     if (CompareNoCase(entry.text, "TRUE") == 0)
3161 mike    1.23 	result = true;
3162 mike    1.25     else if (CompareNoCase(entry.text, "FALSE") == 0)
3163 mike    1.23 	result = false;
3164                  else
3165              	throw XmlSemanticError(parser.getLine(), 
3166              	    "Bad value for VALUE element: must be \"TRUE\" or \"FALSE\"");
3167              
3168                  expectEndTag(parser, "VALUE");
3169              
3170                  return true;
3171              }
3172              
3173              //------------------------------------------------------------------------------
3174              //
3175              // getErrorElement()
3176              //
3177              //     <!ELEMENT ERROR EMPTY>
3178              //     <!ATTLIST ERROR 
3179              //         CODE CDATA #REQUIRED
3180              //         DESCRIPTION CDATA #IMPLIED>
3181              //
3182              //------------------------------------------------------------------------------
3183              
3184 mike    1.23 Boolean XmlReader::getErrorElement(
3185                  XmlParser& parser, 
3186 kumpf   1.50     CIMException& cimException,
3187 mike    1.23     Boolean required)
3188              {
3189                  XmlEntry entry;
3190              
3191                  if (!testStartTagOrEmptyTag(parser, entry, "ERROR"))
3192                  {
3193              	if (required)
3194              	    throw XmlValidationError(parser.getLine(),"Expected ERROR element");
3195              	return false;
3196                  }
3197              
3198                  Boolean empty = entry.type == XmlEntry::EMPTY_TAG;
3199              
3200                  // Get ERROR.CODE
3201              
3202                  Uint32 tmpCode;
3203              
3204                  if (!entry.getAttributeValue("CODE", tmpCode))
3205              	throw XmlValidationError(
3206              	    parser.getLine(), "missing ERROR.CODE attribute");
3207              
3208 kumpf   1.50     // Get ERROR.DESCRIPTION:
3209 mike    1.23 
3210 kumpf   1.50     String tmpDescription;
3211 mike    1.23 
3212 kumpf   1.50     entry.getAttributeValue("DESCRIPTION", tmpDescription);
3213 mike    1.23 
3214                  if (!empty)
3215              	expectEndTag(parser, "ERROR");
3216              
3217 kumpf   1.50     cimException = PEGASUS_CIM_EXCEPTION(CIMStatusCode(tmpCode), tmpDescription);
3218 mike    1.23     return true;
3219              }
3220              
3221              
3222              //------------------------------------------------------------------------------
3223 kumpf   1.48 // getValueObjectElement()
3224              //
3225              // <!ELEMENT VALUE.OBJECT (CLASS|INSTANCE)>
3226              //
3227              //------------------------------------------------------------------------------
3228              
3229              Boolean XmlReader::getValueObjectElement(
3230                  XmlParser& parser, 
3231                  CIMObject& object)
3232              {
3233                  XmlEntry entry;
3234              
3235                  if (!testStartTag(parser, entry, "VALUE.OBJECT"))
3236              	return false;
3237              
3238                  CIMInstance cimInstance;
3239                  CIMClass cimClass;
3240              
3241                  if (XmlReader::getInstanceElement(parser, cimInstance))
3242                  {
3243              	object = CIMObject(cimInstance);
3244 kumpf   1.48     }
3245                  else if (!XmlReader::getClassElement(parser, cimClass))
3246                  {
3247              	object = CIMObject(cimClass);
3248                  }
3249                  else
3250                  {
3251                      throw XmlValidationError(parser.getLine(),
3252                          "Expected INSTANCE or CLASS element");
3253                  }
3254              
3255                  expectEndTag(parser, "VALUE.OBJECT");
3256              
3257                  return true;
3258              }
3259              
3260              //------------------------------------------------------------------------------
3261              // getValueObjectWithPathElement()
3262 mike    1.23 //
3263              // <!ELEMENT VALUE.OBJECTWITHPATH ((CLASSPATH,CLASS)|(INSTANCEPATH,INSTANCE))>
3264              //
3265              //------------------------------------------------------------------------------
3266              
3267 kumpf   1.48 Boolean XmlReader::getValueObjectWithPathElement(
3268 mike    1.23     XmlParser& parser, 
3269 kumpf   1.57     CIMObject& objectWithPath)
3270 mike    1.23 {
3271                  XmlEntry entry;
3272              
3273                  if (!testStartTag(parser, entry, "VALUE.OBJECTWITHPATH"))
3274              	return false;
3275              
3276 kumpf   1.54     CIMObjectPath reference;
3277 mike    1.23     Boolean isInstance = false;
3278              
3279                  if (XmlReader::getInstancePathElement(parser, reference))
3280              	isInstance = true;
3281                  else if (!XmlReader::getClassPathElement(parser, reference))
3282                  {
3283 kumpf   1.48         throw XmlValidationError(parser.getLine(),
3284                          "Expected INSTANCEPATH or CLASSPATH element");
3285 mike    1.23     }
3286              
3287                  if (isInstance)
3288                  {
3289              	CIMInstance cimInstance;
3290              
3291              	if (!XmlReader::getInstanceElement(parser, cimInstance))
3292              	{
3293              	    throw XmlValidationError(parser.getLine(),
3294 kumpf   1.48 	        "Expected INSTANCE element");
3295 mike    1.23 	}
3296 kumpf   1.57 	objectWithPath = CIMObject (cimInstance);
3297                      objectWithPath.setPath (reference);
3298 mike    1.23     }
3299                  else
3300                  {
3301              	CIMClass cimClass;
3302              
3303              	if (!XmlReader::getClassElement(parser, cimClass))
3304              	{
3305              	    throw XmlValidationError(parser.getLine(),
3306              		"Expected CLASS element");
3307              	}
3308 kumpf   1.57 	objectWithPath = CIMObject (cimClass);
3309                      objectWithPath.setPath (reference);
3310 mike    1.23     }
3311              
3312                  expectEndTag(parser, "VALUE.OBJECTWITHPATH");
3313              
3314                  return true;
3315 kumpf   1.48 }
3316              
3317              //------------------------------------------------------------------------------
3318              // getValueObjectWithLocalPathElement()
3319              //
3320              // <!ELEMENT VALUE.OBJECTWITHLOCALPATH
3321              //     ((LOCALCLASSPATH,CLASS)|(LOCALINSTANCEPATH,INSTANCE))>
3322              //
3323              //------------------------------------------------------------------------------
3324              
3325              Boolean XmlReader::getValueObjectWithLocalPathElement(
3326                  XmlParser& parser, 
3327 kumpf   1.57     CIMObject& objectWithPath)
3328 kumpf   1.48 {
3329                  XmlEntry entry;
3330              
3331                  if (!testStartTag(parser, entry, "VALUE.OBJECTWITHLOCALPATH"))
3332              	return false;
3333              
3334 kumpf   1.54     CIMObjectPath reference;
3335 kumpf   1.48     Boolean isInstance = false;
3336              
3337                  if (XmlReader::getLocalInstancePathElement(parser, reference))
3338              	isInstance = true;
3339                  else if (!XmlReader::getLocalClassPathElement(parser, reference))
3340                  {
3341                      throw XmlValidationError(parser.getLine(),
3342              	    "Expected LOCALINSTANCEPATH or LOCALCLASSPATH element");
3343                  }
3344              
3345                  if (isInstance)
3346                  {
3347              	CIMInstance cimInstance;
3348              
3349              	if (!XmlReader::getInstanceElement(parser, cimInstance))
3350              	{
3351              	    throw XmlValidationError(parser.getLine(),
3352              	        "Expected INSTANCE element");
3353              	}
3354 kumpf   1.57 	objectWithPath = CIMObject (cimInstance);
3355              	objectWithPath.setPath (reference);
3356 kumpf   1.48     }
3357                  else
3358                  {
3359              	CIMClass cimClass;
3360              
3361              	if (!XmlReader::getClassElement(parser, cimClass))
3362              	{
3363              	    throw XmlValidationError(parser.getLine(),
3364              		"Expected CLASS element");
3365              	}
3366 kumpf   1.57 	objectWithPath = CIMObject (cimClass);
3367              	objectWithPath.setPath (reference);
3368 kumpf   1.48     }
3369              
3370                  expectEndTag(parser, "VALUE.OBJECTWITHLOCALPATH");
3371              
3372                  return true;
3373              }
3374              
3375              //------------------------------------------------------------------------------
3376              // getObjectArray()
3377              //
3378              // <object>
3379              //     (VALUE.OBJECT|VALUE.OBJECTWITHLOCALPATH|VALUE.OBJECTWITHPATH)
3380              //
3381              //------------------------------------------------------------------------------
3382              
3383              void XmlReader::getObjectArray(
3384                  XmlParser& parser, 
3385 kumpf   1.57     Array<CIMObject>& objectArray)
3386 kumpf   1.48 {
3387                  CIMObject object;
3388 kumpf   1.57     CIMObject objectWithPath;
3389 kumpf   1.48 
3390                  objectArray.clear();
3391              
3392                  if (getValueObjectElement(parser, object))
3393                  {
3394 kumpf   1.57         objectArray.append(object);
3395 kumpf   1.48         while (getValueObjectElement(parser, object))
3396 kumpf   1.57             objectArray.append(object);
3397 kumpf   1.48     }
3398                  else if (getValueObjectWithPathElement(parser, objectWithPath))
3399                  {
3400                      objectArray.append(objectWithPath);
3401                      while (getValueObjectWithPathElement(parser, objectWithPath))
3402                          objectArray.append(objectWithPath);
3403                  }
3404                  else if (getValueObjectWithLocalPathElement(parser, objectWithPath))
3405                  {
3406                      objectArray.append(objectWithPath);
3407                      while (getValueObjectWithLocalPathElement(parser, objectWithPath))
3408                          objectArray.append(objectWithPath);
3409                  }
3410 mike    1.23 }
3411              
3412              //------------------------------------------------------------------------------
3413              //
3414              // <objectName>: (CLASSNAME|INSTANCENAME)
3415              //
3416              //------------------------------------------------------------------------------
3417              
3418              Boolean XmlReader::getObjectNameElement(
3419                  XmlParser& parser, 
3420 kumpf   1.54     CIMObjectPath& objectName)
3421 mike    1.23 {
3422                  String className;
3423              
3424                  if (getClassNameElement(parser, className, false))
3425                  {
3426 kumpf   1.62 	objectName.set(String(), CIMNamespaceName(), className);
3427 mike    1.23 	return true;
3428                  }
3429                  else if (getInstanceNameElement(parser, objectName))
3430              	return true;
3431                  else
3432                  {
3433              	throw XmlValidationError(parser.getLine(),
3434              	    "expected CLASSNAME or INSTANCENAME element");
3435                  }
3436              
3437                  return false;
3438              }
3439              
3440              //------------------------------------------------------------------------------
3441              //
3442              // <!ELEMENT OBJECTPATH (INSTANCEPATH|CLASSPATH)>
3443              //
3444              //------------------------------------------------------------------------------
3445              
3446              Boolean XmlReader::getObjectPathElement(
3447                  XmlParser& parser, 
3448 kumpf   1.54     CIMObjectPath& objectPath)
3449 mike    1.23 {
3450                  XmlEntry entry;
3451              
3452                  if (!testStartTag(parser, entry, "OBJECTPATH"))
3453              	return false;
3454              
3455                  if (getClassPathElement(parser, objectPath))
3456                  {
3457              	expectEndTag(parser, "OBJECTPATH");
3458              	return true;
3459                  }
3460                  else if (getInstancePathElement(parser, objectPath))
3461                  {
3462              	expectEndTag(parser, "OBJECTPATH");
3463              	return true;
3464                  }
3465                  else
3466                  {
3467              	throw XmlValidationError(parser.getLine(),
3468              	    "expected INSTANCEPATH or CLASSPATH element");
3469                  }
3470 mike    1.23 
3471 mike    1.24     PEGASUS_UNREACHABLE ( return false; )
3472 mike    1.25 }
3473              
3474              //------------------------------------------------------------------------------
3475              //
3476              // getEMethodCallStartTag()
3477              //
3478              //------------------------------------------------------------------------------
3479              
3480              Boolean XmlReader::getEMethodCallStartTag(
3481                  XmlParser& parser, 
3482                  const char*& name)
3483              {
3484                  XmlEntry entry;
3485              
3486                  if (!testStartTag(parser, entry, "EXPMETHODCALL"))
3487              	return false;
3488              
3489                  // Get EXPMETHODCALL.NAME attribute:
3490              
3491                  if (!entry.getAttributeValue("NAME", name))
3492              	throw XmlValidationError(parser.getLine(),
3493 mike    1.25 	    "Missing EXPMETHODCALL.NAME attribute");
3494              
3495                  return true;
3496              }
3497              
3498              //------------------------------------------------------------------------------
3499              //
3500              // getEMethodResponseStartTag()
3501              //
3502              //------------------------------------------------------------------------------
3503              
3504              Boolean XmlReader::getEMethodResponseStartTag(
3505                  XmlParser& parser, 
3506                  const char*& name)
3507              {
3508                  XmlEntry entry;
3509              
3510                  if (!testStartTag(parser, entry, "EXPMETHODRESPONSE"))
3511              	return false;
3512              
3513                  // Get EXPMETHODRESPONSE.NAME attribute:
3514 mike    1.25 
3515                  if (!entry.getAttributeValue("NAME", name))
3516              	throw XmlValidationError(parser.getLine(),
3517              	    "Missing EXPMETHODRESPONSE.NAME attribute");
3518              
3519                  return true;
3520              }
3521              
3522              //------------------------------------------------------------------------------
3523              //
3524              // getMethodCallStartTag()
3525              //
3526              //------------------------------------------------------------------------------
3527              
3528              Boolean XmlReader::getMethodCallStartTag(
3529                  XmlParser& parser, 
3530                  const char*& name)
3531              {
3532                  XmlEntry entry;
3533              
3534                  if (!testStartTag(parser, entry, "METHODCALL"))
3535 mike    1.25 	return false;
3536              
3537                  // Get METHODCALL.NAME attribute:
3538              
3539                  if (!entry.getAttributeValue("NAME", name))
3540              	throw XmlValidationError(parser.getLine(),
3541              	    "Missing METHODCALL.NAME attribute");
3542              
3543                  return true;
3544              }
3545              
3546              //------------------------------------------------------------------------------
3547              //
3548              // getMethodResponseStartTag()
3549              //
3550              //------------------------------------------------------------------------------
3551              
3552              Boolean XmlReader::getMethodResponseStartTag(
3553                  XmlParser& parser, 
3554                  const char*& name)
3555              {
3556 mike    1.25     XmlEntry entry;
3557              
3558                  if (!testStartTag(parser, entry, "METHODRESPONSE"))
3559              	return false;
3560              
3561                  // Get METHODRESPONSE.NAME attribute:
3562              
3563                  if (!entry.getAttributeValue("NAME", name))
3564              	throw XmlValidationError(parser.getLine(),
3565              	    "Missing METHODRESPONSE.NAME attribute");
3566              
3567                  return true;
3568              }
3569              
3570              //------------------------------------------------------------------------------
3571              //
3572 kumpf   1.26 // getParamValueElement()
3573              //
3574              // <!ELEMENT PARAMVALUE (VALUE|VALUE.REFERENCE|VALUE.ARRAY|VALUE.REFARRAY)?>
3575              // <!ATTLIST PARAMVALUE
3576              //      %CIMName;
3577              //      %ParamType;>
3578 mike    1.25 //
3579              //------------------------------------------------------------------------------
3580              
3581 kumpf   1.26 Boolean XmlReader::getParamValueElement(
3582 mike    1.25     XmlParser& parser, 
3583 kumpf   1.26     CIMParamValue& paramValue)
3584 mike    1.25 {
3585                  XmlEntry entry;
3586 kumpf   1.26     const char* name;
3587                  CIMType type;
3588                  CIMValue value;
3589 mike    1.25 
3590 kumpf   1.26     if (!testStartTagOrEmptyTag(parser, entry, "PARAMVALUE"))
3591 mike    1.25 	return false;
3592              
3593 kumpf   1.26     Boolean empty = entry.type == XmlEntry::EMPTY_TAG;
3594              
3595                  // Get PARAMVALUE.NAME attribute:
3596 mike    1.25 
3597                  if (!entry.getAttributeValue("NAME", name))
3598              	throw XmlValidationError(parser.getLine(),
3599              	    "Missing PARAMVALUE.NAME attribute");
3600 kumpf   1.26 
3601                  // Get PARAMVALUE.PARAMTYPE attribute:
3602              
3603                  type = getCimTypeAttribute(parser.getLine(), entry, "PARAMVALUE",
3604              			       "PARAMTYPE", false);
3605              
3606                  if (!empty)
3607                  {
3608                      // Parse VALUE.REFERENCE and VALUE.REFARRAY type
3609 kumpf   1.61         if ( (type == CIMTYPE_REFERENCE) || (type == CIMTYPE_NONE) )
3610 kumpf   1.26         {
3611 kumpf   1.54 	    CIMObjectPath reference;
3612 kumpf   1.26 	    if (XmlReader::getValueReferenceElement(parser, reference))
3613              	    {
3614              	        value.set(reference);
3615 kumpf   1.61 	        type = CIMTYPE_REFERENCE;
3616 kumpf   1.26 	    }
3617 kumpf   1.28             else if (XmlReader::getValueReferenceArrayElement(parser, value))
3618              	    {
3619 kumpf   1.61 	        type = CIMTYPE_REFERENCE;
3620 kumpf   1.28 	    }
3621 kumpf   1.27             // If type==reference but no VALUE.REFERENCE found, use null value
3622 kumpf   1.26         }
3623              
3624                      // Parse non-reference value
3625 kumpf   1.61         if ( type != CIMTYPE_REFERENCE )
3626 kumpf   1.26         {
3627              	    // If we don't know what type the value is, read it as a String
3628                          CIMType effectiveType = type;
3629 kumpf   1.61             if ( effectiveType == CIMTYPE_NONE)
3630 kumpf   1.26 	    {
3631 kumpf   1.61 		effectiveType = CIMTYPE_STRING;
3632 kumpf   1.26 	    }
3633              
3634                          if ( !XmlReader::getValueArrayElement(parser, effectiveType, value) &&
3635              	         !XmlReader::getValueElement(parser, effectiveType, value) )
3636              	    {
3637              	        value.clear();    // Isn't necessary; should already be cleared
3638              	    }
3639                      }
3640              
3641                      expectEndTag(parser, "PARAMVALUE");
3642                  }
3643              
3644 kumpf   1.61     paramValue = CIMParamValue(name, value, Boolean(type!=CIMTYPE_NONE));
3645 kumpf   1.27 
3646                  return true;
3647              }
3648              
3649              //------------------------------------------------------------------------------
3650              //
3651              // getReturnValueElement()
3652              //
3653              // <!ELEMENT RETURNVALUE (VALUE|VALUE.REFERENCE)>
3654              // <!ATTLIST RETURNVALUE
3655              //      %ParamType;>
3656              //
3657              //------------------------------------------------------------------------------
3658              
3659              Boolean XmlReader::getReturnValueElement(
3660                  XmlParser& parser, 
3661                  CIMValue& returnValue)
3662              {
3663                  XmlEntry entry;
3664                  CIMType type;
3665                  CIMValue value;
3666 kumpf   1.27 
3667                  if (!testStartTag(parser, entry, "RETURNVALUE"))
3668              	return false;
3669              
3670                  // Get RETURNVALUE.PARAMTYPE attribute:
3671                  // NOTE: Array type return values are not allowed (2/20/02)
3672              
3673                  type = getCimTypeAttribute(parser.getLine(), entry, "RETURNVALUE",
3674              			       "PARAMTYPE", false);
3675              
3676                  // Parse VALUE.REFERENCE type
3677 kumpf   1.61     if ( (type == CIMTYPE_REFERENCE) || (type == CIMTYPE_NONE) )
3678 kumpf   1.27     {
3679 kumpf   1.54         CIMObjectPath reference;
3680 kumpf   1.27         if (XmlReader::getValueReferenceElement(parser, reference))
3681                      {
3682                          returnValue.set(reference);
3683 kumpf   1.61             type = CIMTYPE_REFERENCE;
3684 kumpf   1.27         }
3685 kumpf   1.61         else if (type == CIMTYPE_REFERENCE)
3686 kumpf   1.27         {
3687                          throw XmlValidationError(parser.getLine(),
3688                              "expected VALUE.REFERENCE element");
3689                      }
3690                  }
3691              
3692                  // Parse non-reference return value
3693 kumpf   1.61     if ( type != CIMTYPE_REFERENCE )
3694 kumpf   1.27     {
3695                      // If we don't know what type the value is, read it as a String
3696 kumpf   1.61         if ( type == CIMTYPE_NONE)
3697 kumpf   1.27         {
3698 kumpf   1.61             type = CIMTYPE_STRING;
3699 kumpf   1.27         }
3700              
3701                      if ( !XmlReader::getValueElement(parser, type, returnValue) )
3702                      {
3703                          throw XmlValidationError(parser.getLine(),
3704                              "expected VALUE element");
3705                      }
3706                  }
3707              
3708                  expectEndTag(parser, "RETURNVALUE");
3709 mike    1.25 
3710                  return true;
3711 mike    1.23 }
3712              
3713              PEGASUS_NAMESPACE_END

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2