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

   1 mike  1.1 //BEGIN_LICENSE
   2           //
   3           // Copyright (c) 2000 The Open Group, BMC Software, Tivoli Systems, IBM
   4           //
   5           // Permission is hereby granted, free of charge, to any person obtaining a
   6           // copy of this software and associated documentation files (the "Software"),
   7           // to deal in the Software without restriction, including without limitation
   8           // the rights to use, copy, modify, merge, publish, distribute, sublicense,
   9           // and/or sell copies of the Software, and to permit persons to whom the
  10           // Software is furnished to do so, subject to the following conditions:
  11           //
  12           // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  13           // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  14           // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  15           // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  16           // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  17           // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  18           // DEALINGS IN THE SOFTWARE.
  19           //
  20           //END_LICENSE
  21           //BEGIN_HISTORY
  22 mike  1.1 //
  23           // Author:
  24           //
  25 mike  1.2 // $Log: XmlReader.cpp,v $
  26 mike  1.5 // Revision 1.4  2001/02/26 04:33:28  mike
  27           // Fixed many places where cim names were be compared with operator==(String,String).
  28           // Changed all of these to use CIMName::equal()
  29           //
  30 mike  1.4 // Revision 1.3  2001/02/19 01:47:16  mike
  31 mike  1.6 // Renamed names of the form CIMConst to CIMConst.
  32 mike  1.4 //
  33 mike  1.3 // Revision 1.2  2001/02/16 02:06:07  mike
  34           // Renamed many classes and headers.
  35           //
  36 mike  1.2 // Revision 1.1.1.1  2001/01/14 19:53:32  mike
  37           // Pegasus import
  38           //
  39 mike  1.1 //
  40           //END_HISTORY
  41           
  42           #include <cassert>
  43           #include <cctype>
  44           #include <cstdio>
  45           #include <cstdlib>
  46 mike  1.2 #include "CIMName.h"
  47 mike  1.1 #include "XmlReader.h"
  48           #include "XmlWriter.h"
  49 mike  1.2 #include "CIMQualifier.h"
  50           #include "CIMQualifierDecl.h"
  51           #include "CIMClass.h"
  52           #include "CIMInstance.h"
  53 mike  1.1 
  54           PEGASUS_NAMESPACE_BEGIN
  55           
  56           static const Uint32 MESSAGE_SIZE = 128;
  57           
  58           //------------------------------------------------------------------------------
  59           //
  60           // expectXmlDeclaration()
  61           //
  62           //------------------------------------------------------------------------------
  63           
  64           void XmlReader::expectXmlDeclaration(
  65               XmlParser& parser, 
  66               XmlEntry& entry)
  67           {
  68               if (!parser.next(entry) ||
  69           	entry.type != XmlEntry::XML_DECLARATION ||
  70           	strcmp(entry.text, "xml") != 0)
  71               {
  72           	throw XmlValidationError(parser.getLine(),
  73           	    "Expected <?xml ... ?> style declaration");
  74 mike  1.1     }
  75           }
  76           
  77           //------------------------------------------------------------------------------
  78           //
  79           // expectStartTag()
  80           //
  81           //------------------------------------------------------------------------------
  82           
  83           void XmlReader::expectStartTag(
  84               XmlParser& parser, 
  85               XmlEntry& entry,
  86               const char* tagName)
  87           {
  88               if (!parser.next(entry) ||
  89           	entry.type != XmlEntry::START_TAG ||
  90           	strcmp(entry.text, tagName) != 0)
  91               {
  92           	char message[MESSAGE_SIZE];
  93           	sprintf(message, "Expected open of %s element", tagName);
  94           	throw XmlValidationError(parser.getLine(), message);
  95 mike  1.1     }
  96           }
  97           
  98           //------------------------------------------------------------------------------
  99           //
 100           // expectEndTag()
 101           //
 102           //------------------------------------------------------------------------------
 103           
 104           void XmlReader::expectEndTag(XmlParser& parser, const char* tagName)
 105           {
 106               XmlEntry entry;
 107           
 108               if (!parser.next(entry) ||
 109           	entry.type != XmlEntry::END_TAG ||
 110           	strcmp(entry.text, tagName) != 0)
 111               {
 112           	char message[MESSAGE_SIZE];
 113           	sprintf(message, "Expected close of %s element", tagName);
 114           	throw XmlValidationError(parser.getLine(), message);
 115               }
 116 mike  1.1 }
 117           
 118           //------------------------------------------------------------------------------
 119           //
 120           // expectStartTagOrEmptyTag()
 121           //
 122           //------------------------------------------------------------------------------
 123           
 124           void XmlReader::expectStartTagOrEmptyTag(
 125               XmlParser& parser, 
 126               XmlEntry& entry,
 127               const char* tagName)
 128           {
 129               if (!parser.next(entry) ||
 130           	(entry.type != XmlEntry::START_TAG &&
 131           	entry.type != XmlEntry::EMPTY_TAG) ||
 132           	strcmp(entry.text, tagName) != 0)
 133               {
 134           	char message[MESSAGE_SIZE];
 135           	sprintf(message, 
 136           	    "Expected either open or open/close %s element", tagName);
 137 mike  1.1 	throw XmlValidationError(parser.getLine(), message);
 138               }
 139           }
 140           
 141           //------------------------------------------------------------------------------
 142           //
 143           // expectContentOrCData()
 144           //
 145           //------------------------------------------------------------------------------
 146           
 147           Boolean XmlReader::expectContentOrCData(
 148               XmlParser& parser, 
 149               XmlEntry& entry)
 150           {
 151               if (!parser.next(entry) ||
 152           	(entry.type != XmlEntry::CONTENT &&
 153           	entry.type != XmlEntry::CDATA))
 154               {
 155           	throw XmlValidationError(parser.getLine(),
 156           	    "Expected content of CDATA");
 157               }
 158 mike  1.1 
 159               return true;
 160           }
 161           
 162           //------------------------------------------------------------------------------
 163           //
 164           // testStartTag()
 165           //
 166           //------------------------------------------------------------------------------
 167           
 168           Boolean XmlReader::testStartTag(
 169               XmlParser& parser, 
 170               XmlEntry& entry,
 171               const char* tagName)
 172           {
 173               if (!parser.next(entry) ||
 174           	entry.type != XmlEntry::START_TAG ||
 175           	strcmp(entry.text, tagName) != 0)
 176               {
 177           	parser.putBack(entry);
 178           	return false;
 179 mike  1.1     }
 180           
 181               return true;
 182           }
 183           
 184           //------------------------------------------------------------------------------
 185           //
 186           // testEndTag>()
 187           //
 188           //------------------------------------------------------------------------------
 189           
 190           Boolean XmlReader::testEndTag(XmlParser& parser, const char* tagName)
 191           {
 192               XmlEntry entry;
 193           
 194               if (!parser.next(entry) ||
 195           	entry.type != XmlEntry::END_TAG ||
 196           	strcmp(entry.text, tagName) != 0)
 197               {
 198           	parser.putBack(entry);
 199           	return false;
 200 mike  1.1     }
 201           
 202               return true;
 203           }
 204           
 205           //------------------------------------------------------------------------------
 206           //
 207           // testStartTagOrEmptyTag()
 208           //
 209           //------------------------------------------------------------------------------
 210           
 211           Boolean XmlReader::testStartTagOrEmptyTag(
 212               XmlParser& parser, 
 213               XmlEntry& entry,
 214               const char* tagName)
 215           {
 216               if (!parser.next(entry) ||
 217           	(entry.type != XmlEntry::START_TAG &&
 218           	entry.type != XmlEntry::EMPTY_TAG) ||
 219           	strcmp(entry.text, tagName) != 0)
 220               {
 221 mike  1.1 	parser.putBack(entry);
 222           	return false;
 223               }
 224           
 225               return true;
 226           }
 227           
 228           //------------------------------------------------------------------------------
 229           //
 230           // testContentOrCData()
 231           //
 232           //------------------------------------------------------------------------------
 233           
 234           Boolean XmlReader::testContentOrCData(
 235               XmlParser& parser, 
 236               XmlEntry& entry)
 237           {
 238               if (!parser.next(entry) ||
 239           	(entry.type != XmlEntry::CONTENT &&
 240           	entry.type != XmlEntry::CDATA))
 241               {
 242 mike  1.1 	parser.putBack(entry);
 243           	return false;
 244               }
 245           
 246               return true;
 247           }
 248           
 249           //------------------------------------------------------------------------------
 250           //
 251           // testCimStartTag()
 252           //
 253           //     <!ELEMENT CIM (MESSAGE|DECLARATION)>
 254           //     <!ATTRLIST CIM 
 255           //         CIMVERSION CDATA #REQUIRED
 256           //         DTDVERSION CDATA #REQUIRED>
 257           //
 258           //------------------------------------------------------------------------------
 259           
 260           void XmlReader::testCimStartTag(XmlParser& parser)
 261           {
 262               XmlEntry entry;
 263 mike  1.1     XmlReader::expectStartTag(parser, entry, "CIM");
 264           
 265               const char* cimVersion;
 266           
 267               if (!entry.getAttributeValue("CIMVERSION", cimVersion))
 268           	throw XmlValidationError(
 269           	    parser.getLine(), "missing CIM.CIMVERSION attribute");
 270           
 271               if (strcmp(cimVersion, "2.0") != 0)
 272           	throw XmlValidationError(parser.getLine(), 
 273           	    "CIM.CIMVERSION attribute must be \"2.0\"");
 274           
 275               const char* dtdVersion;
 276           
 277               if (!entry.getAttributeValue("DTDVERSION", dtdVersion))
 278           	throw XmlValidationError(
 279           	    parser.getLine(), "missing CIM.DTDVERSION attribute");
 280           
 281               if (strcmp(dtdVersion, "2.0") != 0)
 282           	throw XmlValidationError(parser.getLine(), 
 283           	    "CIM.DTDVERSION attribute must be \"2.0\"");
 284 mike  1.1 }
 285           
 286           //------------------------------------------------------------------------------
 287           //
 288           // getIsArrayAttribute()
 289           //
 290           //------------------------------------------------------------------------------
 291           
 292           Boolean XmlReader::getIsArrayAttribute(
 293               Uint32 lineNumber,
 294               const XmlEntry& entry,
 295               const char* tagName,
 296               Boolean& value)
 297           {
 298               const char* tmp;
 299           
 300               if (!entry.getAttributeValue("ISARRAY", tmp))
 301           	return false;
 302           
 303               if (strcmp(tmp, "true") == 0)
 304               {
 305 mike  1.1 	value = true;
 306           	return true;
 307               }
 308               else if (strcmp(tmp, "false") == 0)
 309               {
 310           	value = false;
 311           	return true;
 312               }
 313           
 314               char buffer[62];
 315               sprintf(buffer, "Bad %s.%s attribute value", "ISARRAY", tagName);
 316               throw XmlSemanticError(lineNumber, buffer);
 317               return false;
 318           }
 319           
 320           //------------------------------------------------------------------------------
 321           //
 322           // getCimNameAttribute()
 323           //
 324           //     <!ENTITY % CIMName "NAME CDATA #REQUIRED">
 325           //
 326 mike  1.1 //------------------------------------------------------------------------------
 327           
 328           String XmlReader::getCimNameAttribute(
 329               Uint32 lineNumber, 
 330               const XmlEntry& entry,
 331               const char* elementName,
 332               Boolean acceptNull)
 333           {
 334               String name;
 335           
 336               if (!entry.getAttributeValue("NAME", name))
 337               {
 338           	char buffer[MESSAGE_SIZE];
 339           	sprintf(buffer, "missing %s.NAME attribute", elementName);
 340           	throw XmlValidationError(lineNumber, buffer);
 341               }
 342           
 343               if (acceptNull && name.getLength() == 0)
 344           	return name;
 345           
 346 mike  1.2     if (!CIMName::legal(name))
 347 mike  1.1     {
 348           	char buffer[MESSAGE_SIZE];
 349           	sprintf(buffer, "Illegal value for %s.NAME attribute", elementName);
 350           	throw XmlSemanticError(lineNumber, buffer);
 351               }
 352           
 353               return name;
 354           }
 355           
 356           //------------------------------------------------------------------------------
 357           //
 358           // getClassNameAttribute()
 359           //
 360           //     <!ENTITY % CIMName "CLASSNAME CDATA #REQUIRED">
 361           //
 362           //------------------------------------------------------------------------------
 363           
 364           String XmlReader::getClassNameAttribute(
 365               Uint32 lineNumber, 
 366               const XmlEntry& entry,
 367               const char* elementName)
 368 mike  1.1 {
 369               String name;
 370           
 371               if (!entry.getAttributeValue("CLASSNAME", name))
 372               {
 373           	char buffer[MESSAGE_SIZE];
 374           	sprintf(buffer, "missing %s.CLASSNAME attribute", elementName);
 375           	throw XmlValidationError(lineNumber, buffer);
 376               }
 377           
 378 mike  1.2     if (!CIMName::legal(name))
 379 mike  1.1     {
 380           	char buffer[MESSAGE_SIZE];
 381           	sprintf(buffer, 
 382           	    "Illegal value for %s.CLASSNAME attribute", elementName);
 383           	throw XmlSemanticError(lineNumber, buffer);
 384               }
 385           
 386               return name;
 387           }
 388           
 389           //------------------------------------------------------------------------------
 390           //
 391           // getClassOriginAttribute()
 392           //
 393           //     <!ENTITY % ClassOrigin "CLASSORIGIN CDATA #IMPLIED">
 394           //
 395           //------------------------------------------------------------------------------
 396           
 397           String XmlReader::getClassOriginAttribute(
 398               Uint32 lineNumber, 
 399               const XmlEntry& entry,
 400 mike  1.1     const char* tagName)
 401           {
 402               String name;
 403           
 404               if (!entry.getAttributeValue("CLASSORIGIN", name))
 405           	return String();
 406           
 407 mike  1.2     if (!CIMName::legal(name))
 408 mike  1.1     {
 409           	char buffer[MESSAGE_SIZE];
 410           	sprintf(buffer, 
 411           	    "Illegal value for %s.CLASSORIGIN attribute", tagName);
 412           	throw XmlSemanticError(lineNumber, buffer);
 413               }
 414           
 415               return name;
 416           }
 417           
 418           //------------------------------------------------------------------------------
 419           //
 420           // getReferenceClassAttribute()
 421           //
 422           //     <!ENTITY % ReferenceClass "REFERENCECLASS CDATA #IMPLIED">
 423           //
 424           //------------------------------------------------------------------------------
 425           
 426           String XmlReader::getReferenceClassAttribute(
 427               Uint32 lineNumber, 
 428               const XmlEntry& entry,
 429 mike  1.1     const char* elementName)
 430           {
 431               String name;
 432           
 433               if (!entry.getAttributeValue("REFERENCECLASS", name))
 434           	return String();
 435           
 436 mike  1.2     if (!CIMName::legal(name))
 437 mike  1.1     {
 438           	char buffer[MESSAGE_SIZE];
 439           	sprintf(buffer, 
 440           	    "Illegal value for %s.REFERENCECLASS attribute", elementName);
 441           	throw XmlSemanticError(lineNumber, buffer);
 442               }
 443           
 444               return name;
 445           }
 446           
 447           //------------------------------------------------------------------------------
 448           //
 449           // getSuperClassAttribute()
 450           //
 451           //     <!ENTITY % SuperClass "SUPERCLASS CDATA #IMPLIED">
 452           //
 453           //------------------------------------------------------------------------------
 454           
 455           String XmlReader::getSuperClassAttribute(
 456               Uint32 lineNumber, 
 457               const XmlEntry& entry,
 458 mike  1.1     const char* tagName)
 459           {
 460               String superClass;
 461           
 462               if (!entry.getAttributeValue("SUPERCLASS", superClass))
 463           	return String();
 464           
 465 mike  1.2     if (!CIMName::legal(superClass))
 466 mike  1.1     {
 467           	char buffer[MESSAGE_SIZE];
 468           	sprintf(
 469           	    buffer, "Illegal value for %s.SUPERCLASS attribute", tagName);
 470           	throw XmlSemanticError(lineNumber, buffer);
 471               }
 472           
 473               return superClass;
 474           }
 475           
 476           //------------------------------------------------------------------------------
 477           //
 478           // getCimTypeAttribute()
 479           //
 480           //     <!ENTITY % CIMType "TYPE (boolean|string|char16|uint8|sint8|uint16
 481           //         |sint16|uint32|sint32|uint64|sint64|datetime|real32|real64)">
 482           //
 483           //------------------------------------------------------------------------------
 484           
 485 mike  1.2 CIMType XmlReader::getCimTypeAttribute(
 486 mike  1.1     Uint32 lineNumber, 
 487               const XmlEntry& entry, 
 488               const char* tagName)
 489           {
 490               const char* typeName;
 491           
 492               if (!entry.getAttributeValue("TYPE", typeName))
 493               {
 494           	char message[MESSAGE_SIZE];
 495           	sprintf(message, "missing %s.TYPE attribute", tagName);
 496           	throw XmlValidationError(lineNumber, message);
 497               }
 498           
 499 mike  1.2     CIMType type = CIMType::NONE;
 500 mike  1.1 
 501               if (strcmp(typeName, "boolean") == 0)
 502 mike  1.2 	type = CIMType::BOOLEAN;
 503 mike  1.1     else if (strcmp(typeName, "string") == 0)
 504 mike  1.2 	type = CIMType::STRING;
 505 mike  1.1     else if (strcmp(typeName, "char16") == 0)
 506 mike  1.2 	type = CIMType::CHAR16;
 507 mike  1.1     else if (strcmp(typeName, "uint8") == 0)
 508 mike  1.2 	type = CIMType::UINT8;
 509 mike  1.1     else if (strcmp(typeName, "sint8") == 0)
 510 mike  1.2 	type = CIMType::SINT8;
 511 mike  1.1     else if (strcmp(typeName, "uint16") == 0)
 512 mike  1.2 	type = CIMType::UINT16;
 513 mike  1.1     else if (strcmp(typeName, "sint16") == 0)
 514 mike  1.2 	type = CIMType::SINT16;
 515 mike  1.1     else if (strcmp(typeName, "uint32") == 0)
 516 mike  1.2 	type = CIMType::UINT32;
 517 mike  1.1     else if (strcmp(typeName, "sint32") == 0)
 518 mike  1.2 	type = CIMType::SINT32;
 519 mike  1.1     else if (strcmp(typeName, "uint64") == 0)
 520 mike  1.2 	type = CIMType::UINT64;
 521 mike  1.1     else if (strcmp(typeName, "sint64") == 0)
 522 mike  1.2 	type = CIMType::SINT64;
 523 mike  1.1     else if (strcmp(typeName, "datetime") == 0)
 524 mike  1.2 	type = CIMType::DATETIME;
 525 mike  1.1     else if (strcmp(typeName, "real32") == 0)
 526 mike  1.2 	type = CIMType::REAL32;
 527 mike  1.1     else if (strcmp(typeName, "real64") == 0)
 528 mike  1.2 	type = CIMType::REAL64;
 529 mike  1.1     else if (strcmp(typeName, "reference") == 0)
 530 mike  1.2 	type = CIMType::REFERENCE;
 531 mike  1.1 
 532               // ATTN: "reference" is not legal according to the DTD; however, it is
 533               // used by the XML version of the CIM schema.
 534           
 535 mike  1.2     if (type == CIMType::NONE)
 536 mike  1.1     {
 537           	char message[MESSAGE_SIZE];
 538           	sprintf(message, "Illegal value for %s.TYPE attribute", tagName);
 539           	throw XmlSemanticError(lineNumber, message);
 540               }
 541           
 542               return type;
 543           }
 544           
 545           //------------------------------------------------------------------------------
 546           //
 547           // getCimBooleanAttribute()
 548           //
 549           //------------------------------------------------------------------------------
 550           
 551           Boolean XmlReader::getCimBooleanAttribute(
 552               Uint32 lineNumber,
 553               const XmlEntry& entry,
 554               const char* tagName,
 555               const char* attributeName,
 556               Boolean defaultValue,
 557 mike  1.1     Boolean required)
 558           {
 559               const char* tmp;
 560           
 561               if (!entry.getAttributeValue(attributeName, tmp))
 562               {
 563           	if (!required)
 564           	    return defaultValue;
 565           
 566           	char buffer[62];
 567           	sprintf(buffer, "missing required %s.%s attribute", 
 568           	    attributeName, tagName);
 569           
 570           	throw XmlValidationError(lineNumber, buffer);
 571               }
 572           
 573               if (strcmp(tmp, "true") == 0)
 574           	return true;
 575               else if (strcmp(tmp, "false") == 0)
 576           	return false;
 577           
 578 mike  1.1     char buffer[62];
 579               sprintf(buffer, "Bad %s.%s attribute value", attributeName, tagName);
 580               throw XmlSemanticError(lineNumber, buffer);
 581               return false;
 582           }
 583           
 584           //------------------------------------------------------------------------------
 585           //
 586           // SringToReal()
 587           //
 588           //	[ "+" | "-" ] *decimalDigit "." 1*decimalDigit 
 589           //	    [ ( "e" | "E" ) [ "+" | "-" ] 1*decimalDigit ]
 590           //
 591           //------------------------------------------------------------------------------
 592           
 593           Boolean XmlReader::stringToReal(const char* stringValue, Real64& x)
 594           {
 595               const char* p = stringValue;
 596           
 597               if (!*p)
 598           	return false;
 599 mike  1.1 
 600               // Skip optional sign:
 601           
 602               if (*p == '+' || *p  == '-')
 603           	p++;
 604           
 605               // Skip optional first set of digits:
 606           
 607               while (isdigit(*p))
 608           	p++;
 609           
 610               // Test required dot:
 611           
 612               if (*p++ != '.')
 613           	return false;
 614           
 615               // One or more digits required:
 616           
 617               if (!isdigit(*p++))
 618           	return false;
 619           
 620 mike  1.1     while (isdigit(*p))
 621           	p++;
 622           
 623               // If there is an exponent now:
 624           
 625               if (*p)
 626               {
 627           	// Test exponent:
 628           
 629           	if (*p != 'e' && *p != 'E')
 630           	    return false;
 631           
 632           	p++;
 633           
 634           	// Skip optional sign:
 635           
 636           	if (*p == '+' || *p  == '-')
 637           	    p++;
 638           
 639           	// One or more digits required:
 640           
 641 mike  1.1 	if (!isdigit(*p++))
 642           	    return false;
 643           
 644           	while (isdigit(*p))
 645           	    p++;
 646               }
 647           
 648               if (*p)
 649           	return false;
 650           
 651               char* end;
 652               x = strtod(stringValue, &end);
 653               return true;
 654           }
 655           
 656           //------------------------------------------------------------------------------
 657           //
 658           // stringToSignedInteger
 659           //
 660           //	[ "+" | "-" ] ( positiveDecimalDigit *decimalDigit | "0" )
 661           //
 662 mike  1.1 // ATTN-B: handle conversion from hexadecimal.
 663           //------------------------------------------------------------------------------
 664           
 665           Boolean XmlReader::stringToSignedInteger(
 666               const char* stringValue, 
 667               Sint64& x)
 668           {
 669               x = 0;
 670               const char* p = stringValue;
 671           
 672               if (!*p)
 673           	return false;
 674           
 675               // Skip optional sign:
 676           
 677               Boolean negative = *p == '-';
 678           
 679               if (negative || *p == '+')
 680           	p++;
 681           
 682               // If the next thing is a zero, then it must be the last:
 683 mike  1.1 
 684               if (*p == '0')
 685           	return p[1] == '\0';
 686           
 687               // Expect a positive decimal digit:
 688           
 689               const char* first = p;
 690           
 691               if (!isdigit(*p) || *p == '0')
 692           	return false;
 693           
 694               p++;
 695           
 696               // Expect zero or more digits:
 697           
 698               while (isdigit(*p))
 699           	p++;
 700           
 701               if (*p)
 702           	return false;
 703           
 704 mike  1.1     const char* last = p;
 705           
 706               while (first != last)
 707           	x = 10 * x + (*first++ - '0');
 708           
 709               if (negative)
 710           	x = -x;
 711           
 712               return true;
 713           }
 714           
 715           //------------------------------------------------------------------------------
 716           //
 717           // stringToUnsignedInteger
 718           //
 719           //	[ "+" | "-" ] ( positiveDecimalDigit *decimalDigit | "0" )
 720           //
 721           // ATTN-B: handle conversion from hexadecimal.
 722           //------------------------------------------------------------------------------
 723           
 724           Boolean XmlReader::stringToUnsignedInteger(
 725 mike  1.1     const char* stringValue, 
 726               Uint64& x)
 727           {
 728               x = 0;
 729               const char* p = stringValue;
 730           
 731               if (!*p)
 732           	return false;
 733           
 734               // Skip optional sign:
 735           
 736               if (*p == '-')
 737           	return false;
 738           
 739               if (*p == '+')
 740           	p++;
 741           
 742               // If the next thing is a zero, then it must be the last:
 743           
 744               if (*p == '0')
 745           	return p[1] == '\0';
 746 mike  1.1 
 747               // Expect a positive decimal digit:
 748           
 749               const char* first = p;
 750           
 751               if (!isdigit(*p) || *p == '0')
 752           	return false;
 753           
 754               p++;
 755           
 756               // Expect zero or more digits:
 757           
 758               while (isdigit(*p))
 759           	p++;
 760           
 761               if (*p)
 762           	return false;
 763           
 764               const char* last = p;
 765           
 766               while (first != last)
 767 mike  1.1 	x = 10 * x + (*first++ - '0');
 768           
 769               return true;
 770           }
 771           
 772           //------------------------------------------------------------------------------
 773           //
 774           // stringToValue()
 775           //
 776           // ATTN-C: note that integers are truncated without warning. What should be 
 777           // done in this case? In C they are truncated without warning by design.
 778           //
 779           //------------------------------------------------------------------------------
 780           
 781 mike  1.2 CIMValue XmlReader::stringToValue(
 782 mike  1.1     Uint32 lineNumber, 
 783               const char* valueString, 
 784 mike  1.2     CIMType type)
 785 mike  1.1 {
 786               // ATTN-B: accepting only UTF-8 for now! (affects string and char16):
 787           
 788               switch (type)
 789               {
 790 mike  1.2 	case CIMType::BOOLEAN:
 791 mike  1.1 	{
 792           	    if (strcmp(valueString, "TRUE") == 0)
 793 mike  1.2 		return CIMValue(true);
 794 mike  1.1 	    else if (strcmp(valueString, "FALSE") == 0)
 795 mike  1.2 		return CIMValue(false);
 796 mike  1.1 	    else
 797           		throw XmlSemanticError(
 798           		    lineNumber, "Bad boolean value");
 799           	}
 800           
 801 mike  1.2 	case CIMType::STRING:
 802 mike  1.1 	{
 803 mike  1.2 	    return CIMValue(valueString);
 804 mike  1.1 	}
 805           
 806 mike  1.2 	case CIMType::CHAR16:
 807 mike  1.1 	{
 808           	    if (strlen(valueString) != 1)
 809           		throw XmlSemanticError(lineNumber, "Bad char16 value");
 810           
 811 mike  1.2 	    return CIMValue(Char16(valueString[0]));
 812 mike  1.1 	}
 813           
 814 mike  1.2 	case CIMType::UINT8:
 815           	case CIMType::UINT16:
 816           	case CIMType::UINT32:
 817           	case CIMType::UINT64:
 818 mike  1.1 	{
 819           	    Uint64 x;
 820           
 821           	    if (!stringToUnsignedInteger(valueString, x))
 822           	    {
 823           		throw XmlSemanticError(
 824           		    lineNumber, "Bad unsigned integer value");
 825           	    }
 826           
 827           	    switch (type)
 828           	    {
 829 mike  1.2 		case CIMType::UINT8: return CIMValue(Uint8(x));
 830           		case CIMType::UINT16: return CIMValue(Uint16(x));
 831           		case CIMType::UINT32: return CIMValue(Uint32(x));
 832           		case CIMType::UINT64: return CIMValue(Uint64(x));
 833 mike  1.1 		default: break;
 834           	    }
 835           	}
 836           
 837 mike  1.2 	case CIMType::SINT8:
 838           	case CIMType::SINT16:
 839           	case CIMType::SINT32:
 840           	case CIMType::SINT64:
 841 mike  1.1 	{
 842           	    Sint64 x;
 843           
 844           	    if (!stringToSignedInteger(valueString, x))
 845           	    {
 846           		throw XmlSemanticError(
 847           		    lineNumber, "Bad signed integer value");
 848           	    }
 849           
 850           	    switch (type)
 851           	    {
 852 mike  1.2 		case CIMType::SINT8: return CIMValue(Sint8(x));
 853           		case CIMType::SINT16: return CIMValue(Sint16(x));
 854           		case CIMType::SINT32: return CIMValue(Sint32(x));
 855           		case CIMType::SINT64: return CIMValue(Sint64(x));
 856 mike  1.1 		default: break;
 857           	    }
 858           	}
 859           
 860 mike  1.2 	case CIMType::DATETIME:
 861 mike  1.1 	{
 862 mike  1.2 	    CIMDateTime tmp;
 863 mike  1.1 
 864           	    try
 865           	    {
 866           		tmp.set(valueString);
 867           	    }
 868           	    catch (BadDateTimeFormat&)
 869           	    {
 870           		throw XmlSemanticError(lineNumber, "Bad datetime value");
 871           	    }
 872           
 873 mike  1.2 	    return CIMValue(tmp);
 874 mike  1.1 	}
 875           
 876 mike  1.2 	case CIMType::REAL32:
 877 mike  1.1 	{
 878           	    Real64 x;
 879           
 880           	    if (!stringToReal(valueString, x))
 881           		throw XmlSemanticError(lineNumber, "Bad real value");
 882           
 883 mike  1.2 	    return CIMValue(Real32(x));
 884 mike  1.1 	}
 885           
 886 mike  1.2 	case CIMType::REAL64:
 887 mike  1.1 	{
 888           	    Real64 x;
 889           
 890           	    if (!stringToReal(valueString, x))
 891           		throw XmlSemanticError(lineNumber, "Bad real value");
 892           
 893 mike  1.2 	    return CIMValue(x);
 894 mike  1.1 	}
 895           
 896           	default:
 897           	    break;
 898               }
 899           
 900               throw XmlSemanticError(lineNumber, "malformed XML");
 901               return false;
 902           }
 903           
 904           //------------------------------------------------------------------------------
 905           //
 906           // getValueElement()
 907           //
 908           //     <!ELEMENT VALUE (#PCDATA)>
 909           //
 910           //------------------------------------------------------------------------------
 911           
 912           Boolean XmlReader::getValueElement(
 913               XmlParser& parser, 
 914 mike  1.2     CIMType type, 
 915               CIMValue& value)
 916 mike  1.1 {
 917               // Get VALUE start tag:
 918           
 919               XmlEntry entry;
 920           
 921               if (!testStartTagOrEmptyTag(parser, entry, "VALUE"))
 922           	return false;
 923           
 924               Boolean empty = entry.type == XmlEntry::EMPTY_TAG;
 925           
 926               // Get VALUE content:
 927           
 928               const char* valueString = "";
 929           
 930               if (!empty)
 931               {
 932           	if (testContentOrCData(parser, entry))
 933           	    valueString = entry.text;
 934           
 935           	expectEndTag(parser, "VALUE");
 936               }
 937 mike  1.1 
 938               value = stringToValue(parser.getLine(), valueString,type);
 939               return true;
 940           }
 941           
 942           //------------------------------------------------------------------------------
 943           //
 944           // stringArrayToValue()
 945           //
 946           //------------------------------------------------------------------------------
 947           
 948           template<class T>
 949 mike  1.2 CIMValue StringArrayToValueAux(
 950 mike  1.1     Uint32 lineNumber, 
 951               const Array<const char*>& stringArray,
 952 mike  1.2     CIMType type,
 953 mike  1.1     T*)
 954           {
 955               Array<T> array;
 956           
 957               for (Uint32 i = 0, n = stringArray.getSize(); i < n; i++)
 958               {
 959 mike  1.2 	CIMValue value = XmlReader::stringToValue(
 960 mike  1.1 	    lineNumber, stringArray[i], type);
 961           
 962           	T x;
 963           	value.get(x);
 964           	array.append(x);
 965               }
 966           
 967 mike  1.2     return CIMValue(array);
 968 mike  1.1 }
 969           
 970 mike  1.2 CIMValue XmlReader::stringArrayToValue(
 971 mike  1.1     Uint32 lineNumber, 
 972               const Array<const char*>& array, 
 973 mike  1.2     CIMType type)
 974 mike  1.1 {
 975               switch (type)
 976               {
 977 mike  1.2 	case CIMType::BOOLEAN: 
 978 mike  1.1 	    return StringArrayToValueAux(lineNumber, array, type, (Boolean*)0);
 979           
 980 mike  1.2 	case CIMType::STRING:
 981 mike  1.1 	    return StringArrayToValueAux(lineNumber, array, type, (String*)0);
 982           
 983 mike  1.2 	case CIMType::CHAR16:
 984 mike  1.1 	    return StringArrayToValueAux(lineNumber, array, type, (Char16*)0);
 985           
 986 mike  1.2 	case CIMType::UINT8:
 987 mike  1.1 	    return StringArrayToValueAux(lineNumber, array, type, (Uint8*)0);
 988           
 989 mike  1.2 	case CIMType::UINT16:
 990 mike  1.1 	    return StringArrayToValueAux(lineNumber, array, type, (Uint16*)0);
 991           
 992 mike  1.2 	case CIMType::UINT32:
 993 mike  1.1 	    return StringArrayToValueAux(lineNumber, array, type, (Uint32*)0);
 994           
 995 mike  1.2 	case CIMType::UINT64:
 996 mike  1.1 	    return StringArrayToValueAux(lineNumber, array, type, (Uint64*)0);
 997           
 998 mike  1.2 	case CIMType::SINT8:
 999 mike  1.1 	    return StringArrayToValueAux(lineNumber, array, type, (Sint8*)0);
1000           
1001 mike  1.2 	case CIMType::SINT16:
1002 mike  1.1 	    return StringArrayToValueAux(lineNumber, array, type, (Sint16*)0);
1003           
1004 mike  1.2 	case CIMType::SINT32:
1005 mike  1.1 	    return StringArrayToValueAux(lineNumber, array, type, (Sint32*)0);
1006           
1007 mike  1.2 	case CIMType::SINT64:
1008 mike  1.1 	    return StringArrayToValueAux(lineNumber, array, type, (Sint64*)0);
1009           
1010 mike  1.2 	case CIMType::DATETIME:
1011           	    return StringArrayToValueAux(lineNumber, array, type, (CIMDateTime*)0);
1012 mike  1.1 
1013 mike  1.2 	case CIMType::REAL32:
1014 mike  1.1 	    return StringArrayToValueAux(lineNumber, array, type, (Real32*)0);
1015           
1016 mike  1.2 	case CIMType::REAL64:
1017 mike  1.1 	    return StringArrayToValueAux(lineNumber, array, type, (Real64*)0);
1018           
1019           	default:
1020           	    break;
1021               }
1022           
1023               // Unreachable:
1024 mike  1.2     return CIMValue();
1025 mike  1.1 }
1026           
1027           //------------------------------------------------------------------------------
1028           //
1029           // getValueArrayElement()
1030           //
1031           //     <!ELEMENT VALUE.ARRAY (VALUE*)>
1032           //
1033           //------------------------------------------------------------------------------
1034           
1035           Boolean XmlReader::getValueArrayElement(
1036               XmlParser& parser, 
1037 mike  1.2     CIMType type, 
1038               CIMValue& value)
1039 mike  1.1 {
1040               value.clear();
1041           
1042               // Get VALUE.ARRAY open tag:
1043           
1044               XmlEntry entry;
1045           
1046               if (!testStartTagOrEmptyTag(parser, entry, "VALUE.ARRAY"))
1047           	return false;
1048           
1049               if (entry.type == XmlEntry::EMPTY_TAG)
1050           	return true;
1051           
1052               // For each VALUE element:
1053           
1054               Array<const char*> stringArray;
1055           
1056               while (testStartTagOrEmptyTag(parser, entry, "VALUE"))
1057               {
1058           	if (entry.type == XmlEntry::EMPTY_TAG)
1059           	{
1060 mike  1.1 	    stringArray.append("");
1061           	    continue;
1062           	}
1063           
1064           	if (testContentOrCData(parser, entry))
1065           	    stringArray.append(entry.text);
1066           	else
1067           	    stringArray.append("");
1068           
1069           	expectEndTag(parser, "VALUE");
1070               }
1071           
1072               expectEndTag(parser, "VALUE.ARRAY");
1073           
1074               value = stringArrayToValue(parser.getLine(), stringArray, type);
1075               return true;
1076           }
1077           
1078           //------------------------------------------------------------------------------
1079           //
1080           // getFlavor()
1081 mike  1.1 //
1082           //     <!ENTITY % QualifierFlavor 
1083           //         "OVERRIDABLE (true|false) 'true'
1084           //         TOSUBCLASS (true|false) 'true'
1085           //         TOINSTANCE (true|false)  'false'
1086           //         TRANSLATABLE (true|false)  'false'">
1087           //
1088           //------------------------------------------------------------------------------
1089           
1090           Uint32 XmlReader::getFlavor(
1091               XmlEntry& entry, 
1092               Uint32 lineNumber, 
1093               const char* tagName)
1094           {
1095               // Get QUALIFIER.OVERRIDABLE
1096           
1097               Boolean overridable = getCimBooleanAttribute(
1098           	lineNumber, entry, tagName, "OVERRIDABLE", true, false);
1099           
1100               // Get QUALIFIER.TOSUBCLASS
1101           
1102 mike  1.1     Boolean toSubClass = getCimBooleanAttribute(
1103           	lineNumber, entry, tagName, "TOSUBCLASS", true, false);
1104           
1105               // Get QUALIFIER.TOINSTANCE
1106           
1107               Boolean toInstance = getCimBooleanAttribute(
1108           	lineNumber, entry, tagName, "TOINSTANCE", false, false);
1109           
1110               // Get QUALIFIER.TRANSLATABLE
1111           
1112               Boolean translatable = getCimBooleanAttribute(
1113           	lineNumber, entry, tagName, "TRANSLATABLE", false, false);
1114           
1115               Uint32 flavor = 0;
1116           
1117               if (overridable)
1118 mike  1.2 	flavor |= CIMFlavor::OVERRIDABLE;
1119 mike  1.1 
1120               if (toSubClass)
1121 mike  1.2 	flavor |= CIMFlavor::TOSUBCLASS;
1122 mike  1.1 
1123               if (toInstance)
1124 mike  1.2 	flavor |= CIMFlavor::TOINSTANCE;
1125 mike  1.1 
1126               if (translatable)
1127 mike  1.2 	flavor |= CIMFlavor::TRANSLATABLE;
1128 mike  1.1 
1129               return flavor;
1130           }
1131           
1132           //------------------------------------------------------------------------------
1133           //
1134           // getOptionalScope()
1135           //
1136           //     DTD:
1137           //         <!ELEMENT SCOPE EMPTY>
1138           //         <!ATTLIST SCOPE 
1139           //              CLASS (true|false) 'false'
1140           //              ASSOCIATION (true|false) 'false'
1141           //              REFERENCE (true|false) 'false'
1142           //              PROPERTY (true|false) 'false'
1143           //              METHOD (true|false) 'false'
1144           //              PARAMETER (true|false) 'false'
1145           //              INDICATION (true|false) 'false'>
1146           //
1147           //------------------------------------------------------------------------------
1148           
1149 mike  1.1 Uint32 XmlReader::getOptionalScope(XmlParser& parser)
1150           {
1151               XmlEntry entry;
1152           
1153               if (!parser.next(entry))
1154           	return false;
1155           
1156               Boolean isEmptyTag = entry.type == XmlEntry::EMPTY_TAG;
1157           
1158               if ((!isEmptyTag && 
1159           	entry.type != XmlEntry::START_TAG) ||
1160           	strcmp(entry.text, "SCOPE") != 0)
1161               {
1162           	parser.putBack(entry);
1163           	return 0;
1164               }
1165           
1166               Uint32 line = parser.getLine();
1167               Uint32 scope = 0;
1168           
1169               if (getCimBooleanAttribute(line, entry, "SCOPE", "CLASS", false, false))
1170 mike  1.2 	scope |= CIMScope::CLASS;
1171 mike  1.1 
1172               if (getCimBooleanAttribute(
1173           	line, entry, "SCOPE", "ASSOCIATION", false, false))
1174 mike  1.2 	scope |= CIMScope::ASSOCIATION;
1175 mike  1.1 
1176               if (getCimBooleanAttribute(
1177           	line, entry, "SCOPE", "REFERENCE", false, false))
1178 mike  1.2 	scope |= CIMScope::REFERENCE;
1179 mike  1.1 
1180               if (getCimBooleanAttribute(line, entry, "SCOPE", "PROPERTY", false, false))
1181 mike  1.2 	scope |= CIMScope::PROPERTY;
1182 mike  1.1 
1183               if (getCimBooleanAttribute(line, entry, "SCOPE", "METHOD", false, false))
1184 mike  1.2 	scope |= CIMScope::METHOD;
1185 mike  1.1 
1186               if (getCimBooleanAttribute(line, entry, "SCOPE", "PARAMETER", false, false))
1187 mike  1.2 	scope |= CIMScope::PARAMETER;
1188 mike  1.1 
1189               if (getCimBooleanAttribute(line, entry, "SCOPE", "INDICATION",false, false))
1190 mike  1.2 	scope |= CIMScope::INDICATION;
1191 mike  1.1 
1192               if (!isEmptyTag)
1193           	expectEndTag(parser, "SCOPE");
1194           
1195               return scope;
1196           }
1197           
1198           //------------------------------------------------------------------------------
1199           //
1200           // getQualifierElement()
1201           //
1202           //     <!ELEMENT QUALIFIER (VALUE|VALUE.ARRAY)>
1203           //     <!ATTLIST QUALIFIER
1204           //         %CIMName;
1205           //         %CIMType; #REQUIRED
1206           //         %Propagated;
1207           //         %QualifierFlavor;>
1208           //
1209           //------------------------------------------------------------------------------
1210           
1211           Boolean XmlReader::getQualifierElement(
1212 mike  1.1     XmlParser& parser, 
1213 mike  1.2     CIMQualifier& qualifier)
1214 mike  1.1 {
1215               // Get QUALIFIER element:
1216           
1217               XmlEntry entry;
1218               if (!testStartTag(parser, entry, "QUALIFIER"))
1219           	return false;
1220           
1221               // Get QUALIFIER.NAME attribute:
1222           
1223               String name = getCimNameAttribute(parser.getLine(), entry, "QUALIFIER");
1224           
1225               // Get QUALIFIER.TYPE attribute:
1226           
1227 mike  1.2     CIMType type = getCimTypeAttribute(parser.getLine(), entry, "QUALIFIER");
1228 mike  1.1 
1229               // Get QUALIFIER.PROPAGATED
1230           
1231               Boolean propagated = getCimBooleanAttribute(
1232           	parser.getLine(), entry, "QUALIFIER", "PROPAGATED", false, false);
1233           
1234               // Get flavor oriented attributes:
1235           
1236               Uint32 flavor = getFlavor(entry, parser.getLine(), "QUALIFIER");
1237           
1238               // Get VALUE or VALUE.ARRAY element:
1239           
1240 mike  1.2     CIMValue value;
1241 mike  1.1 
1242               if (!getValueElement(parser, type, value) &&
1243           	!getValueArrayElement(parser, type, value))
1244               {
1245           	throw XmlSemanticError(parser.getLine(),
1246           	    "Expected VALUE or VALUE.ARRAY element");
1247               }
1248           
1249               // Expect </QUALIFIER>:
1250           
1251               expectEndTag(parser, "QUALIFIER");
1252           
1253               // Build qualifier:
1254           
1255 mike  1.2     qualifier = CIMQualifier(name, value, flavor, propagated);
1256 mike  1.1     return true;
1257           }
1258           
1259           //------------------------------------------------------------------------------
1260           //
1261           // getQualifierElements()
1262           //
1263           //------------------------------------------------------------------------------
1264           
1265           template<class CONTAINER>
1266           void getQualifierElements(XmlParser& parser, CONTAINER& container)
1267           {
1268 mike  1.2     CIMQualifier qualifier;
1269 mike  1.1 
1270               while (XmlReader::getQualifierElement(parser, qualifier))
1271               {
1272           	try
1273           	{
1274           	    container.addQualifier(qualifier);
1275           	}
1276           	catch (AlreadyExists&)
1277           	{
1278           	    throw XmlSemanticError(parser.getLine(), "duplicate qualifier");
1279           	}
1280               }
1281           }
1282           
1283           //------------------------------------------------------------------------------
1284           //
1285           // getPropertyElement()
1286           //
1287           //     <!ELEMENT PROPERTY (QUALIFIER*,VALUE?)>
1288           //     <!ATTLIST PROPERTY
1289           //         %CIMName;
1290 mike  1.1 //         %ClassOrigin;
1291           //         %Propagated;
1292           //         %CIMType; #REQUIRED>
1293           //
1294           //------------------------------------------------------------------------------
1295           
1296 mike  1.2 Boolean XmlReader::getPropertyElement(XmlParser& parser, CIMProperty& property)
1297 mike  1.1 {
1298               XmlEntry entry;
1299           
1300               if (!testStartTagOrEmptyTag(parser, entry, "PROPERTY"))
1301           	return false;
1302           
1303               Boolean empty = entry.type == XmlEntry::EMPTY_TAG;
1304           
1305               // Get PROPERTY.NAME attribute:
1306           
1307               String name = getCimNameAttribute(parser.getLine(), entry, "PROPERTY");
1308           
1309               // Get PROPERTY.CLASSORIGIN attribute:
1310           
1311               String classOrigin = 
1312           	getClassOriginAttribute(parser.getLine(), entry, "PROPERTY");
1313           
1314               // Get PROPERTY.PROPAGATED
1315           
1316               Boolean propagated = getCimBooleanAttribute(
1317           	parser.getLine(), entry, "PROPERTY", "PROPAGATED", false, false);
1318 mike  1.1 
1319               // Get PROPERTY.TYPE attribute:
1320           
1321 mike  1.2     CIMType type = getCimTypeAttribute(parser.getLine(), entry, "PROPERTY");
1322 mike  1.1 
1323               // Create property:
1324           
1325 mike  1.2     CIMValue value;
1326 mike  1.1     value.setNullValue(type, false);
1327 mike  1.2     property = CIMProperty(
1328 mike  1.1 	name, value, 0, String(), classOrigin, propagated);
1329           
1330               if (!empty)
1331               {
1332           	// Get qualifiers:
1333           
1334           	getQualifierElements(parser, property);
1335           
1336           	// Get value:
1337           
1338           	if (getValueElement(parser, type, value))
1339           	    property.setValue(value);
1340           
1341           	expectEndTag(parser, "PROPERTY");
1342               }
1343           
1344               return true;
1345           }
1346           
1347           //------------------------------------------------------------------------------
1348           //
1349 mike  1.1 // getArraySizeAttribute()
1350           //
1351           //     Returns true if able to get array-size. Note that array size will
1352           //     always be a positive integer.
1353           //
1354           //     <!ENTITY % ArraySize "ARRAYSIZE CDATA #IMPLIED">
1355           //
1356           //------------------------------------------------------------------------------
1357           
1358           Boolean XmlReader::getArraySizeAttribute(
1359               Uint32 lineNumber,
1360               const XmlEntry& entry,
1361               const char* tagName,
1362               Uint32& value)
1363           {
1364               const char* tmp;
1365           
1366               if (!entry.getAttributeValue("ARRAYSIZE", tmp))
1367           	return false;
1368           
1369               Uint64 arraySize;
1370 mike  1.1 
1371               if (!stringToUnsignedInteger(tmp, arraySize) || arraySize == 0)
1372               {
1373           	char message[128];
1374           	sprintf(message, "Illegal value for %s.%s", tagName, "ARRAYSIZE");
1375           	throw XmlSemanticError(lineNumber, message);
1376               }
1377           
1378               value = Uint32(arraySize);
1379               return true;
1380           }
1381           
1382           //------------------------------------------------------------------------------
1383           //
1384           // getPropertyArrayElement()
1385           //
1386           //     <!ELEMENT PROPERTY.ARRAY (QUALIFIER*,VALUE.ARRAY?)>
1387           //     <!ATTLIST PROPERTY.ARRAY
1388           //             %CIMName;
1389           //             %CIMType; #REQUIRED
1390           //             %ArraySize;
1391 mike  1.1 //             %ClassOrigin;
1392           //             %Propagated;>
1393           //
1394           //------------------------------------------------------------------------------
1395           
1396           Boolean XmlReader::getPropertyArrayElement(
1397               XmlParser& parser, 
1398 mike  1.2     CIMProperty& property)
1399 mike  1.1 {
1400               // Get PROPERTY element:
1401           
1402               XmlEntry entry;
1403           
1404               if (!testStartTagOrEmptyTag(parser, entry, "PROPERTY.ARRAY"))
1405           	return false;
1406           
1407               Boolean empty = entry.type == XmlEntry::EMPTY_TAG;
1408           
1409               // Get PROPERTY.NAME attribute:
1410           
1411               String name = 
1412           	getCimNameAttribute(parser.getLine(), entry, "PROPERTY.ARRAY");
1413           
1414               // Get PROPERTY.TYPE attribute:
1415           
1416 mike  1.2     CIMType type = getCimTypeAttribute(parser.getLine(), entry, "PROPERTY.ARRAY");
1417 mike  1.1 
1418               // Get PROPERTY.ARRAYSIZE attribute:
1419           
1420               Uint32 arraySize = 0;
1421               getArraySizeAttribute(parser.getLine(), entry, "PROPERTY.ARRAY", arraySize);
1422           
1423               // Get PROPERTY.CLASSORIGIN attribute:
1424           
1425               String classOrigin 
1426           	= getClassOriginAttribute(parser.getLine(), entry, "PROPERTY.ARRAY");
1427           
1428               // Get PROPERTY.ARRAY.PROPAGATED
1429           
1430               Boolean propagated = getCimBooleanAttribute(
1431           	parser.getLine(), entry, "PROPERTY.ARRAY", "PROPAGATED", false, false);
1432           
1433               // Create property:
1434           
1435 mike  1.2     CIMValue nullValue;
1436 mike  1.1     nullValue.setNullValue(type, true, arraySize);
1437 mike  1.2     property = CIMProperty(
1438 mike  1.1 	name, nullValue, arraySize, String(), classOrigin, propagated);
1439           
1440               if (!empty)
1441               {
1442           	// Get qualifiers:
1443           
1444           	getQualifierElements(parser, property);
1445           
1446           	// Get value:
1447           
1448 mike  1.2 	CIMValue value;
1449 mike  1.1 
1450           	if (getValueArrayElement(parser, type, value))
1451           	{
1452           	    if (arraySize && arraySize != value.getArraySize())
1453           	    {
1454           		throw XmlSemanticError(parser.getLine(),
1455           		    "ARRAYSIZE attribute and value-array size are different");
1456           	    }
1457           
1458           	    property.setValue(value);
1459           	}
1460           
1461           	expectEndTag(parser, "PROPERTY.ARRAY");
1462               }
1463           
1464               return true;
1465           }
1466           
1467           //------------------------------------------------------------------------------
1468           //
1469           // getHostElement()
1470 mike  1.1 //
1471           //     <!ELEMENT HOST (#PCDATA)>
1472           //
1473           //------------------------------------------------------------------------------
1474           
1475           Boolean XmlReader::getHostElement(
1476               XmlParser& parser,
1477               String& host)
1478           {
1479               XmlEntry entry;
1480           
1481               if (!testStartTag(parser, entry, "HOST"))
1482           	return false;
1483           
1484               if (!parser.next(entry) || entry.type != XmlEntry::CONTENT)
1485               {
1486           	throw XmlValidationError(parser.getLine(),
1487           	    "expected content of HOST element");
1488               }
1489           
1490               host = entry.text;
1491 mike  1.1 
1492               expectEndTag(parser, "HOST");
1493               return true;
1494           }
1495           
1496           //------------------------------------------------------------------------------
1497           //
1498           // getNameSpaceElement()
1499           //     
1500           //     <!ELEMENT NAMESPACE EMPTY>
1501           //     <!ATTLIST NAMESPACE %CIMName;>
1502           //
1503           //------------------------------------------------------------------------------
1504           
1505           Boolean XmlReader::getNameSpaceElement(
1506               XmlParser& parser,
1507               String& nameSpaceComponent)
1508           {
1509               XmlEntry entry;
1510           
1511               if (!testStartTagOrEmptyTag(parser, entry, "NAMESPACE"))
1512 mike  1.1 	return false;
1513           
1514               Boolean empty = entry.type == XmlEntry::EMPTY_TAG;
1515           
1516               nameSpaceComponent = getCimNameAttribute(
1517           	parser.getLine(), entry, "NAMESPACE");
1518           
1519               if (!empty)
1520           	expectEndTag(parser, "NAMESPACE");
1521           
1522               return true;
1523           }
1524           
1525           //------------------------------------------------------------------------------
1526           //
1527           // getLocalNameSpacePathElement()
1528           //     
1529           //     <!ELEMENT LOCALNAMESPACEPATH (NAMESPACE+)>
1530           //
1531           //------------------------------------------------------------------------------
1532           
1533 mike  1.1 Boolean XmlReader::getLocalNameSpacePathElement(
1534               XmlParser& parser,
1535               String& nameSpace)
1536           {
1537               XmlEntry entry;
1538           
1539               if (!testStartTag(parser, entry, "LOCALNAMESPACEPATH"))
1540           	return false;
1541           
1542               String nameSpaceComponent;
1543           
1544               while (getNameSpaceElement(parser, nameSpaceComponent))
1545               {
1546           	if (nameSpace.getLength())
1547           	    nameSpace += '/';
1548           
1549           	nameSpace += nameSpaceComponent;
1550               }
1551           
1552               if (!nameSpace.getLength())
1553               {
1554 mike  1.1 	throw XmlValidationError(parser.getLine(),
1555           	    "Expected one or more NAMESPACE elements within "
1556           	    "LOCALNAMESPACEPATH element");
1557               }
1558           
1559               expectEndTag(parser, "LOCALNAMESPACEPATH");
1560               return true;
1561           }
1562           
1563           //------------------------------------------------------------------------------
1564           //
1565           // getNameSpacePathElement()
1566           //
1567           //     <!ELEMENT NAMESPACEPATH (HOST,LOCALNAMESPACEPATH)>
1568           //
1569           //------------------------------------------------------------------------------
1570           
1571           Boolean XmlReader::getNameSpacePathElement(
1572               XmlParser& parser,
1573               String& host,
1574               String& nameSpace)
1575 mike  1.1 {
1576               host.clear();
1577               nameSpace.clear();
1578           
1579               XmlEntry entry;
1580           
1581               if (!testStartTag(parser, entry, "NAMESPACEPATH"))
1582           	return false;
1583           
1584               if (!getHostElement(parser, host))
1585           	throw XmlValidationError(parser.getLine(), "expected HOST element");
1586           
1587               if (!getLocalNameSpacePathElement(parser, nameSpace))
1588               {
1589           	throw XmlValidationError(parser.getLine(), 
1590           	    "expected LOCALNAMESPACEPATH element");
1591               }
1592           
1593               expectEndTag(parser, "NAMESPACEPATH");
1594           
1595               return true;
1596 mike  1.1 }
1597           
1598           //------------------------------------------------------------------------------
1599           //
1600           // getClassNameElement()
1601           //
1602           //     <!ELEMENT CLASSNAME EMPTY>
1603           //     <!ATTLIST CLASSNAME %CIMName;>
1604           //
1605           //------------------------------------------------------------------------------
1606           
1607           Boolean XmlReader::getClassNameElement(
1608               XmlParser& parser,
1609               String& className,
1610               Boolean required)
1611           {
1612               XmlEntry entry;
1613           
1614               if (!testStartTagOrEmptyTag(parser, entry, "CLASSNAME"))
1615               {
1616           	if (required)
1617 mike  1.1 	{
1618           	    throw XmlValidationError(parser.getLine(),
1619           		"expected CLASSNAME element");
1620           	}
1621           	else
1622           	    return false;
1623               }
1624           
1625               Boolean empty = entry.type == XmlEntry::EMPTY_TAG;
1626           
1627               className = getCimNameAttribute(
1628           	parser.getLine(), entry, "CLASSNAME", true);
1629           
1630               if (!empty)
1631           	expectEndTag(parser, "CLASSNAME");
1632           
1633               return true;
1634           }
1635           
1636           //------------------------------------------------------------------------------
1637           //
1638 mike  1.1 // getValueTypeAttribute()
1639           //
1640           //     VALUETYPE (string|boolean|numeric) 'string'
1641           //
1642           //------------------------------------------------------------------------------
1643           
1644 mike  1.2 KeyBinding::CIMType XmlReader::getValueTypeAttribute(
1645 mike  1.1     Uint32 lineNumber, 
1646               const XmlEntry& entry,
1647               const char* elementName)
1648           {
1649               String tmp;
1650           
1651               if (!entry.getAttributeValue("VALUETYPE", tmp))
1652           	return KeyBinding::STRING;
1653           
1654 mike  1.4     if (String::equal(tmp, "string"))
1655 mike  1.1 	return KeyBinding::STRING;
1656 mike  1.4     else if (String::equal(tmp, "boolean"))
1657 mike  1.1 	return KeyBinding::BOOLEAN;
1658 mike  1.4     else if (String::equal(tmp, "numeric"))
1659 mike  1.1 	return KeyBinding::NUMERIC;
1660           
1661               char buffer[MESSAGE_SIZE];
1662           
1663               sprintf(buffer, 
1664           	"Illegal value for %s.VALUETYPE attribute; "
1665 mike  1.2 	"CIMValue must be one of \"string\", \"boolean\", or \"numeric\"",
1666 mike  1.1 	elementName);
1667           
1668               throw XmlSemanticError(lineNumber, buffer);
1669               return KeyBinding::BOOLEAN;
1670           }
1671           
1672           //------------------------------------------------------------------------------
1673           //
1674           // getKeyValueElement()
1675           //
1676           //     <!ELEMENT KEYVALUE (#PCDATA)>
1677           //     <!ATTLIST KEYVALUE
1678           //         VALUETYPE (string|boolean|numeric)  'string'>
1679           //
1680           // ATTN-B: VALUE.REFERENCE ignored above; can't understand why it is needed!
1681           //
1682           //------------------------------------------------------------------------------
1683           
1684           Boolean XmlReader::getKeyValueElement(
1685               XmlParser& parser,
1686 mike  1.2     KeyBinding::CIMType& type,
1687 mike  1.1     String& value)
1688           {
1689               XmlEntry entry;
1690           
1691               if (!testStartTagOrEmptyTag(parser, entry, "KEYVALUE"))
1692           	return false;
1693           
1694               Boolean empty = entry.type == XmlEntry::EMPTY_TAG;
1695           
1696               type = getValueTypeAttribute(parser.getLine(), entry, "KEYVALUE");
1697           
1698               value.clear();
1699           
1700               if (!empty)
1701               {
1702           	if (!parser.next(entry))
1703           	    throw XmlException(XmlException::UNCLOSED_TAGS, parser.getLine());
1704           
1705           	if (entry.type == XmlEntry::CONTENT)
1706           	    value = entry.text;
1707           	else
1708 mike  1.1 	    parser.putBack(entry);
1709           
1710           	expectEndTag(parser, "KEYVALUE");
1711               }
1712           
1713               return true;
1714           }
1715           
1716           //------------------------------------------------------------------------------
1717           //
1718           // getKeyBindingElement()
1719           //
1720           //     <!ELEMENT KEYBINDING (KEYVALUE|VALUE.REFERENCE)>
1721           //     <!ATTLIST KEYBINDING
1722           //         %CIMName;>
1723           //
1724           // ATTN-B: VALUE.REFERENCE ignored above; can't understand why it is needed!
1725           //
1726           //------------------------------------------------------------------------------
1727           
1728           Boolean XmlReader::getKeyBindingElement(
1729 mike  1.1     XmlParser& parser,
1730               String& name,
1731               String& value,
1732 mike  1.2     KeyBinding::CIMType& type)
1733 mike  1.1 {
1734               XmlEntry entry;
1735           
1736               if (!testStartTag(parser, entry, "KEYBINDING"))
1737           	return false;
1738           
1739               name = getCimNameAttribute(parser.getLine(), entry, "KEYBINDING");
1740           
1741               if (!getKeyValueElement(parser, type, value))
1742           	throw XmlValidationError(parser.getLine(), "Expected KEYVALUE element");
1743           
1744               expectEndTag(parser, "KEYBINDING");
1745               return true;
1746           }
1747           
1748           //------------------------------------------------------------------------------
1749           //
1750           // getInstanceNameElement()
1751           //
1752           //     <!ELEMENT INSTANCENAME (KEYBINDING*|KEYVALUE?|VALUE.REFERENCE?)>
1753           //     <!ATTLIST INSTANCENAME
1754 mike  1.1 //         %ClassName;>
1755           //
1756           // ATTN-B: VALUE.REFERENCE sub-element not accepted yet.
1757           // ATTN-B: KEYVALUE sub-element nothandled yet.
1758           //
1759           //------------------------------------------------------------------------------
1760           
1761           Boolean XmlReader::getInstanceNameElement(
1762               XmlParser& parser,
1763               String& className,
1764               Array<KeyBinding>& keyBindings)
1765           {
1766               className.clear();
1767               keyBindings.clear();
1768           
1769               XmlEntry entry;
1770           
1771               if (!testStartTagOrEmptyTag(parser, entry, "INSTANCENAME"))
1772           	return false;
1773           
1774               Boolean empty = entry.type == XmlEntry::EMPTY_TAG;
1775 mike  1.1 
1776               className = getClassNameAttribute(parser.getLine(), entry, "INSTANCENAME");
1777           
1778               if (!empty)
1779               {
1780           	String name;
1781 mike  1.2 	KeyBinding::CIMType type;
1782 mike  1.1 	String value;
1783           
1784           	while (getKeyBindingElement(parser, name, value, type))
1785           	    keyBindings.append(KeyBinding(name, value, type));
1786           
1787           	if (!empty)
1788           	    expectEndTag(parser, "INSTANCENAME");
1789               }
1790           
1791               return true;
1792           }
1793           
1794           //------------------------------------------------------------------------------
1795           //
1796           // getInstancePathElement()
1797           //
1798           //     <!ELEMENT INSTANCEPATH (NAMESPACEPATH,INSTANCENAME)>
1799           //
1800           //------------------------------------------------------------------------------
1801           
1802           Boolean XmlReader::getInstancePathElement(
1803 mike  1.1     XmlParser& parser,
1804 mike  1.2     CIMReference& reference)
1805 mike  1.1 {
1806               XmlEntry entry;
1807           
1808               if (!testStartTag(parser, entry, "INSTANCEPATH"))
1809           	return false;
1810           
1811               String host;
1812               String nameSpace;
1813           
1814               if (!getNameSpacePathElement(parser, host, nameSpace))
1815               {
1816           	throw XmlValidationError(parser.getLine(),
1817           	    "expected NAMESPACEPATH element");
1818               }
1819           
1820               String className;
1821               Array<KeyBinding> keyBindings;
1822           
1823               if (!getInstanceNameElement(parser, className, keyBindings))
1824               {
1825           	throw XmlValidationError(parser.getLine(), 
1826 mike  1.1 	    "expected INSTANCENAME element");
1827               }
1828           
1829               reference.set(host, nameSpace, className, keyBindings);
1830           
1831               expectEndTag(parser, "INSTANCEPATH");
1832               return true;
1833           }
1834           
1835           //------------------------------------------------------------------------------
1836           //
1837           // getLocalInstancePathElement()
1838           //
1839           //     <!ELEMENT LOCALINSTANCEPATH (NAMESPACEPATH,INSTANCENAME)>
1840           //
1841           //------------------------------------------------------------------------------
1842           
1843           Boolean XmlReader::getLocalInstancePathElement(
1844               XmlParser& parser,
1845 mike  1.2     CIMReference& reference)
1846 mike  1.1 {
1847               XmlEntry entry;
1848           
1849               if (!testStartTag(parser, entry, "LOCALINSTANCEPATH"))
1850           	return false;
1851           
1852               String nameSpace;
1853           
1854               if (!getLocalNameSpacePathElement(parser, nameSpace))
1855               {
1856           	throw XmlValidationError(parser.getLine(),
1857           	    "expected LOCALNAMESPACEPATH element");
1858               }
1859           
1860               String className;
1861               Array<KeyBinding> keyBindings;
1862           
1863               if (!getInstanceNameElement(parser, className, keyBindings))
1864               {
1865           	throw XmlValidationError(parser.getLine(), 
1866           	    "expected INSTANCENAME element");
1867 mike  1.1     }
1868           
1869               reference.set(String(), nameSpace, className, keyBindings);
1870           
1871               expectEndTag(parser, "LOCALINSTANCEPATH");
1872               return true;
1873           }
1874           
1875           //------------------------------------------------------------------------------
1876           //
1877           // getClassPathElement()
1878           //
1879           //     <!ELEMENT CLASSPATH (NAMESPACEPATH,CLASSNAME)>
1880           //
1881           //------------------------------------------------------------------------------
1882           
1883           Boolean XmlReader::getClassPathElement(
1884               XmlParser& parser,
1885 mike  1.2     CIMReference& reference)
1886 mike  1.1 {
1887               XmlEntry entry;
1888           
1889               if (!testStartTag(parser, entry, "CLASSPATH"))
1890           	return false;
1891           
1892               String host;
1893               String nameSpace;
1894           
1895               if (!getNameSpacePathElement(parser, host, nameSpace))
1896               {
1897           	throw XmlValidationError(parser.getLine(),
1898           	    "expected NAMESPACEPATH element");
1899               }
1900           
1901               String className;
1902           
1903               if (!getClassNameElement(parser, className))
1904               {
1905           	throw XmlValidationError(parser.getLine(), 
1906           	    "expected CLASSNAME element");
1907 mike  1.1     }
1908           
1909               reference.set(host, nameSpace, className);
1910           
1911               expectEndTag(parser, "CLASSPATH");
1912               return true;
1913           }
1914           
1915           //------------------------------------------------------------------------------
1916           //
1917           // getLocalClassPathElement()
1918           //
1919           //     <!ELEMENT LOCALCLASSPATH (LOCALNAMESPACEPATH,CLASSNAME)>
1920           //
1921           //------------------------------------------------------------------------------
1922           
1923           Boolean XmlReader::getLocalClassPathElement(
1924               XmlParser& parser,
1925 mike  1.2     CIMReference& reference)
1926 mike  1.1 {
1927               XmlEntry entry;
1928           
1929               if (!testStartTag(parser, entry, "LOCALCLASSPATH"))
1930           	return false;
1931           
1932               String nameSpace;
1933           
1934               if (!getLocalNameSpacePathElement(parser, nameSpace))
1935               {
1936           	throw XmlValidationError(parser.getLine(),
1937           	    "expected LOCALNAMESPACEPATH element");
1938               }
1939           
1940               String className;
1941           
1942               if (!getClassNameElement(parser, className))
1943               {
1944           	throw XmlValidationError(parser.getLine(), 
1945           	    "expected CLASSNAME element");
1946               }
1947 mike  1.1 
1948               reference.set(String(), nameSpace, className);
1949           
1950               expectEndTag(parser, "LOCALCLASSPATH");
1951           
1952               return true;
1953           }
1954           
1955           //------------------------------------------------------------------------------
1956           //
1957           // getValueReferenceElement()
1958           //
1959           //     <!ELEMENT VALUE.REFERENCE (CLASSPATH|LOCALCLASSPATH|CLASSNAME|
1960           //         INSTANCEPATH|LOCALINSTANCEPATH|INSTANCENAME)>
1961           //
1962           //
1963           //------------------------------------------------------------------------------
1964           
1965           Boolean XmlReader::getValueReferenceElement(
1966               XmlParser& parser,
1967 mike  1.2     CIMReference& reference)
1968 mike  1.1 {
1969               XmlEntry entry;
1970           
1971               if (!testStartTag(parser, entry, "VALUE.REFERENCE"))
1972           	return false;
1973           
1974               if (!parser.next(entry))
1975           	throw XmlException(XmlException::UNCLOSED_TAGS, parser.getLine());
1976           
1977               if (entry.type != XmlEntry::START_TAG && 
1978           	entry.type != XmlEntry::EMPTY_TAG)
1979               {
1980           	throw XmlValidationError(parser.getLine(), 
1981           	    "Expected one of the following start tags: "
1982           	    "CLASSPATH, LOCALCLASSPATH, CLASSNAME, INSTANCEPATH, "
1983           	    "LOCALINSTANCEPATH, INSTANCENAME");
1984               }
1985           
1986               if (strcmp(entry.text, "CLASSPATH") == 0)
1987               {
1988           	parser.putBack(entry);
1989 mike  1.1 	getClassPathElement(parser, reference);
1990               }
1991               else if (strcmp(entry.text, "LOCALCLASSPATH") == 0)
1992               {
1993           	parser.putBack(entry);
1994           	getLocalClassPathElement(parser, reference);
1995               }
1996               else if (strcmp(entry.text, "CLASSNAME") == 0)
1997               {
1998           	parser.putBack(entry);
1999           	String className;
2000           	getClassNameElement(parser, className);
2001           	reference.set(String(), String(), className);
2002               }
2003               else if (strcmp(entry.text, "INSTANCEPATH") == 0)
2004               {
2005           	parser.putBack(entry);
2006           	getInstancePathElement(parser, reference);
2007               }
2008               else if (strcmp(entry.text, "LOCALINSTANCEPATH") == 0)
2009               {
2010 mike  1.1 	parser.putBack(entry);
2011           	getLocalInstancePathElement(parser, reference);
2012               }
2013               else if (strcmp(entry.text, "INSTANCENAME") == 0)
2014               {
2015           	parser.putBack(entry);
2016           	String className;
2017           	Array<KeyBinding> keyBindings;
2018           	getInstanceNameElement(parser, className, keyBindings);
2019           	reference.set(String(), String(), className, keyBindings);
2020               }
2021           
2022               expectEndTag(parser, "VALUE.REFERENCE");
2023               return true;
2024           }
2025           
2026           //------------------------------------------------------------------------------
2027           //
2028           // getPropertyReferenceElement()
2029           //
2030           //     <!ELEMENT PROPERTY.REFERENCE (QUALIFIER*,(VALUE.REFERENCE)?)>
2031 mike  1.1 //     <!ATTLIST PROPERTY.REFERENCE
2032           //         %CIMName;
2033           //         %ReferenceClass;
2034           //         %ClassOrigin;
2035           //         %Propagated;>
2036           //
2037           //------------------------------------------------------------------------------
2038           
2039           Boolean XmlReader::getPropertyReferenceElement(
2040               XmlParser& parser, 
2041 mike  1.2     CIMProperty& property)
2042 mike  1.1 {
2043               XmlEntry entry;
2044           
2045               if (!testStartTagOrEmptyTag(parser, entry, "PROPERTY.REFERENCE"))
2046           	return false;
2047           
2048               Boolean empty = entry.type == XmlEntry::EMPTY_TAG;
2049           
2050               // Get PROPERTY.NAME attribute:
2051           
2052               String name = getCimNameAttribute(
2053           	parser.getLine(), entry, "PROPERTY.REFERENCE");
2054           
2055               // Get PROPERTY.REFERENCECLASS attribute:
2056           
2057               String referenceClass = getReferenceClassAttribute(
2058           	parser.getLine(), entry, "PROPERTY.REFERENCE");
2059           
2060               // Get PROPERTY.CLASSORIGIN attribute:
2061           
2062               String classOrigin = 
2063 mike  1.1 	getClassOriginAttribute(parser.getLine(), entry, "PROPERTY.REFERENCE");
2064           
2065               // Get PROPERTY.PROPAGATED
2066           
2067               Boolean propagated = getCimBooleanAttribute(parser.getLine(), entry, 
2068           	"PROPERTY.REFERENCE", "PROPAGATED", false, false);
2069           
2070               // Create property:
2071           
2072 mike  1.2     CIMValue value;
2073               value.set(CIMReference());
2074               property = CIMProperty(
2075 mike  1.1 	name, value, 0, referenceClass, classOrigin, propagated);
2076           
2077               if (!empty)
2078               {
2079           	getQualifierElements(parser, property);
2080           
2081 mike  1.2 	CIMReference reference;
2082 mike  1.1 
2083           	if (getValueReferenceElement(parser, reference))
2084           	    property.setValue(reference);
2085           
2086           	expectEndTag(parser, "PROPERTY.REFERENCE");
2087               }
2088           
2089               return true;
2090           }
2091           
2092           //------------------------------------------------------------------------------
2093           //
2094           // GetPropertyElements()
2095           //
2096           //------------------------------------------------------------------------------
2097           
2098           template<class CONTAINER>
2099           void GetPropertyElements(XmlParser& parser, CONTAINER& container)
2100           {
2101 mike  1.2     CIMProperty property;
2102 mike  1.1 
2103               while (XmlReader::getPropertyElement(parser, property) ||
2104           	XmlReader::getPropertyArrayElement(parser, property) ||
2105           	XmlReader::getPropertyReferenceElement(parser, property))
2106               {
2107           	try
2108           	{
2109           	    container.addProperty(property);
2110           	}
2111           	catch (AlreadyExists&)
2112           	{
2113           	    throw XmlSemanticError(parser.getLine(), "duplicate property");
2114           	}
2115               }
2116           }
2117           
2118           //------------------------------------------------------------------------------
2119           //
2120           // getParameterElement()
2121           //
2122           //     <!ELEMENT PARAMETER (QUALIFIER*)>
2123 mike  1.1 //     <!ATTLIST PARAMETER
2124           //         %CIMName;
2125           //         %CIMType; #REQUIRED>
2126           //
2127           //------------------------------------------------------------------------------
2128           
2129           Boolean XmlReader::getParameterElement(
2130               XmlParser& parser, 
2131 mike  1.2     CIMParameter& parameter)
2132 mike  1.1 {
2133               XmlEntry entry;
2134           
2135               if (!testStartTagOrEmptyTag(parser, entry, "PARAMETER"))
2136           	return false;
2137           
2138               Boolean empty = entry.type == XmlEntry::EMPTY_TAG;
2139           
2140               // Get PARAMETER.NAME attribute:
2141           
2142               String name = getCimNameAttribute(parser.getLine(), entry, "PARAMETER");
2143           
2144               // Get PARAMETER.TYPE attribute:
2145           
2146 mike  1.2     CIMType type = getCimTypeAttribute(parser.getLine(), entry, "PARAMETER");
2147 mike  1.1 
2148               // Create parameter:
2149           
2150 mike  1.2     parameter = CIMParameter(name, type);
2151 mike  1.1 
2152               if (!empty)
2153               {
2154           	getQualifierElements(parser, parameter);
2155           
2156           	expectEndTag(parser, "PARAMETER");
2157               }
2158           
2159               return true;
2160           }
2161           
2162           //------------------------------------------------------------------------------
2163           //
2164           // getParameterArrayElement()
2165           //
2166           //     <!ELEMENT PARAMETER.ARRAY (QUALIFIER*)>
2167           //     <!ATTLIST PARAMETER.ARRAY
2168           //         %CIMName;
2169           //         %CIMType; #REQUIRED
2170           //         %ArraySize;>
2171           //
2172 mike  1.1 //------------------------------------------------------------------------------
2173           
2174           Boolean XmlReader::getParameterArrayElement(
2175               XmlParser& parser, 
2176 mike  1.2     CIMParameter& parameter)
2177 mike  1.1 {
2178               XmlEntry entry;
2179           
2180               if (!testStartTagOrEmptyTag(parser, entry, "PARAMETER.ARRAY"))
2181           	return false;
2182           
2183               Boolean empty = entry.type == XmlEntry::EMPTY_TAG;
2184           
2185               // Get PARAMETER.ARRAY.NAME attribute:
2186           
2187               String name = getCimNameAttribute(
2188           	parser.getLine(), entry, "PARAMETER.ARRAY");
2189           
2190               // Get PARAMETER.ARRAY.TYPE attribute:
2191           
2192 mike  1.2     CIMType type = getCimTypeAttribute(parser.getLine(), entry, "PARAMETER.ARRAY");
2193 mike  1.1 
2194               // Get PARAMETER.ARRAYSIZE attribute:
2195           
2196               Uint32 arraySize = 0;
2197               getArraySizeAttribute(parser.getLine(), entry, "PARAMETER.ARRAY",arraySize);
2198           
2199               // Create parameter:
2200           
2201 mike  1.2     parameter = CIMParameter(name, type, true, arraySize);
2202 mike  1.1 
2203               if (!empty)
2204               {
2205           	getQualifierElements(parser, parameter);
2206           
2207           	expectEndTag(parser, "PARAMETER.ARRAY");
2208               }
2209           
2210               return true;
2211           }
2212           
2213           //------------------------------------------------------------------------------
2214           //
2215           // getParameterReferenceElement()
2216           //
2217           //     <!ELEMENT PARAMETER.REFERENCE (QUALIFIER*)>
2218           //     <!ATTLIST PARAMETER.REFERENCE
2219           //         %CIMName;
2220           //         %ReferenceClass;>
2221           //
2222           //------------------------------------------------------------------------------
2223 mike  1.1 
2224           Boolean XmlReader::getParameterReferenceElement(
2225               XmlParser& parser, 
2226 mike  1.2     CIMParameter& parameter)
2227 mike  1.1 {
2228               XmlEntry entry;
2229           
2230               if (!testStartTagOrEmptyTag(parser, entry, "PARAMETER.REFERENCE"))
2231           	return false;
2232           
2233               Boolean empty = entry.type == XmlEntry::EMPTY_TAG;
2234           
2235               // Get PARAMETER.NAME attribute:
2236           
2237               String name = getCimNameAttribute(
2238           	parser.getLine(), entry, "PARAMETER.REFERENCE");
2239           
2240               // Get PARAMETER.REFERENCECLASS attribute:
2241           
2242               String referenceClass = getReferenceClassAttribute(
2243           	parser.getLine(), entry, "PARAMETER.REFERENCE");
2244           
2245               // Create parameter:
2246           
2247 mike  1.2     parameter = CIMParameter(name, CIMType::REFERENCE, false, 0, referenceClass);
2248 mike  1.1 
2249               if (!empty)
2250               {
2251           	getQualifierElements(parser, parameter);
2252           	expectEndTag(parser, "PARAMETER.REFERENCE");
2253               }
2254           
2255               return true;
2256           }
2257           
2258           //------------------------------------------------------------------------------
2259           //
2260           // GetParameterElements()
2261           //
2262           //------------------------------------------------------------------------------
2263           
2264           template<class CONTAINER>
2265           void GetParameterElements(XmlParser& parser, CONTAINER& container)
2266           {
2267 mike  1.2     CIMParameter parameter;
2268 mike  1.1 
2269               while (XmlReader::getParameterElement(parser, parameter) ||
2270           	XmlReader::getParameterArrayElement(parser, parameter) ||
2271           	XmlReader::getParameterReferenceElement(parser, parameter))
2272               {
2273           	try
2274           	{
2275           	    container.addParameter(parameter);
2276           	}
2277           	catch (AlreadyExists&)
2278           	{
2279           	    throw XmlSemanticError(parser.getLine(), "duplicate parameter");
2280           	}
2281               }
2282           }
2283           
2284           //------------------------------------------------------------------------------
2285           //
2286           // getQualifierDeclElement()
2287           //
2288           //     <!ELEMENT QUALIFIER.DECLARATION (SCOPE?,(VALUE|VALUE.ARRAY)?)>
2289 mike  1.1 //     <!ATTLIST QUALIFIER.DECLARATION 
2290           //         %CIMName;               
2291           //         %CIMType; #REQUIRED
2292           //         ISARRAY (true|false) #IMPLIED
2293           //         %ArraySize;
2294           //         %QualifierFlavor;>
2295           //         
2296           //------------------------------------------------------------------------------
2297           
2298           Boolean XmlReader::getQualifierDeclElement(
2299               XmlParser& parser, 
2300 mike  1.2     CIMQualifierDecl& qualifierDecl)
2301 mike  1.1 {
2302               XmlEntry entry;
2303           
2304               if (!testStartTagOrEmptyTag(parser, entry, "QUALIFIER.DECLARATION"))
2305           	return false;
2306           
2307               Boolean empty = entry.type == XmlEntry::EMPTY_TAG;
2308           
2309               // Get NAME attribute:
2310           
2311               String name = getCimNameAttribute(
2312           	parser.getLine(), entry, "QUALIFIER.DECLARATION");
2313           
2314               // Get TYPE attribute:
2315           
2316 mike  1.2     CIMType type = getCimTypeAttribute(
2317 mike  1.1 	parser.getLine(), entry, "QUALIFIER.DECLARATION");
2318           
2319               // Get ISARRAY attribute:
2320           
2321               Boolean isArray = false;
2322               getIsArrayAttribute(
2323           	parser.getLine(), entry, "QUALIFIER.DECLARATION", isArray); 
2324           
2325               // Get ARRAYSIZE attribute:
2326           
2327               Uint32 arraySize = 0;
2328               Boolean gotArraySize = getArraySizeAttribute(parser.getLine(),
2329           	entry, "QUALIFIER.DECLARATION", arraySize);
2330           
2331               // Get flavor oriented attributes:
2332           
2333               Uint32 flavor = getFlavor(entry,parser.getLine(), "QUALIFIER.DECLARATION");
2334           
2335               // No need to look for interior elements if empty tag:
2336           
2337 mike  1.2     Uint32 scope = CIMScope::NONE;
2338               CIMValue value;
2339 mike  1.1 
2340               if (!empty)
2341               {
2342           	// Get the option SCOPE element:
2343           
2344           	scope = getOptionalScope(parser);
2345           
2346           	// Get VALUE or VALUE.ARRAY element:
2347           
2348           	if (getValueArrayElement(parser, type, value))
2349           	{
2350           	    if (!isArray)
2351           	    {
2352           		throw XmlSemanticError(parser.getLine(),
2353           		    "VALUE.ARRAY element encountered without "
2354           		    "ISARRAY attribute");
2355           	    }
2356           
2357           	    if (arraySize && arraySize != value.getArraySize())
2358           	    {
2359           		throw XmlSemanticError(parser.getLine(),
2360 mike  1.1 		    "VALUE.ARRAY size is not the same as "
2361           		    "ARRAYSIZE attribute");
2362           	    }
2363           	}
2364           	else if (getValueElement(parser, type, value))
2365           	{
2366           	    if (isArray)
2367           	    {
2368           		throw XmlSemanticError(parser.getLine(),
2369           		    "ISARRAY attribute used but VALUE element encountered");
2370           	    }
2371           	}
2372           
2373           	// Now get the closing tag:
2374           
2375           	expectEndTag(parser, "QUALIFIER.DECLARATION");
2376               }
2377           
2378 mike  1.2     if (value.getType() == CIMType::NONE)
2379 mike  1.1     {
2380           	if (isArray)
2381           	    value.setNullValue(type, true, arraySize);
2382           	else
2383           	    value.setNullValue(type, false);
2384               }
2385           
2386 mike  1.2     CIMQualifierDecl tmp(name, value, scope, flavor, arraySize);
2387               qualifierDecl = CIMQualifierDecl(name, value, scope, flavor, arraySize);
2388 mike  1.1     return true;
2389           }
2390           
2391           //------------------------------------------------------------------------------
2392           // getMethodElement()
2393           //
2394           //     <!ELEMENT METHOD (QUALIFIER*,(PARAMETER|PARAMETER.REFERENCE|
2395           //         PARAMETER.ARRAY|PARAMETER.REFARRAY)*)>
2396           //     <!ATTLIST METHOD
2397           //         %CIMName;
2398           //         %CIMType; #IMPLIED
2399           //         %ClassOrigin;
2400           //         %Propagated;>
2401           //
2402           //------------------------------------------------------------------------------
2403           
2404 mike  1.2 Boolean XmlReader::getMethodElement(XmlParser& parser, CIMMethod& method)
2405 mike  1.1 {
2406               XmlEntry entry;
2407           
2408               if (!testStartTagOrEmptyTag(parser, entry, "METHOD"))
2409           	return false;
2410           
2411               Boolean empty = entry.type == XmlEntry::EMPTY_TAG;
2412           
2413               String name = getCimNameAttribute(parser.getLine(), entry, "PROPERTY");
2414           
2415 mike  1.2     CIMType type = getCimTypeAttribute(parser.getLine(), entry, "PROPERTY");
2416 mike  1.1 
2417               String classOrigin = 
2418           	getClassOriginAttribute(parser.getLine(), entry, "PROPERTY");
2419           
2420               Boolean propagated = getCimBooleanAttribute(
2421           	parser.getLine(), entry, "PROPERTY", "PROPAGATED", false, false);
2422           
2423 mike  1.2     method = CIMMethod(name, type, classOrigin, propagated);
2424 mike  1.1 
2425               if (!empty)
2426               {
2427           	getQualifierElements(parser, method);
2428           
2429           	GetParameterElements(parser, method);
2430           
2431           	expectEndTag(parser, "METHOD");
2432               }
2433           
2434               return true;
2435           }
2436           
2437           //------------------------------------------------------------------------------
2438           // getClassElement()
2439           //
2440           //     <!ELEMENT CLASS (QUALIFIER*,
2441           //         (PROPERTY|PROPERTY.ARRAY|PROPERTY.REFERENCE)*,METHOD*)>
2442           //     <!ATTLIST CLASS %CIMName; %SuperClass;>
2443           //
2444           //------------------------------------------------------------------------------
2445 mike  1.1 
2446 mike  1.3 Boolean XmlReader::getClassElement(XmlParser& parser, CIMClass& cimClass)
2447 mike  1.1 {
2448               XmlEntry entry;
2449           
2450               if (!testStartTag(parser, entry, "CLASS"))
2451           	return false;
2452           
2453               String name = getCimNameAttribute(parser.getLine(), entry, "CLASS");
2454           
2455               String superClass = getSuperClassAttribute(parser.getLine(), entry,"CLASS");
2456           
2457 mike  1.3     cimClass = CIMClass(name, superClass);
2458 mike  1.1 
2459               // Get QUALIFIER elements:
2460           
2461 mike  1.3     getQualifierElements(parser, cimClass);
2462 mike  1.1 
2463               // Get PROPERTY elements:
2464           
2465 mike  1.3     GetPropertyElements(parser, cimClass);
2466 mike  1.1 
2467               // Get METHOD elements:
2468           
2469 mike  1.2     CIMMethod method;
2470 mike  1.1 
2471               while (getMethodElement(parser, method))
2472 mike  1.3 	cimClass.addMethod(method);	
2473 mike  1.1 
2474               // Get CLASS end tag:
2475           
2476               expectEndTag(parser, "CLASS");
2477           
2478               return true;
2479           }
2480           
2481           //------------------------------------------------------------------------------
2482           // getInstanceElement()
2483           //
2484           //     <!ELEMENT INSTANCE (QUALIFIER*,
2485           //         (PROPERTY|PROPERTY.ARRAY|PROPERTY.REFERENCE)*) >
2486           //     <!ATTLIST INSTANCE
2487           //         %ClassName;>
2488           //
2489           //------------------------------------------------------------------------------
2490           
2491           Boolean XmlReader::getInstanceElement(
2492               XmlParser& parser, 
2493 mike  1.3     CIMInstance& cimInstance)
2494 mike  1.1 {
2495               XmlEntry entry;
2496           
2497               if (!testStartTag(parser, entry, "INSTANCE"))
2498           	return false;
2499           
2500               String className = getClassNameAttribute(
2501           	parser.getLine(), entry, "INSTANCE");
2502           
2503 mike  1.3     cimInstance = CIMInstance(className);
2504 mike  1.1 
2505               // Get QUALIFIER elements:
2506           
2507 mike  1.3     getQualifierElements(parser, cimInstance);
2508 mike  1.1 
2509               // Get PROPERTY elements:
2510           
2511 mike  1.3     GetPropertyElements(parser, cimInstance);
2512 mike  1.1 
2513               // Get INSTANCE end tag:
2514           
2515               expectEndTag(parser, "INSTANCE");
2516           
2517               return true;
2518           }
2519           
2520           //------------------------------------------------------------------------------
2521           //
2522           // getMessageStartTag()
2523           //
2524           //------------------------------------------------------------------------------
2525           
2526           Boolean XmlReader::getMessageStartTag(
2527               XmlParser& parser, 
2528               Uint32& id,
2529               const char*& protocolVersion)
2530           {
2531               XmlEntry entry;
2532           
2533 mike  1.1     if (!testStartTag(parser, entry, "MESSAGE"))
2534           	return false;
2535           
2536               // Get MESSAGE.ID:
2537           
2538               if (!entry.getAttributeValue("ID", id))
2539           	throw XmlValidationError(parser.getLine(), 
2540           	    "Bad or missing MESSAGE.ID attribute");
2541           
2542               // Get MESSAGE.PROTOCOLVERSION:
2543           
2544               if (!entry.getAttributeValue("PROTOCOLVERSION", protocolVersion))
2545           	throw XmlValidationError(parser.getLine(),
2546           	    "Bad or missing MESSAGE.ID attribute");
2547           
2548               return true;
2549           }
2550           
2551           //------------------------------------------------------------------------------
2552           //
2553           // getIMethodCallStartTag()
2554 mike  1.1 //
2555           //------------------------------------------------------------------------------
2556           
2557           Boolean XmlReader::getIMethodCallStartTag(
2558               XmlParser& parser, 
2559               const char*& name)
2560           {
2561               XmlEntry entry;
2562           
2563               if (!testStartTag(parser, entry, "IMETHODCALL"))
2564           	return false;
2565           
2566               // Get IMETHODCALL.NAME attribute:
2567           
2568               if (!entry.getAttributeValue("NAME", name))
2569           	throw XmlValidationError(parser.getLine(),
2570           	    "Missing IMETHODCALL.NAME attribute");
2571           
2572               return true;
2573           }
2574           
2575 mike  1.1 //------------------------------------------------------------------------------
2576           //
2577           // getIMethodResponseStartTag()
2578           //
2579           //------------------------------------------------------------------------------
2580           
2581           Boolean XmlReader::getIMethodResponseStartTag(
2582               XmlParser& parser, 
2583               const char*& name)
2584           {
2585               XmlEntry entry;
2586           
2587               if (!testStartTag(parser, entry, "IMETHODRESPONSE"))
2588           	return false;
2589           
2590               // Get IMETHODRESPONSE.NAME attribute:
2591           
2592               if (!entry.getAttributeValue("NAME", name))
2593           	throw XmlValidationError(parser.getLine(),
2594           	    "Missing IMETHODRESPONSE.NAME attribute");
2595           
2596 mike  1.1     return true;
2597           }
2598           
2599           //------------------------------------------------------------------------------
2600           //
2601           // getIParamValueTag()
2602           //
2603           //------------------------------------------------------------------------------
2604           
2605           Boolean XmlReader::getIParamValueTag(
2606               XmlParser& parser, 
2607               const char*& name)
2608           {
2609               XmlEntry entry;
2610           
2611               if (!testStartTag(parser, entry, "IPARAMVALUE"))
2612           	return false;
2613           
2614               // Get IPARAMVALUE.NAME attribute:
2615           
2616               if (!entry.getAttributeValue("NAME", name))
2617 mike  1.1 	throw XmlValidationError(parser.getLine(),
2618           	    "Missing IPARAMVALUE.NAME attribute");
2619           
2620               return true;
2621           }
2622           
2623           //------------------------------------------------------------------------------
2624           //
2625           // getBooleanValueElement()
2626           //
2627           //     Get an elements like: "<VALUE>FALSE</VALUE>"
2628           //
2629           //------------------------------------------------------------------------------
2630           
2631           Boolean XmlReader::getBooleanValueElement(
2632               XmlParser& parser, 
2633               Boolean& result,
2634               Boolean required)
2635           {
2636               XmlEntry entry;
2637           
2638 mike  1.1     if (!testStartTag(parser, entry, "VALUE"))
2639               {
2640           	if (required)
2641           	{
2642           	    throw XmlValidationError(parser.getLine(),
2643           		"Expected VALUE element");
2644           	}
2645           	return false;
2646               }
2647           
2648               expectContentOrCData(parser, entry);
2649           
2650               if (strcmp(entry.text, "TRUE") == 0)
2651           	result = true;
2652               else if (strcmp(entry.text, "FALSE") == 0)
2653           	result = false;
2654               else
2655           	throw XmlSemanticError(parser.getLine(), 
2656           	    "Bad value for VALUE element: must be \"TRUE\" or \"FALSE\"");
2657           
2658               expectEndTag(parser, "VALUE");
2659 mike  1.1 
2660               return true;
2661           }
2662           
2663           //------------------------------------------------------------------------------
2664           //
2665           // getErrorElement()
2666           //
2667           //     <!ELEMENT ERROR EMPTY>
2668           //     <!ATTLIST ERROR 
2669           //         CODE CDATA #REQUIRED
2670           //         DESCRIPTION CDATA #IMPLIED>
2671           //
2672           //------------------------------------------------------------------------------
2673           
2674           Boolean XmlReader::getErrorElement(
2675               XmlParser& parser, 
2676 mike  1.5     CIMException::Code& code,
2677 mike  1.1     const char*& description,
2678               Boolean required)
2679           {
2680               XmlEntry entry;
2681           
2682               if (!testStartTagOrEmptyTag(parser, entry, "ERROR"))
2683               {
2684           	if (required)
2685           	    throw XmlValidationError(parser.getLine(),"Expected ERROR element");
2686           	return false;
2687               }
2688           
2689               Boolean empty = entry.type == XmlEntry::EMPTY_TAG;
2690           
2691               // Get ERROR.CODE
2692           
2693               Uint32 tmpCode;
2694           
2695               if (!entry.getAttributeValue("CODE", tmpCode))
2696           	throw XmlValidationError(
2697           	    parser.getLine(), "missing ERROR.CODE attribute");
2698 mike  1.1 
2699 mike  1.5     code = CIMException::Code(tmpCode);
2700 mike  1.1 
2701               // Get ERROR.DESCRIPTION:
2702           
2703               description = "";
2704               entry.getAttributeValue("DESCRIPTION", description);
2705           
2706               if (!empty)
2707           	expectEndTag(parser, "ERROR");
2708           
2709               return true;
2710           }
2711           
2712           PEGASUS_NAMESPACE_END

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2