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

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2