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

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

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2