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

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2