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

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2