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

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2