(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 kumpf 1.30 //     Use: Decode property value from SetProperty request and
1003            //     GetProperty response.
1004 mike  1.23 //
1005 kumpf 1.30 //     PropertyValue is one of:
1006 mike  1.23 //
1007 kumpf 1.30 //         <!ELEMENT VALUE (#PCDATA)>
1008 mike  1.23 //
1009 kumpf 1.30 //         <!ELEMENT VALUE.ARRAY (VALUE*)>
1010            //
1011            //         <!ELEMENT VALUE.REFERENCE (CLASSPATH|LOCALCLASSPATH|CLASSNAME|
1012 mike  1.23 //                           INSTANCEPATH|LOCALINSTANCEPATH|INSTANCENAME)>
1013            //
1014 kumpf 1.30 //         <!ELEMENT VALUE.REFARRAY (VALUE.REFERENCE*)>
1015            //
1016 mike  1.23 //----------------------------------------------------------------------------
1017            Boolean XmlReader::getPropertyValue(
1018                XmlParser& parser, 
1019                CIMValue& cimValue)
1020            {
1021 kumpf 1.30     // Can not test for value type, so assume String
1022                const CIMType type = CIMType::STRING;
1023 mike  1.23 
1024 kumpf 1.30     // Test for VALUE element
1025 mike  1.23     if (XmlReader::getValueElement(parser, type, cimValue))
1026                {
1027            	return true;
1028                }
1029            
1030 kumpf 1.30     // Test for VALUE.ARRAY element
1031                if (XmlReader::getValueArrayElement(parser, type, cimValue))
1032                {
1033 mike  1.23        return true;
1034 kumpf 1.30     }
1035 mike  1.23 
1036 kumpf 1.30     // Test for VALUE.REFERENCE element
1037 mike  1.25     CIMReference reference;
1038 kumpf 1.30     if (XmlReader::getValueReferenceElement(parser, reference))
1039 mike  1.25     {
1040                    cimValue.set(reference);
1041                    return true;
1042                }
1043 mike  1.23 
1044 kumpf 1.30     // Test for VALUE.REFARRAY element
1045                if (XmlReader::getValueReferenceArrayElement(parser, cimValue))
1046                {
1047                   return true;
1048                }
1049            
1050                return false;
1051 mike  1.23 }
1052            
1053            //------------------------------------------------------------------------------
1054            //
1055            // stringArrayToValue()
1056            //
1057            //------------------------------------------------------------------------------
1058            
1059            template<class T>
1060            CIMValue StringArrayToValueAux(
1061                Uint32 lineNumber, 
1062                const Array<const char*>& stringArray,
1063                CIMType type,
1064                T*)
1065            {
1066                Array<T> array;
1067            
1068                for (Uint32 i = 0, n = stringArray.size(); i < n; i++)
1069                {
1070            	CIMValue value = XmlReader::stringToValue(
1071            	    lineNumber, stringArray[i], type);
1072 mike  1.23 
1073            	T x;
1074            	value.get(x);
1075            	array.append(x);
1076                }
1077            
1078                return CIMValue(array);
1079            }
1080            
1081            CIMValue XmlReader::stringArrayToValue(
1082                Uint32 lineNumber, 
1083                const Array<const char*>& array, 
1084                CIMType type)
1085            {
1086                switch (type)
1087                {
1088            	case CIMType::BOOLEAN: 
1089            	    return StringArrayToValueAux(lineNumber, array, type, (Boolean*)0);
1090            
1091            	case CIMType::STRING:
1092            	    return StringArrayToValueAux(lineNumber, array, type, (String*)0);
1093 mike  1.23 
1094            	case CIMType::CHAR16:
1095            	    return StringArrayToValueAux(lineNumber, array, type, (Char16*)0);
1096            
1097            	case CIMType::UINT8:
1098            	    return StringArrayToValueAux(lineNumber, array, type, (Uint8*)0);
1099            
1100            	case CIMType::UINT16:
1101            	    return StringArrayToValueAux(lineNumber, array, type, (Uint16*)0);
1102            
1103            	case CIMType::UINT32:
1104            	    return StringArrayToValueAux(lineNumber, array, type, (Uint32*)0);
1105            
1106            	case CIMType::UINT64:
1107            	    return StringArrayToValueAux(lineNumber, array, type, (Uint64*)0);
1108            
1109            	case CIMType::SINT8:
1110            	    return StringArrayToValueAux(lineNumber, array, type, (Sint8*)0);
1111            
1112            	case CIMType::SINT16:
1113            	    return StringArrayToValueAux(lineNumber, array, type, (Sint16*)0);
1114 mike  1.23 
1115            	case CIMType::SINT32:
1116            	    return StringArrayToValueAux(lineNumber, array, type, (Sint32*)0);
1117            
1118            	case CIMType::SINT64:
1119            	    return StringArrayToValueAux(lineNumber, array, type, (Sint64*)0);
1120            
1121            	case CIMType::DATETIME:
1122            	    return StringArrayToValueAux(lineNumber, array, type, (CIMDateTime*)0);
1123            
1124            	case CIMType::REAL32:
1125            	    return StringArrayToValueAux(lineNumber, array, type, (Real32*)0);
1126            
1127            	case CIMType::REAL64:
1128            	    return StringArrayToValueAux(lineNumber, array, type, (Real64*)0);
1129            
1130            	default:
1131            	    break;
1132                }
1133            
1134                // Unreachable:
1135 mike  1.23     return CIMValue();
1136            }
1137            
1138            //------------------------------------------------------------------------------
1139            //
1140            // getValueArrayElement()
1141            //
1142            //     <!ELEMENT VALUE.ARRAY (VALUE*)>
1143            //
1144            //------------------------------------------------------------------------------
1145            
1146            Boolean XmlReader::getValueArrayElement(
1147                XmlParser& parser, 
1148                CIMType type, 
1149                CIMValue& value)
1150            {
1151                value.clear();
1152            
1153                // Get VALUE.ARRAY open tag:
1154            
1155                XmlEntry entry;
1156 mike  1.23 
1157                if (!testStartTagOrEmptyTag(parser, entry, "VALUE.ARRAY"))
1158            	return false;
1159            
1160                if (entry.type == XmlEntry::EMPTY_TAG)
1161            	return true;
1162            
1163                // For each VALUE element:
1164            
1165                Array<const char*> stringArray;
1166            
1167                while (testStartTagOrEmptyTag(parser, entry, "VALUE"))
1168                {
1169            	if (entry.type == XmlEntry::EMPTY_TAG)
1170            	{
1171            	    stringArray.append("");
1172            	    continue;
1173            	}
1174            
1175            	if (testContentOrCData(parser, entry))
1176            	    stringArray.append(entry.text);
1177 mike  1.23 	else
1178            	    stringArray.append("");
1179            
1180            	expectEndTag(parser, "VALUE");
1181                }
1182            
1183                expectEndTag(parser, "VALUE.ARRAY");
1184            
1185                value = stringArrayToValue(parser.getLine(), stringArray, type);
1186                return true;
1187            }
1188            
1189            //------------------------------------------------------------------------------
1190            //
1191            // getFlavor()
1192            //
1193            //     <!ENTITY % QualifierFlavor 
1194            //         "OVERRIDABLE (true|false) 'true'
1195            //         TOSUBCLASS (true|false) 'true'
1196            //         TOINSTANCE (true|false)  'false'
1197            //         TRANSLATABLE (true|false)  'false'">
1198 mike  1.23 //
1199            //------------------------------------------------------------------------------
1200            
1201            Uint32 XmlReader::getFlavor(
1202                XmlEntry& entry, 
1203                Uint32 lineNumber, 
1204                const char* tagName)
1205            {
1206                // Get QUALIFIER.OVERRIDABLE
1207            
1208                Boolean overridable = getCimBooleanAttribute(
1209            	lineNumber, entry, tagName, "OVERRIDABLE", true, false);
1210            
1211                // Get QUALIFIER.TOSUBCLASS
1212            
1213                Boolean toSubClass = getCimBooleanAttribute(
1214            	lineNumber, entry, tagName, "TOSUBCLASS", true, false);
1215            
1216                // Get QUALIFIER.TOINSTANCE
1217            
1218                Boolean toInstance = getCimBooleanAttribute(
1219 mike  1.23 	lineNumber, entry, tagName, "TOINSTANCE", false, false);
1220            
1221                // Get QUALIFIER.TRANSLATABLE
1222            
1223                Boolean translatable = getCimBooleanAttribute(
1224            	lineNumber, entry, tagName, "TRANSLATABLE", false, false);
1225            
1226                Uint32 flavor = 0;
1227            
1228                if (overridable)
1229            	flavor |= CIMFlavor::OVERRIDABLE;
1230            
1231                if (toSubClass)
1232            	flavor |= CIMFlavor::TOSUBCLASS;
1233            
1234                if (toInstance)
1235            	flavor |= CIMFlavor::TOINSTANCE;
1236            
1237                if (translatable)
1238            	flavor |= CIMFlavor::TRANSLATABLE;
1239            
1240 mike  1.23     return flavor;
1241            }
1242            
1243            //------------------------------------------------------------------------------
1244            //
1245            // getOptionalScope()
1246            //
1247            //     DTD:
1248            //         <!ELEMENT SCOPE EMPTY>
1249            //         <!ATTLIST SCOPE 
1250            //              CLASS (true|false) 'false'
1251            //              ASSOCIATION (true|false) 'false'
1252            //              REFERENCE (true|false) 'false'
1253            //              PROPERTY (true|false) 'false'
1254            //              METHOD (true|false) 'false'
1255            //              PARAMETER (true|false) 'false'
1256            //              INDICATION (true|false) 'false'>
1257            //
1258            //------------------------------------------------------------------------------
1259            
1260            Uint32 XmlReader::getOptionalScope(XmlParser& parser)
1261 mike  1.23 {
1262                XmlEntry entry;
1263            
1264                if (!parser.next(entry))
1265            	return false;
1266            
1267                Boolean isEmptyTag = entry.type == XmlEntry::EMPTY_TAG;
1268            
1269                if ((!isEmptyTag && 
1270            	entry.type != XmlEntry::START_TAG) ||
1271            	strcmp(entry.text, "SCOPE") != 0)
1272                {
1273            	parser.putBack(entry);
1274            	return 0;
1275                }
1276            
1277                Uint32 line = parser.getLine();
1278                Uint32 scope = 0;
1279            
1280                if (getCimBooleanAttribute(line, entry, "SCOPE", "CLASS", false, false))
1281            	scope |= CIMScope::CLASS;
1282 mike  1.23 
1283                if (getCimBooleanAttribute(
1284            	line, entry, "SCOPE", "ASSOCIATION", false, false))
1285            	scope |= CIMScope::ASSOCIATION;
1286            
1287                if (getCimBooleanAttribute(
1288            	line, entry, "SCOPE", "REFERENCE", false, false))
1289            	scope |= CIMScope::REFERENCE;
1290            
1291                if (getCimBooleanAttribute(line, entry, "SCOPE", "PROPERTY", false, false))
1292            	scope |= CIMScope::PROPERTY;
1293            
1294                if (getCimBooleanAttribute(line, entry, "SCOPE", "METHOD", false, false))
1295            	scope |= CIMScope::METHOD;
1296            
1297                if (getCimBooleanAttribute(line, entry, "SCOPE", "PARAMETER", false, false))
1298            	scope |= CIMScope::PARAMETER;
1299            
1300                if (getCimBooleanAttribute(line, entry, "SCOPE", "INDICATION",false, false))
1301            	scope |= CIMScope::INDICATION;
1302            
1303 mike  1.23     if (!isEmptyTag)
1304            	expectEndTag(parser, "SCOPE");
1305            
1306                return scope;
1307            }
1308            
1309            //------------------------------------------------------------------------------
1310            //
1311            // getQualifierElement()
1312            //
1313            //     <!ELEMENT QUALIFIER (VALUE|VALUE.ARRAY)>
1314            //     <!ATTLIST QUALIFIER
1315            //         %CIMName;
1316            //         %CIMType; #REQUIRED
1317            //         %Propagated;
1318            //         %QualifierFlavor;>
1319            //
1320            //------------------------------------------------------------------------------
1321            
1322            Boolean XmlReader::getQualifierElement(
1323                XmlParser& parser, 
1324 mike  1.23     CIMQualifier& qualifier)
1325            {
1326                // Get QUALIFIER element:
1327            
1328                XmlEntry entry;
1329                if (!testStartTag(parser, entry, "QUALIFIER"))
1330            	return false;
1331            
1332                // Get QUALIFIER.NAME attribute:
1333            
1334                String name = getCimNameAttribute(parser.getLine(), entry, "QUALIFIER");
1335            
1336                // Get QUALIFIER.TYPE attribute:
1337            
1338                CIMType type = getCimTypeAttribute(parser.getLine(), entry, "QUALIFIER");
1339            
1340                // Get QUALIFIER.PROPAGATED
1341            
1342                Boolean propagated = getCimBooleanAttribute(
1343            	parser.getLine(), entry, "QUALIFIER", "PROPAGATED", false, false);
1344            
1345 mike  1.23     // Get flavor oriented attributes:
1346            
1347                Uint32 flavor = getFlavor(entry, parser.getLine(), "QUALIFIER");
1348            
1349                // Get VALUE or VALUE.ARRAY element:
1350            
1351                CIMValue value;
1352            
1353                if (!getValueElement(parser, type, value) &&
1354            	!getValueArrayElement(parser, type, value))
1355                {
1356            	throw XmlSemanticError(parser.getLine(),
1357            	    "Expected VALUE or VALUE.ARRAY element");
1358                }
1359            
1360                // Expect </QUALIFIER>:
1361            
1362                expectEndTag(parser, "QUALIFIER");
1363            
1364                // Build qualifier:
1365            
1366 mike  1.23     qualifier = CIMQualifier(name, value, flavor, propagated);
1367                return true;
1368            }
1369            
1370            //------------------------------------------------------------------------------
1371            //
1372            // getQualifierElements()
1373            //
1374            //------------------------------------------------------------------------------
1375            
1376            template<class CONTAINER>
1377            void getQualifierElements(XmlParser& parser, CONTAINER& container)
1378            {
1379                CIMQualifier qualifier;
1380            
1381                while (XmlReader::getQualifierElement(parser, qualifier))
1382                {
1383            	try
1384            	{
1385            	    container.addQualifier(qualifier);
1386            	}
1387 mike  1.23 	catch (AlreadyExists&)
1388            	{
1389            	    throw XmlSemanticError(parser.getLine(), "duplicate qualifier");
1390            	}
1391                }
1392            }
1393            
1394            //------------------------------------------------------------------------------
1395            //
1396            // getPropertyElement()
1397            //
1398            //     <!ELEMENT PROPERTY (QUALIFIER*,VALUE?)>
1399            //     <!ATTLIST PROPERTY
1400            //         %CIMName;
1401            //         %ClassOrigin;
1402            //         %Propagated;
1403            //         %CIMType; #REQUIRED>
1404            //
1405            //------------------------------------------------------------------------------
1406            
1407            Boolean XmlReader::getPropertyElement(XmlParser& parser, CIMProperty& property)
1408 mike  1.23 {
1409                XmlEntry entry;
1410            
1411                if (!testStartTagOrEmptyTag(parser, entry, "PROPERTY"))
1412            	return false;
1413            
1414                Boolean empty = entry.type == XmlEntry::EMPTY_TAG;
1415            
1416                // Get PROPERTY.NAME attribute:
1417            
1418                String name = getCimNameAttribute(parser.getLine(), entry, "PROPERTY");
1419            
1420                // Get PROPERTY.CLASSORIGIN attribute:
1421            
1422                String classOrigin = 
1423            	getClassOriginAttribute(parser.getLine(), entry, "PROPERTY");
1424            
1425                // Get PROPERTY.PROPAGATED
1426            
1427                Boolean propagated = getCimBooleanAttribute(
1428            	parser.getLine(), entry, "PROPERTY", "PROPAGATED", false, false);
1429 mike  1.23 
1430                // Get PROPERTY.TYPE attribute:
1431            
1432                CIMType type = getCimTypeAttribute(parser.getLine(), entry, "PROPERTY");
1433            
1434                // Create property:
1435            
1436                CIMValue value;
1437                value.setNullValue(type, false);
1438                property = CIMProperty(
1439            	name, value, 0, String(), classOrigin, propagated);
1440            
1441                if (!empty)
1442                {
1443            	// Get qualifiers:
1444            
1445            	getQualifierElements(parser, property);
1446            
1447            	// Get value:
1448            
1449            	if (getValueElement(parser, type, value))
1450 mike  1.23 	    property.setValue(value);
1451            
1452            	expectEndTag(parser, "PROPERTY");
1453                }
1454            
1455                return true;
1456            }
1457            
1458            //------------------------------------------------------------------------------
1459            //
1460            // getArraySizeAttribute()
1461            //
1462            //     Returns true if able to get array-size. Note that array size will
1463            //     always be a positive integer.
1464            //
1465            //     <!ENTITY % ArraySize "ARRAYSIZE CDATA #IMPLIED">
1466            //
1467            //------------------------------------------------------------------------------
1468            
1469            Boolean XmlReader::getArraySizeAttribute(
1470                Uint32 lineNumber,
1471 mike  1.23     const XmlEntry& entry,
1472                const char* tagName,
1473                Uint32& value)
1474            {
1475                const char* tmp;
1476            
1477                if (!entry.getAttributeValue("ARRAYSIZE", tmp))
1478            	return false;
1479            
1480                Uint64 arraySize;
1481            
1482                if (!stringToUnsignedInteger(tmp, arraySize) || arraySize == 0)
1483                {
1484            	char message[128];
1485            	sprintf(message, "Illegal value for %s.%s", tagName, "ARRAYSIZE");
1486            	throw XmlSemanticError(lineNumber, message);
1487                }
1488            
1489                value = Uint32(arraySize);
1490                return true;
1491            }
1492 mike  1.23 
1493            //------------------------------------------------------------------------------
1494            //
1495            // getPropertyArrayElement()
1496            //
1497            //     <!ELEMENT PROPERTY.ARRAY (QUALIFIER*,VALUE.ARRAY?)>
1498            //     <!ATTLIST PROPERTY.ARRAY
1499            //             %CIMName;
1500            //             %CIMType; #REQUIRED
1501            //             %ArraySize;
1502            //             %ClassOrigin;
1503            //             %Propagated;>
1504            //
1505            //------------------------------------------------------------------------------
1506            
1507            Boolean XmlReader::getPropertyArrayElement(
1508                XmlParser& parser, 
1509                CIMProperty& property)
1510            {
1511                // Get PROPERTY element:
1512            
1513 mike  1.23     XmlEntry entry;
1514            
1515                if (!testStartTagOrEmptyTag(parser, entry, "PROPERTY.ARRAY"))
1516            	return false;
1517            
1518                Boolean empty = entry.type == XmlEntry::EMPTY_TAG;
1519            
1520                // Get PROPERTY.NAME attribute:
1521            
1522                String name = 
1523            	getCimNameAttribute(parser.getLine(), entry, "PROPERTY.ARRAY");
1524            
1525                // Get PROPERTY.TYPE attribute:
1526            
1527                CIMType type = getCimTypeAttribute(parser.getLine(), entry, "PROPERTY.ARRAY");
1528            
1529                // Get PROPERTY.ARRAYSIZE attribute:
1530            
1531                Uint32 arraySize = 0;
1532                getArraySizeAttribute(parser.getLine(), entry, "PROPERTY.ARRAY", arraySize);
1533            
1534 mike  1.23     // Get PROPERTY.CLASSORIGIN attribute:
1535            
1536                String classOrigin 
1537            	= getClassOriginAttribute(parser.getLine(), entry, "PROPERTY.ARRAY");
1538            
1539                // Get PROPERTY.ARRAY.PROPAGATED
1540            
1541                Boolean propagated = getCimBooleanAttribute(
1542            	parser.getLine(), entry, "PROPERTY.ARRAY", "PROPAGATED", false, false);
1543            
1544                // Create property:
1545            
1546                CIMValue nullValue;
1547                nullValue.setNullValue(type, true, arraySize);
1548                property = CIMProperty(
1549            	name, nullValue, arraySize, String(), classOrigin, propagated);
1550            
1551                if (!empty)
1552                {
1553            	// Get qualifiers:
1554            
1555 mike  1.23 	getQualifierElements(parser, property);
1556            
1557            	// Get value:
1558            
1559            	CIMValue value;
1560            
1561            	if (getValueArrayElement(parser, type, value))
1562            	{
1563            	    if (arraySize && arraySize != value.getArraySize())
1564            	    {
1565            		throw XmlSemanticError(parser.getLine(),
1566            		    "ARRAYSIZE attribute and value-array size are different");
1567            	    }
1568            
1569            	    property.setValue(value);
1570            	}
1571            
1572            	expectEndTag(parser, "PROPERTY.ARRAY");
1573                }
1574            
1575                return true;
1576 mike  1.23 }
1577            
1578            //------------------------------------------------------------------------------
1579            //
1580            // getHostElement()
1581            //
1582            //     <!ELEMENT HOST (#PCDATA)>
1583            //
1584            //------------------------------------------------------------------------------
1585            
1586            Boolean XmlReader::getHostElement(
1587                XmlParser& parser,
1588                String& host)
1589            {
1590                XmlEntry entry;
1591            
1592                if (!testStartTag(parser, entry, "HOST"))
1593            	return false;
1594            
1595                if (!parser.next(entry) || entry.type != XmlEntry::CONTENT)
1596                {
1597 mike  1.23 	throw XmlValidationError(parser.getLine(),
1598            	    "expected content of HOST element");
1599                }
1600            
1601                host = entry.text;
1602            
1603                expectEndTag(parser, "HOST");
1604                return true;
1605            }
1606            
1607            //------------------------------------------------------------------------------
1608            //
1609            // getNameSpaceElement()
1610            //     
1611            //     <!ELEMENT NAMESPACE EMPTY>
1612            //     <!ATTLIST NAMESPACE %CIMName;>
1613            //
1614            //------------------------------------------------------------------------------
1615            
1616            Boolean XmlReader::getNameSpaceElement(
1617                XmlParser& parser,
1618 mike  1.23     String& nameSpaceComponent)
1619            {
1620                XmlEntry entry;
1621            
1622                if (!testStartTagOrEmptyTag(parser, entry, "NAMESPACE"))
1623            	return false;
1624            
1625                Boolean empty = entry.type == XmlEntry::EMPTY_TAG;
1626            
1627                nameSpaceComponent = getCimNameAttribute(
1628            	parser.getLine(), entry, "NAMESPACE");
1629            
1630                if (!empty)
1631            	expectEndTag(parser, "NAMESPACE");
1632            
1633                return true;
1634            }
1635            
1636            //------------------------------------------------------------------------------
1637            //
1638            // getLocalNameSpacePathElement()
1639 mike  1.23 //     
1640            //     <!ELEMENT LOCALNAMESPACEPATH (NAMESPACE+)>
1641            //
1642            //------------------------------------------------------------------------------
1643            
1644            Boolean XmlReader::getLocalNameSpacePathElement(
1645                XmlParser& parser,
1646                String& nameSpace)
1647            {
1648                XmlEntry entry;
1649            
1650                if (!testStartTag(parser, entry, "LOCALNAMESPACEPATH"))
1651            	return false;
1652            
1653                String nameSpaceComponent;
1654            
1655                while (getNameSpaceElement(parser, nameSpaceComponent))
1656                {
1657            	if (nameSpace.size())
1658            	    nameSpace += '/';
1659            
1660 mike  1.23 	nameSpace += nameSpaceComponent;
1661                }
1662            
1663                if (!nameSpace.size())
1664                {
1665            	throw XmlValidationError(parser.getLine(),
1666            	    "Expected one or more NAMESPACE elements within "
1667            	    "LOCALNAMESPACEPATH element");
1668                }
1669            
1670                expectEndTag(parser, "LOCALNAMESPACEPATH");
1671                return true;
1672            }
1673            
1674            //------------------------------------------------------------------------------
1675            //
1676            // getNameSpacePathElement()
1677            //
1678            //     <!ELEMENT NAMESPACEPATH (HOST,LOCALNAMESPACEPATH)>
1679            //
1680            //------------------------------------------------------------------------------
1681 mike  1.23 
1682            Boolean XmlReader::getNameSpacePathElement(
1683                XmlParser& parser,
1684                String& host,
1685                String& nameSpace)
1686            {
1687                host.clear();
1688                nameSpace.clear();
1689            
1690                XmlEntry entry;
1691            
1692                if (!testStartTag(parser, entry, "NAMESPACEPATH"))
1693            	return false;
1694            
1695                if (!getHostElement(parser, host))
1696            	throw XmlValidationError(parser.getLine(), "expected HOST element");
1697            
1698                if (!getLocalNameSpacePathElement(parser, nameSpace))
1699                {
1700            	throw XmlValidationError(parser.getLine(), 
1701            	    "expected LOCALNAMESPACEPATH element");
1702 mike  1.23     }
1703            
1704                expectEndTag(parser, "NAMESPACEPATH");
1705            
1706                return true;
1707            }
1708            
1709            //------------------------------------------------------------------------------
1710            //
1711            // getClassNameElement()
1712            //
1713            //     <!ELEMENT CLASSNAME EMPTY>
1714            //     <!ATTLIST CLASSNAME %CIMName;>
1715            //
1716            //------------------------------------------------------------------------------
1717            
1718            Boolean XmlReader::getClassNameElement(
1719                XmlParser& parser,
1720                String& className,
1721                Boolean required)
1722            {
1723 mike  1.23     XmlEntry entry;
1724            
1725                if (!testStartTagOrEmptyTag(parser, entry, "CLASSNAME"))
1726                {
1727            	if (required)
1728            	{
1729            	    throw XmlValidationError(parser.getLine(),
1730            		"expected CLASSNAME element");
1731            	}
1732            	else
1733            	    return false;
1734                }
1735            
1736                Boolean empty = entry.type == XmlEntry::EMPTY_TAG;
1737            
1738                className = getCimNameAttribute(
1739            	parser.getLine(), entry, "CLASSNAME", true);
1740            
1741                if (!empty)
1742            	expectEndTag(parser, "CLASSNAME");
1743            
1744 mike  1.23     return true;
1745            }
1746            
1747            //------------------------------------------------------------------------------
1748            //
1749            // getValueTypeAttribute()
1750            //
1751            //     VALUETYPE (string|boolean|numeric) 'string'
1752            //
1753            //------------------------------------------------------------------------------
1754            
1755            KeyBinding::Type XmlReader::getValueTypeAttribute(
1756                Uint32 lineNumber, 
1757                const XmlEntry& entry,
1758                const char* elementName)
1759            {
1760                String tmp;
1761            
1762                if (!entry.getAttributeValue("VALUETYPE", tmp))
1763            	return KeyBinding::STRING;
1764            
1765 mike  1.23     if (String::equal(tmp, "string"))
1766            	return KeyBinding::STRING;
1767                else if (String::equal(tmp, "boolean"))
1768            	return KeyBinding::BOOLEAN;
1769                else if (String::equal(tmp, "numeric"))
1770            	return KeyBinding::NUMERIC;
1771            
1772                char buffer[MESSAGE_SIZE];
1773            
1774                sprintf(buffer, 
1775            	"Illegal value for %s.VALUETYPE attribute; "
1776            	"CIMValue must be one of \"string\", \"boolean\", or \"numeric\"",
1777            	elementName);
1778            
1779                throw XmlSemanticError(lineNumber, buffer);
1780                return KeyBinding::BOOLEAN;
1781            }
1782            
1783            //------------------------------------------------------------------------------
1784            //
1785            // getKeyValueElement()
1786 mike  1.23 //
1787            //     <!ELEMENT KEYVALUE (#PCDATA)>
1788            //     <!ATTLIST KEYVALUE
1789            //         VALUETYPE (string|boolean|numeric)  'string'>
1790            //
1791            //------------------------------------------------------------------------------
1792            
1793            Boolean XmlReader::getKeyValueElement(
1794                XmlParser& parser,
1795                KeyBinding::Type& type,
1796                String& value)
1797            {
1798                XmlEntry entry;
1799            
1800                if (!testStartTagOrEmptyTag(parser, entry, "KEYVALUE"))
1801            	return false;
1802            
1803                Boolean empty = entry.type == XmlEntry::EMPTY_TAG;
1804            
1805                type = getValueTypeAttribute(parser.getLine(), entry, "KEYVALUE");
1806            
1807 mike  1.23     value.clear();
1808            
1809                if (!empty)
1810                {
1811            	if (!parser.next(entry))
1812            	    throw XmlException(XmlException::UNCLOSED_TAGS, parser.getLine());
1813            
1814            	if (entry.type == XmlEntry::CONTENT)
1815            	    value = entry.text;
1816            	else
1817            	    parser.putBack(entry);
1818            
1819            	expectEndTag(parser, "KEYVALUE");
1820                }
1821            
1822                return true;
1823            }
1824            
1825            //------------------------------------------------------------------------------
1826            //
1827            // getKeyBindingElement()
1828 mike  1.23 //
1829            //     <!ELEMENT KEYBINDING (KEYVALUE|VALUE.REFERENCE)>
1830            //     <!ATTLIST KEYBINDING
1831            //         %CIMName;>
1832            //
1833            //------------------------------------------------------------------------------
1834            
1835            Boolean XmlReader::getKeyBindingElement(
1836                XmlParser& parser,
1837                String& name,
1838                String& value,
1839                KeyBinding::Type& type)
1840            {
1841                XmlEntry entry;
1842            
1843                if (!testStartTag(parser, entry, "KEYBINDING"))
1844            	return false;
1845            
1846                name = getCimNameAttribute(parser.getLine(), entry, "KEYBINDING");
1847            
1848                if (!getKeyValueElement(parser, type, value))
1849 mike  1.25     {
1850                    CIMReference reference;
1851            
1852                    if (!getValueReferenceElement(parser, reference))
1853                    {
1854            	    throw XmlValidationError(parser.getLine(),
1855                                  "Expected KEYVALUE or VALUE.REFERENCE element");
1856                    }
1857            
1858                    type = KeyBinding::REFERENCE;
1859                    value = reference.toString();
1860                }
1861 mike  1.23 
1862                expectEndTag(parser, "KEYBINDING");
1863                return true;
1864            }
1865            
1866            //------------------------------------------------------------------------------
1867            //
1868            // getInstanceNameElement()
1869            //
1870            //     <!ELEMENT INSTANCENAME (KEYBINDING*|KEYVALUE?|VALUE.REFERENCE?)>
1871            //     <!ATTLIST INSTANCENAME
1872            //         %ClassName;>
1873            //
1874 mike  1.25 // Note: An empty key name is used in the keyBinding when the INSTANCENAME is
1875            // specified using a KEYVALUE or a VALUE.REFERENCE.
1876 mike  1.23 //
1877            //------------------------------------------------------------------------------
1878            
1879            Boolean XmlReader::getInstanceNameElement(
1880                XmlParser& parser,
1881                String& className,
1882                Array<KeyBinding>& keyBindings)
1883            {
1884                className.clear();
1885                keyBindings.clear();
1886            
1887                XmlEntry entry;
1888            
1889                if (!testStartTagOrEmptyTag(parser, entry, "INSTANCENAME"))
1890            	return false;
1891            
1892                Boolean empty = entry.type == XmlEntry::EMPTY_TAG;
1893            
1894                className = getClassNameAttribute(parser.getLine(), entry, "INSTANCENAME");
1895            
1896 mike  1.25     if (empty)
1897 mike  1.23     {
1898 mike  1.25         return true;
1899                }
1900 mike  1.23 
1901 mike  1.25     String name;
1902                KeyBinding::Type type;
1903                String value;
1904                CIMReference reference;
1905            
1906                if (getKeyValueElement(parser, type, value))
1907                {
1908                    // Use empty key name because none was specified
1909                    keyBindings.append(KeyBinding(name, value, type));
1910                }
1911                else if (getValueReferenceElement(parser, reference))
1912                {
1913                    // Use empty key name because none was specified
1914                    type = KeyBinding::REFERENCE;
1915                    value = reference.toString();
1916                    keyBindings.append(KeyBinding(name, value, type));
1917                }
1918                else
1919                {
1920 mike  1.23 	while (getKeyBindingElement(parser, name, value, type))
1921            	    keyBindings.append(KeyBinding(name, value, type));
1922 mike  1.25     }
1923 mike  1.23 
1924 mike  1.25     expectEndTag(parser, "INSTANCENAME");
1925 mike  1.23 
1926                return true;
1927            }
1928            
1929            Boolean XmlReader::getInstanceNameElement(
1930                XmlParser& parser,
1931                CIMReference& instanceName)
1932            {
1933                String className;
1934                Array<KeyBinding> keyBindings;
1935            
1936                if (!XmlReader::getInstanceNameElement(parser, className, keyBindings))
1937            	return false;
1938            
1939                instanceName.set(String(), String(), className, keyBindings);
1940                return true;
1941            }
1942            
1943            //------------------------------------------------------------------------------
1944            //
1945            // getInstancePathElement()
1946 mike  1.23 //
1947            //     <!ELEMENT INSTANCEPATH (NAMESPACEPATH,INSTANCENAME)>
1948            //
1949            //------------------------------------------------------------------------------
1950            
1951            Boolean XmlReader::getInstancePathElement(
1952                XmlParser& parser,
1953                CIMReference& reference)
1954            {
1955                XmlEntry entry;
1956            
1957                if (!testStartTag(parser, entry, "INSTANCEPATH"))
1958            	return false;
1959            
1960                String host;
1961                String nameSpace;
1962            
1963                if (!getNameSpacePathElement(parser, host, nameSpace))
1964                {
1965            	throw XmlValidationError(parser.getLine(),
1966            	    "expected NAMESPACEPATH element");
1967 mike  1.23     }
1968            
1969                String className;
1970                Array<KeyBinding> keyBindings;
1971            
1972                if (!getInstanceNameElement(parser, className, keyBindings))
1973                {
1974            	throw XmlValidationError(parser.getLine(), 
1975            	    "expected INSTANCENAME element");
1976                }
1977            
1978                reference.set(host, nameSpace, className, keyBindings);
1979            
1980                expectEndTag(parser, "INSTANCEPATH");
1981                return true;
1982            }
1983            
1984            //------------------------------------------------------------------------------
1985            //
1986            // getLocalInstancePathElement()
1987            //
1988 mike  1.23 //     <!ELEMENT LOCALINSTANCEPATH (NAMESPACEPATH,INSTANCENAME)>
1989            //
1990            //------------------------------------------------------------------------------
1991            
1992            Boolean XmlReader::getLocalInstancePathElement(
1993                XmlParser& parser,
1994                CIMReference& reference)
1995            {
1996                XmlEntry entry;
1997            
1998                if (!testStartTag(parser, entry, "LOCALINSTANCEPATH"))
1999            	return false;
2000            
2001                String nameSpace;
2002            
2003                if (!getLocalNameSpacePathElement(parser, nameSpace))
2004                {
2005            	throw XmlValidationError(parser.getLine(),
2006            	    "expected LOCALNAMESPACEPATH element");
2007                }
2008            
2009 mike  1.23     String className;
2010                Array<KeyBinding> keyBindings;
2011            
2012                if (!getInstanceNameElement(parser, className, keyBindings))
2013                {
2014            	throw XmlValidationError(parser.getLine(), 
2015            	    "expected INSTANCENAME element");
2016                }
2017            
2018                reference.set(String(), nameSpace, className, keyBindings);
2019            
2020                expectEndTag(parser, "LOCALINSTANCEPATH");
2021                return true;
2022            }
2023            
2024            //------------------------------------------------------------------------------
2025            //
2026            // getClassPathElement()
2027            //
2028            //     <!ELEMENT CLASSPATH (NAMESPACEPATH,CLASSNAME)>
2029            //
2030 mike  1.23 //------------------------------------------------------------------------------
2031            
2032            Boolean XmlReader::getClassPathElement(
2033                XmlParser& parser,
2034                CIMReference& reference)
2035            {
2036                XmlEntry entry;
2037            
2038                if (!testStartTag(parser, entry, "CLASSPATH"))
2039            	return false;
2040            
2041                String host;
2042                String nameSpace;
2043            
2044                if (!getNameSpacePathElement(parser, host, nameSpace))
2045                {
2046            	throw XmlValidationError(parser.getLine(),
2047            	    "expected NAMESPACEPATH element");
2048                }
2049            
2050                String className;
2051 mike  1.23 
2052                if (!getClassNameElement(parser, className))
2053                {
2054            	throw XmlValidationError(parser.getLine(), 
2055            	    "expected CLASSNAME element");
2056                }
2057            
2058                reference.set(host, nameSpace, className);
2059            
2060                expectEndTag(parser, "CLASSPATH");
2061                return true;
2062            }
2063            
2064            //------------------------------------------------------------------------------
2065            //
2066            // getLocalClassPathElement()
2067            //
2068            //     <!ELEMENT LOCALCLASSPATH (LOCALNAMESPACEPATH,CLASSNAME)>
2069            //
2070            //------------------------------------------------------------------------------
2071            
2072 mike  1.23 Boolean XmlReader::getLocalClassPathElement(
2073                XmlParser& parser,
2074                CIMReference& reference)
2075            {
2076                XmlEntry entry;
2077            
2078                if (!testStartTag(parser, entry, "LOCALCLASSPATH"))
2079            	return false;
2080            
2081                String nameSpace;
2082            
2083                if (!getLocalNameSpacePathElement(parser, nameSpace))
2084                {
2085            	throw XmlValidationError(parser.getLine(),
2086            	    "expected LOCALNAMESPACEPATH element");
2087                }
2088            
2089                String className;
2090            
2091                if (!getClassNameElement(parser, className))
2092                {
2093 mike  1.23 	throw XmlValidationError(parser.getLine(), 
2094            	    "expected CLASSNAME element");
2095                }
2096            
2097                reference.set(String(), nameSpace, className);
2098            
2099                expectEndTag(parser, "LOCALCLASSPATH");
2100            
2101                return true;
2102            }
2103            
2104            //------------------------------------------------------------------------------
2105            //
2106            // getValueReferenceElement()
2107            //
2108            //     <!ELEMENT VALUE.REFERENCE (CLASSPATH|LOCALCLASSPATH|CLASSNAME|
2109            //         INSTANCEPATH|LOCALINSTANCEPATH|INSTANCENAME)>
2110            //
2111            //
2112            //------------------------------------------------------------------------------
2113            
2114 mike  1.23 Boolean XmlReader::getValueReferenceElement(
2115                XmlParser& parser,
2116                CIMReference& reference)
2117            {
2118                XmlEntry entry;
2119            
2120                if (!testStartTag(parser, entry, "VALUE.REFERENCE"))
2121            	return false;
2122            
2123                if (!parser.next(entry))
2124            	throw XmlException(XmlException::UNCLOSED_TAGS, parser.getLine());
2125            
2126                if (entry.type != XmlEntry::START_TAG && 
2127            	entry.type != XmlEntry::EMPTY_TAG)
2128                {
2129            	throw XmlValidationError(parser.getLine(), 
2130            	    "Expected one of the following start tags: "
2131            	    "CLASSPATH, LOCALCLASSPATH, CLASSNAME, INSTANCEPATH, "
2132            	    "LOCALINSTANCEPATH, INSTANCENAME");
2133                }
2134            
2135 mike  1.23     if (strcmp(entry.text, "CLASSPATH") == 0)
2136                {
2137            	parser.putBack(entry);
2138            	getClassPathElement(parser, reference);
2139                }
2140                else if (strcmp(entry.text, "LOCALCLASSPATH") == 0)
2141                {
2142            	parser.putBack(entry);
2143            	getLocalClassPathElement(parser, reference);
2144                }
2145                else if (strcmp(entry.text, "CLASSNAME") == 0)
2146                {
2147            	parser.putBack(entry);
2148            	String className;
2149            	getClassNameElement(parser, className);
2150            	reference.set(String(), String(), className);
2151                }
2152                else if (strcmp(entry.text, "INSTANCEPATH") == 0)
2153                {
2154            	parser.putBack(entry);
2155            	getInstancePathElement(parser, reference);
2156 mike  1.23     }
2157                else if (strcmp(entry.text, "LOCALINSTANCEPATH") == 0)
2158                {
2159            	parser.putBack(entry);
2160            	getLocalInstancePathElement(parser, reference);
2161                }
2162                else if (strcmp(entry.text, "INSTANCENAME") == 0)
2163                {
2164            	parser.putBack(entry);
2165            	String className;
2166            	Array<KeyBinding> keyBindings;
2167            	getInstanceNameElement(parser, className, keyBindings);
2168            	reference.set(String(), String(), className, keyBindings);
2169                }
2170            
2171                expectEndTag(parser, "VALUE.REFERENCE");
2172                return true;
2173            }
2174            
2175            //------------------------------------------------------------------------------
2176            //
2177 kumpf 1.28 // getValueReferenceArrayElement()
2178            //
2179            //     <!ELEMENT VALUE.REFARRAY (VALUE.REFERENCE*)>
2180            //
2181            //------------------------------------------------------------------------------
2182            
2183            Boolean XmlReader::getValueReferenceArrayElement(
2184                XmlParser& parser, 
2185                CIMValue& value)
2186            {
2187                XmlEntry entry;
2188            
2189                value.clear();
2190            
2191                // Get VALUE.REFARRAY open tag:
2192            
2193                if (!testStartTagOrEmptyTag(parser, entry, "VALUE.REFARRAY"))
2194            	return false;
2195            
2196                if (entry.type == XmlEntry::EMPTY_TAG)
2197                    // ATTN-RK-P3-20020220: Should the type and array size get set in
2198 kumpf 1.28         // the value even though it is null?  (See also getValueArrayElement.)
2199            	return true;
2200            
2201                // For each VALUE.REFERENCE element:
2202            
2203                Array<CIMReference> referenceArray;
2204                CIMReference reference;
2205            
2206                while (getValueReferenceElement(parser, reference))
2207                {
2208            	referenceArray.append(reference);
2209                }
2210            
2211                expectEndTag(parser, "VALUE.REFARRAY");
2212            
2213                value.set(referenceArray);
2214                return true;
2215            }
2216            
2217            //------------------------------------------------------------------------------
2218            //
2219 mike  1.23 // getPropertyReferenceElement()
2220            //
2221            //     <!ELEMENT PROPERTY.REFERENCE (QUALIFIER*,(VALUE.REFERENCE)?)>
2222            //     <!ATTLIST PROPERTY.REFERENCE
2223            //         %CIMName;
2224            //         %ReferenceClass;
2225            //         %ClassOrigin;
2226            //         %Propagated;>
2227            //
2228            //------------------------------------------------------------------------------
2229            
2230            Boolean XmlReader::getPropertyReferenceElement(
2231                XmlParser& parser, 
2232                CIMProperty& property)
2233            {
2234                XmlEntry entry;
2235            
2236                if (!testStartTagOrEmptyTag(parser, entry, "PROPERTY.REFERENCE"))
2237            	return false;
2238            
2239                Boolean empty = entry.type == XmlEntry::EMPTY_TAG;
2240 mike  1.23 
2241                // Get PROPERTY.NAME attribute:
2242            
2243                String name = getCimNameAttribute(
2244            	parser.getLine(), entry, "PROPERTY.REFERENCE");
2245            
2246                // Get PROPERTY.REFERENCECLASS attribute:
2247            
2248                String referenceClass = getReferenceClassAttribute(
2249            	parser.getLine(), entry, "PROPERTY.REFERENCE");
2250            
2251                // Get PROPERTY.CLASSORIGIN attribute:
2252            
2253                String classOrigin = 
2254            	getClassOriginAttribute(parser.getLine(), entry, "PROPERTY.REFERENCE");
2255            
2256                // Get PROPERTY.PROPAGATED
2257            
2258                Boolean propagated = getCimBooleanAttribute(parser.getLine(), entry, 
2259            	"PROPERTY.REFERENCE", "PROPAGATED", false, false);
2260            
2261 mike  1.23     // Create property:
2262            
2263                CIMValue value;
2264                value.set(CIMReference());
2265                property = CIMProperty(
2266            	name, value, 0, referenceClass, classOrigin, propagated);
2267            
2268                if (!empty)
2269                {
2270            	getQualifierElements(parser, property);
2271            
2272            	CIMReference reference;
2273            
2274            	if (getValueReferenceElement(parser, reference))
2275            	    property.setValue(reference);
2276            
2277            	expectEndTag(parser, "PROPERTY.REFERENCE");
2278                }
2279            
2280                return true;
2281            }
2282 mike  1.23 
2283            //------------------------------------------------------------------------------
2284            //
2285            // GetPropertyElements()
2286            //
2287            //------------------------------------------------------------------------------
2288            
2289            template<class CONTAINER>
2290            void GetPropertyElements(XmlParser& parser, CONTAINER& container)
2291            {
2292                CIMProperty property;
2293            
2294                while (XmlReader::getPropertyElement(parser, property) ||
2295            	XmlReader::getPropertyArrayElement(parser, property) ||
2296            	XmlReader::getPropertyReferenceElement(parser, property))
2297                {
2298            	try
2299            	{
2300            	    container.addProperty(property);
2301            	}
2302            	catch (AlreadyExists&)
2303 mike  1.23 	{
2304            	    throw XmlSemanticError(parser.getLine(), "duplicate property");
2305            	}
2306                }
2307            }
2308            
2309            //------------------------------------------------------------------------------
2310            //
2311            // getParameterElement()
2312            //
2313            //     <!ELEMENT PARAMETER (QUALIFIER*)>
2314            //     <!ATTLIST PARAMETER
2315            //         %CIMName;
2316            //         %CIMType; #REQUIRED>
2317            //
2318            //------------------------------------------------------------------------------
2319            
2320            Boolean XmlReader::getParameterElement(
2321                XmlParser& parser, 
2322                CIMParameter& parameter)
2323            {
2324 mike  1.23     XmlEntry entry;
2325            
2326                if (!testStartTagOrEmptyTag(parser, entry, "PARAMETER"))
2327            	return false;
2328            
2329                Boolean empty = entry.type == XmlEntry::EMPTY_TAG;
2330            
2331                // Get PARAMETER.NAME attribute:
2332            
2333                String name = getCimNameAttribute(parser.getLine(), entry, "PARAMETER");
2334            
2335                // Get PARAMETER.TYPE attribute:
2336            
2337                CIMType type = getCimTypeAttribute(parser.getLine(), entry, "PARAMETER");
2338            
2339                // Create parameter:
2340            
2341                parameter = CIMParameter(name, type);
2342            
2343                if (!empty)
2344                {
2345 mike  1.23 	getQualifierElements(parser, parameter);
2346            
2347            	expectEndTag(parser, "PARAMETER");
2348                }
2349            
2350                return true;
2351            }
2352            
2353            //------------------------------------------------------------------------------
2354            //
2355            // getParameterArrayElement()
2356            //
2357            //     <!ELEMENT PARAMETER.ARRAY (QUALIFIER*)>
2358            //     <!ATTLIST PARAMETER.ARRAY
2359            //         %CIMName;
2360            //         %CIMType; #REQUIRED
2361            //         %ArraySize;>
2362            //
2363            //------------------------------------------------------------------------------
2364            
2365            Boolean XmlReader::getParameterArrayElement(
2366 mike  1.23     XmlParser& parser, 
2367                CIMParameter& parameter)
2368            {
2369                XmlEntry entry;
2370            
2371                if (!testStartTagOrEmptyTag(parser, entry, "PARAMETER.ARRAY"))
2372            	return false;
2373            
2374                Boolean empty = entry.type == XmlEntry::EMPTY_TAG;
2375            
2376                // Get PARAMETER.ARRAY.NAME attribute:
2377            
2378                String name = getCimNameAttribute(
2379            	parser.getLine(), entry, "PARAMETER.ARRAY");
2380            
2381                // Get PARAMETER.ARRAY.TYPE attribute:
2382            
2383                CIMType type = getCimTypeAttribute(parser.getLine(), entry, "PARAMETER.ARRAY");
2384            
2385                // Get PARAMETER.ARRAYSIZE attribute:
2386            
2387 mike  1.23     Uint32 arraySize = 0;
2388                getArraySizeAttribute(parser.getLine(), entry, "PARAMETER.ARRAY",arraySize);
2389            
2390                // Create parameter:
2391            
2392                parameter = CIMParameter(name, type, true, arraySize);
2393            
2394                if (!empty)
2395                {
2396            	getQualifierElements(parser, parameter);
2397            
2398            	expectEndTag(parser, "PARAMETER.ARRAY");
2399                }
2400            
2401                return true;
2402            }
2403            
2404            //------------------------------------------------------------------------------
2405            //
2406            // getParameterReferenceElement()
2407            //
2408 mike  1.23 //     <!ELEMENT PARAMETER.REFERENCE (QUALIFIER*)>
2409            //     <!ATTLIST PARAMETER.REFERENCE
2410            //         %CIMName;
2411            //         %ReferenceClass;>
2412            //
2413            //------------------------------------------------------------------------------
2414            
2415            Boolean XmlReader::getParameterReferenceElement(
2416                XmlParser& parser, 
2417                CIMParameter& parameter)
2418            {
2419                XmlEntry entry;
2420            
2421                if (!testStartTagOrEmptyTag(parser, entry, "PARAMETER.REFERENCE"))
2422            	return false;
2423            
2424                Boolean empty = entry.type == XmlEntry::EMPTY_TAG;
2425            
2426                // Get PARAMETER.NAME attribute:
2427            
2428                String name = getCimNameAttribute(
2429 mike  1.23 	parser.getLine(), entry, "PARAMETER.REFERENCE");
2430            
2431                // Get PARAMETER.REFERENCECLASS attribute:
2432            
2433                String referenceClass = getReferenceClassAttribute(
2434            	parser.getLine(), entry, "PARAMETER.REFERENCE");
2435            
2436                // Create parameter:
2437            
2438                parameter = CIMParameter(name, CIMType::REFERENCE, false, 0, referenceClass);
2439            
2440                if (!empty)
2441                {
2442            	getQualifierElements(parser, parameter);
2443            	expectEndTag(parser, "PARAMETER.REFERENCE");
2444                }
2445            
2446                return true;
2447            }
2448            
2449            //------------------------------------------------------------------------------
2450 mike  1.23 //
2451 kumpf 1.26 // getParameterReferenceArrayElement()
2452            //
2453            //     <!ELEMENT PARAMETER.REFARRAY (QUALIFIER*)>
2454            //     <!ATTLIST PARAMETER.REFARRAY
2455            //         %CIMName;
2456            //         %ReferenceClass;
2457            //         %ArraySize;>
2458            //
2459            //------------------------------------------------------------------------------
2460            
2461            Boolean XmlReader::getParameterReferenceArrayElement(
2462                XmlParser& parser, 
2463                CIMParameter& parameter)
2464            {
2465                XmlEntry entry;
2466            
2467                if (!testStartTagOrEmptyTag(parser, entry, "PARAMETER.REFARRAY"))
2468            	return false;
2469            
2470                Boolean empty = entry.type == XmlEntry::EMPTY_TAG;
2471            
2472 kumpf 1.26     // Get PARAMETER.NAME attribute:
2473            
2474                String name = getCimNameAttribute(
2475            	parser.getLine(), entry, "PARAMETER.REFARRAY");
2476            
2477                // Get PARAMETER.REFERENCECLASS attribute:
2478            
2479                String referenceClass = getReferenceClassAttribute(
2480            	parser.getLine(), entry, "PARAMETER.REFARRAY");
2481            
2482                // Get PARAMETER.ARRAYSIZE attribute:
2483            
2484                Uint32 arraySize = 0;
2485                getArraySizeAttribute(parser.getLine(), entry, "PARAMETER.REFARRAY",
2486            			  arraySize);
2487            
2488                // Create parameter:
2489            
2490                parameter = CIMParameter(name, CIMType::REFERENCE, true, arraySize,
2491            			     referenceClass);
2492            
2493 kumpf 1.26     if (!empty)
2494                {
2495            	getQualifierElements(parser, parameter);
2496            	expectEndTag(parser, "PARAMETER.REFARRAY");
2497                }
2498            
2499                return true;
2500            }
2501            
2502            //------------------------------------------------------------------------------
2503            //
2504 mike  1.23 // GetParameterElements()
2505            //
2506            //------------------------------------------------------------------------------
2507            
2508            template<class CONTAINER>
2509            void GetParameterElements(XmlParser& parser, CONTAINER& container)
2510            {
2511                CIMParameter parameter;
2512            
2513                while (XmlReader::getParameterElement(parser, parameter) ||
2514            	XmlReader::getParameterArrayElement(parser, parameter) ||
2515 kumpf 1.26 	XmlReader::getParameterReferenceElement(parser, parameter) ||
2516            	XmlReader::getParameterReferenceArrayElement(parser, parameter))
2517 mike  1.23     {
2518            	try
2519            	{
2520            	    container.addParameter(parameter);
2521            	}
2522            	catch (AlreadyExists&)
2523            	{
2524            	    throw XmlSemanticError(parser.getLine(), "duplicate parameter");
2525            	}
2526                }
2527            }
2528            
2529            //------------------------------------------------------------------------------
2530            //
2531            // getQualifierDeclElement()
2532            //
2533            //     <!ELEMENT QUALIFIER.DECLARATION (SCOPE?,(VALUE|VALUE.ARRAY)?)>
2534            //     <!ATTLIST QUALIFIER.DECLARATION 
2535            //         %CIMName;               
2536            //         %CIMType; #REQUIRED
2537            //         ISARRAY (true|false) #IMPLIED
2538 mike  1.23 //         %ArraySize;
2539            //         %QualifierFlavor;>
2540            //         
2541            //------------------------------------------------------------------------------
2542            
2543            Boolean XmlReader::getQualifierDeclElement(
2544                XmlParser& parser, 
2545                CIMQualifierDecl& qualifierDecl)
2546            {
2547                XmlEntry entry;
2548            
2549                if (!testStartTagOrEmptyTag(parser, entry, "QUALIFIER.DECLARATION"))
2550            	return false;
2551            
2552                Boolean empty = entry.type == XmlEntry::EMPTY_TAG;
2553            
2554                // Get NAME attribute:
2555            
2556                String name = getCimNameAttribute(
2557            	parser.getLine(), entry, "QUALIFIER.DECLARATION");
2558            
2559 mike  1.23     // Get TYPE attribute:
2560            
2561                CIMType type = getCimTypeAttribute(
2562            	parser.getLine(), entry, "QUALIFIER.DECLARATION");
2563            
2564                // Get ISARRAY attribute:
2565            
2566 mike  1.25     Boolean isArray = getCimBooleanAttribute(
2567                    parser.getLine(), entry, "QUALIFIER.DECLARATION", "ISARRAY",
2568                    false, false); 
2569 mike  1.23 
2570                // Get ARRAYSIZE attribute:
2571            
2572                Uint32 arraySize = 0;
2573                Boolean gotArraySize = getArraySizeAttribute(parser.getLine(),
2574            	entry, "QUALIFIER.DECLARATION", arraySize);
2575            
2576                // Get flavor oriented attributes:
2577            
2578                Uint32 flavor = getFlavor(entry,parser.getLine(), "QUALIFIER.DECLARATION");
2579            
2580                // No need to look for interior elements if empty tag:
2581            
2582                Uint32 scope = CIMScope::NONE;
2583                CIMValue value;
2584            
2585                if (!empty)
2586                {
2587            	// Get the option SCOPE element:
2588            
2589            	scope = getOptionalScope(parser);
2590 mike  1.23 
2591            	// Get VALUE or VALUE.ARRAY element:
2592            
2593            	if (getValueArrayElement(parser, type, value))
2594            	{
2595            	    if (!isArray)
2596            	    {
2597            		throw XmlSemanticError(parser.getLine(),
2598            		    "VALUE.ARRAY element encountered without "
2599            		    "ISARRAY attribute");
2600            	    }
2601            
2602            	    if (arraySize && arraySize != value.getArraySize())
2603            	    {
2604            		throw XmlSemanticError(parser.getLine(),
2605            		    "VALUE.ARRAY size is not the same as "
2606            		    "ARRAYSIZE attribute");
2607            	    }
2608            	}
2609            	else if (getValueElement(parser, type, value))
2610            	{
2611 mike  1.23 	    if (isArray)
2612            	    {
2613            		throw XmlSemanticError(parser.getLine(),
2614            		    "ISARRAY attribute used but VALUE element encountered");
2615            	    }
2616            	}
2617            
2618            	// Now get the closing tag:
2619            
2620            	expectEndTag(parser, "QUALIFIER.DECLARATION");
2621                }
2622            
2623                if (value.getType() == CIMType::NONE)
2624                {
2625            	if (isArray)
2626            	    value.setNullValue(type, true, arraySize);
2627            	else
2628            	    value.setNullValue(type, false);
2629                }
2630            
2631                CIMQualifierDecl tmp(name, value, scope, flavor, arraySize);
2632 mike  1.23     qualifierDecl = CIMQualifierDecl(name, value, scope, flavor, arraySize);
2633                return true;
2634            }
2635            
2636            //------------------------------------------------------------------------------
2637            // getMethodElement()
2638            //
2639            //     <!ELEMENT METHOD (QUALIFIER*,(PARAMETER|PARAMETER.REFERENCE|
2640            //         PARAMETER.ARRAY|PARAMETER.REFARRAY)*)>
2641            //     <!ATTLIST METHOD
2642            //         %CIMName;
2643            //         %CIMType; #IMPLIED
2644            //         %ClassOrigin;
2645            //         %Propagated;>
2646            //
2647            //------------------------------------------------------------------------------
2648            
2649            Boolean XmlReader::getMethodElement(XmlParser& parser, CIMMethod& method)
2650            {
2651                XmlEntry entry;
2652            
2653 mike  1.23     if (!testStartTagOrEmptyTag(parser, entry, "METHOD"))
2654            	return false;
2655            
2656                Boolean empty = entry.type == XmlEntry::EMPTY_TAG;
2657            
2658                String name = getCimNameAttribute(parser.getLine(), entry, "PROPERTY");
2659            
2660                CIMType type = getCimTypeAttribute(parser.getLine(), entry, "PROPERTY");
2661            
2662                String classOrigin = 
2663            	getClassOriginAttribute(parser.getLine(), entry, "PROPERTY");
2664            
2665                Boolean propagated = getCimBooleanAttribute(
2666            	parser.getLine(), entry, "PROPERTY", "PROPAGATED", false, false);
2667            
2668                method = CIMMethod(name, type, classOrigin, propagated);
2669            
2670                if (!empty)
2671                {
2672 kumpf 1.26         // ATTN-RK-P2-20020219: Decoding algorithm must not depend on the
2673                    // ordering of qualifiers and parameters.
2674 mike  1.23 	getQualifierElements(parser, method);
2675            
2676            	GetParameterElements(parser, method);
2677            
2678            	expectEndTag(parser, "METHOD");
2679                }
2680            
2681                return true;
2682            }
2683            
2684            //------------------------------------------------------------------------------
2685            // getClassElement()
2686            //
2687            //     <!ELEMENT CLASS (QUALIFIER*,
2688            //         (PROPERTY|PROPERTY.ARRAY|PROPERTY.REFERENCE)*,METHOD*)>
2689            //     <!ATTLIST CLASS %CIMName; %SuperClass;>
2690            //
2691            //------------------------------------------------------------------------------
2692            
2693            Boolean XmlReader::getClassElement(XmlParser& parser, CIMClass& cimClass)
2694            {
2695 mike  1.23     XmlEntry entry;
2696            
2697                if (!testStartTag(parser, entry, "CLASS"))
2698            	return false;
2699            
2700                String name = getCimNameAttribute(parser.getLine(), entry, "CLASS");
2701            
2702                String superClass = getSuperClassAttribute(parser.getLine(), entry,"CLASS");
2703            
2704                cimClass = CIMClass(name, superClass);
2705            
2706                // Get QUALIFIER elements:
2707            
2708                getQualifierElements(parser, cimClass);
2709            
2710                // Get PROPERTY elements:
2711            
2712                GetPropertyElements(parser, cimClass);
2713            
2714                // Get METHOD elements:
2715            
2716 mike  1.23     CIMMethod method;
2717            
2718                while (getMethodElement(parser, method))
2719            	cimClass.addMethod(method);	
2720            
2721                // Get CLASS end tag:
2722            
2723                expectEndTag(parser, "CLASS");
2724            
2725                return true;
2726            }
2727            
2728            //------------------------------------------------------------------------------
2729            // getInstanceElement()
2730            //
2731            //     <!ELEMENT INSTANCE (QUALIFIER*,
2732            //         (PROPERTY|PROPERTY.ARRAY|PROPERTY.REFERENCE)*) >
2733            //     <!ATTLIST INSTANCE
2734            //         %ClassName;>
2735            //
2736            //------------------------------------------------------------------------------
2737 mike  1.23 
2738            Boolean XmlReader::getInstanceElement(
2739                XmlParser& parser, 
2740                CIMInstance& cimInstance)
2741            {
2742                XmlEntry entry;
2743            
2744                if (!testStartTag(parser, entry, "INSTANCE"))
2745            	return false;
2746            
2747                String className = getClassNameAttribute(
2748            	parser.getLine(), entry, "INSTANCE");
2749            
2750                cimInstance = CIMInstance(className);
2751            
2752                // Get QUALIFIER elements:
2753            
2754                getQualifierElements(parser, cimInstance);
2755            
2756                // Get PROPERTY elements:
2757            
2758 mike  1.23     GetPropertyElements(parser, cimInstance);
2759            
2760                // Get INSTANCE end tag:
2761            
2762                expectEndTag(parser, "INSTANCE");
2763            
2764                return true;
2765            }
2766            
2767            //------------------------------------------------------------------------------
2768 mike  1.25 // getNamedInstanceElement()
2769            //
2770            //     <!ELEMENT VALUE.NAMEDINSTANCE (INSTANCENAME,INSTANCE)>
2771            //
2772            //------------------------------------------------------------------------------
2773            
2774            Boolean XmlReader::getNamedInstanceElement(
2775                XmlParser& parser, 
2776                CIMNamedInstance& namedInstance)
2777            {
2778                XmlEntry entry;
2779            
2780                if (!testStartTag(parser, entry, "VALUE.NAMEDINSTANCE"))
2781            	return false;
2782            
2783                CIMReference instanceName;
2784            
2785                // Get INSTANCENAME elements:
2786            
2787                if (!getInstanceNameElement(parser, instanceName))
2788                {
2789 mike  1.25 	throw XmlValidationError(parser.getLine(), 
2790            	    "expected INSTANCENAME element");
2791                }
2792            
2793                CIMInstance instance;
2794            
2795                // Get INSTANCE elements:
2796            
2797                if (!getInstanceElement(parser, instance))
2798                {
2799            	throw XmlValidationError(parser.getLine(),
2800            	    "expected INSTANCE element");
2801                }
2802            
2803                // Get VALUE.NAMEDINSTANCE end tag:
2804            
2805                expectEndTag(parser, "VALUE.NAMEDINSTANCE");
2806            
2807                namedInstance.set(instanceName, instance);
2808            
2809                return true;
2810 mike  1.25 }
2811            
2812            //------------------------------------------------------------------------------
2813 mike  1.23 //
2814            // getObject()
2815            //
2816            //------------------------------------------------------------------------------
2817            
2818            void XmlReader::getObject(XmlParser& parser, CIMClass& x)
2819            {
2820                if (!getClassElement(parser, x))
2821                {
2822            	throw XmlValidationError(parser.getLine(),
2823            	    "expected CLASS element");
2824                }
2825            }
2826            
2827            //------------------------------------------------------------------------------
2828            //
2829            // getObject()
2830            //
2831            //------------------------------------------------------------------------------
2832            
2833            void XmlReader::getObject(XmlParser& parser, CIMInstance& x)
2834 mike  1.23 {
2835                if (!getInstanceElement(parser, x))
2836                {
2837            	throw XmlValidationError(parser.getLine(),
2838            	    "expected INSTANCE element");
2839                }
2840            }
2841            
2842            //------------------------------------------------------------------------------
2843            //
2844            // getObject()
2845            //
2846            //------------------------------------------------------------------------------
2847            
2848            void XmlReader::getObject(XmlParser& parser, CIMQualifierDecl& x)
2849            {
2850                if (!getQualifierDeclElement(parser, x))
2851                {
2852            	throw XmlValidationError(parser.getLine(),
2853            	    "expected QUALIFIER.DECLARATION element");
2854                }
2855 mike  1.23 }
2856            
2857            //------------------------------------------------------------------------------
2858            //
2859            // getMessageStartTag()
2860            //
2861            //------------------------------------------------------------------------------
2862            
2863            Boolean XmlReader::getMessageStartTag(
2864                XmlParser& parser, 
2865                String& id,
2866                const char*& protocolVersion)
2867            {
2868                XmlEntry entry;
2869            
2870                if (!testStartTag(parser, entry, "MESSAGE"))
2871            	return false;
2872            
2873                // Get MESSAGE.ID:
2874            
2875                if (!entry.getAttributeValue("ID", id))
2876 mike  1.23 	throw XmlValidationError(parser.getLine(), 
2877            	    "Bad or missing MESSAGE.ID attribute");
2878            
2879                // Get MESSAGE.PROTOCOLVERSION:
2880            
2881                if (!entry.getAttributeValue("PROTOCOLVERSION", protocolVersion))
2882            	throw XmlValidationError(parser.getLine(),
2883            	    "Bad or missing MESSAGE.PROTOCOLVERSION attribute");
2884            
2885                return true;
2886            }
2887            
2888            //------------------------------------------------------------------------------
2889            //
2890            // getIMethodCallStartTag()
2891            //
2892            //------------------------------------------------------------------------------
2893            
2894            Boolean XmlReader::getIMethodCallStartTag(
2895                XmlParser& parser, 
2896                const char*& name)
2897 mike  1.23 {
2898                XmlEntry entry;
2899            
2900                if (!testStartTag(parser, entry, "IMETHODCALL"))
2901            	return false;
2902            
2903                // Get IMETHODCALL.NAME attribute:
2904            
2905                if (!entry.getAttributeValue("NAME", name))
2906            	throw XmlValidationError(parser.getLine(),
2907            	    "Missing IMETHODCALL.NAME attribute");
2908            
2909                return true;
2910            }
2911            
2912            //------------------------------------------------------------------------------
2913            //
2914            // getIMethodResponseStartTag()
2915            //
2916            //------------------------------------------------------------------------------
2917            
2918 mike  1.23 Boolean XmlReader::getIMethodResponseStartTag(
2919                XmlParser& parser, 
2920                const char*& name)
2921            {
2922                XmlEntry entry;
2923            
2924                if (!testStartTag(parser, entry, "IMETHODRESPONSE"))
2925            	return false;
2926            
2927                // Get IMETHODRESPONSE.NAME attribute:
2928            
2929                if (!entry.getAttributeValue("NAME", name))
2930            	throw XmlValidationError(parser.getLine(),
2931            	    "Missing IMETHODRESPONSE.NAME attribute");
2932            
2933                return true;
2934            }
2935            
2936            //------------------------------------------------------------------------------
2937            //
2938            // getIParamValueTag()
2939 mike  1.23 //
2940            //------------------------------------------------------------------------------
2941            
2942            Boolean XmlReader::getIParamValueTag(
2943                XmlParser& parser, 
2944                const char*& name)
2945            {
2946                XmlEntry entry;
2947            
2948                if (!testStartTag(parser, entry, "IPARAMVALUE"))
2949            	return false;
2950            
2951                // Get IPARAMVALUE.NAME attribute:
2952            
2953                if (!entry.getAttributeValue("NAME", name))
2954            	throw XmlValidationError(parser.getLine(),
2955            	    "Missing IPARAMVALUE.NAME attribute");
2956            
2957                return true;
2958            }
2959            
2960 mike  1.23 //------------------------------------------------------------------------------
2961            //
2962            // getBooleanValueElement()
2963            //
2964            //     Get an elements like: "<VALUE>FALSE</VALUE>"
2965            //
2966            //------------------------------------------------------------------------------
2967            
2968            Boolean XmlReader::getBooleanValueElement(
2969                XmlParser& parser, 
2970                Boolean& result,
2971                Boolean required)
2972            {
2973                XmlEntry entry;
2974            
2975                if (!testStartTag(parser, entry, "VALUE"))
2976                {
2977            	if (required)
2978            	{
2979            	    throw XmlValidationError(parser.getLine(),
2980            		"Expected VALUE element");
2981 mike  1.23 	}
2982            	return false;
2983                }
2984            
2985                expectContentOrCData(parser, entry);
2986            
2987 mike  1.25     if (CompareNoCase(entry.text, "TRUE") == 0)
2988 mike  1.23 	result = true;
2989 mike  1.25     else if (CompareNoCase(entry.text, "FALSE") == 0)
2990 mike  1.23 	result = false;
2991                else
2992            	throw XmlSemanticError(parser.getLine(), 
2993            	    "Bad value for VALUE element: must be \"TRUE\" or \"FALSE\"");
2994            
2995                expectEndTag(parser, "VALUE");
2996            
2997                return true;
2998            }
2999            
3000            //------------------------------------------------------------------------------
3001            //
3002            // getErrorElement()
3003            //
3004            //     <!ELEMENT ERROR EMPTY>
3005            //     <!ATTLIST ERROR 
3006            //         CODE CDATA #REQUIRED
3007            //         DESCRIPTION CDATA #IMPLIED>
3008            //
3009            //------------------------------------------------------------------------------
3010            
3011 mike  1.23 Boolean XmlReader::getErrorElement(
3012                XmlParser& parser, 
3013                CIMStatusCode& code,
3014                const char*& description,
3015                Boolean required)
3016            {
3017                XmlEntry entry;
3018            
3019                if (!testStartTagOrEmptyTag(parser, entry, "ERROR"))
3020                {
3021            	if (required)
3022            	    throw XmlValidationError(parser.getLine(),"Expected ERROR element");
3023            	return false;
3024                }
3025            
3026                Boolean empty = entry.type == XmlEntry::EMPTY_TAG;
3027            
3028                // Get ERROR.CODE
3029            
3030                Uint32 tmpCode;
3031            
3032 mike  1.23     if (!entry.getAttributeValue("CODE", tmpCode))
3033            	throw XmlValidationError(
3034            	    parser.getLine(), "missing ERROR.CODE attribute");
3035            
3036                code = CIMStatusCode(tmpCode);
3037            
3038                // Get ERROR.DESCRIPTION:
3039            
3040                description = "";
3041                entry.getAttributeValue("DESCRIPTION", description);
3042            
3043                if (!empty)
3044            	expectEndTag(parser, "ERROR");
3045            
3046                return true;
3047            }
3048            
3049            
3050            //------------------------------------------------------------------------------
3051            // getObjectWithPath()
3052            //
3053 mike  1.23 // <!ELEMENT VALUE.OBJECTWITHPATH ((CLASSPATH,CLASS)|(INSTANCEPATH,INSTANCE))>
3054            //
3055            //------------------------------------------------------------------------------
3056            
3057            Boolean XmlReader::getObjectWithPath(
3058                XmlParser& parser, 
3059                CIMObjectWithPath& objectWithPath)
3060            {
3061                XmlEntry entry;
3062            
3063                if (!testStartTag(parser, entry, "VALUE.OBJECTWITHPATH"))
3064            	return false;
3065            
3066                CIMReference reference;
3067                Boolean isInstance = false;
3068            
3069                if (XmlReader::getInstancePathElement(parser, reference))
3070            	isInstance = true;
3071                else if (!XmlReader::getClassPathElement(parser, reference))
3072                {
3073            	throw XmlValidationError(parser.getLine(),
3074 mike  1.23 	    "Expected INSTANCE element");
3075                }
3076            
3077                if (isInstance)
3078                {
3079            	CIMInstance cimInstance;
3080            
3081            	if (!XmlReader::getInstanceElement(parser, cimInstance))
3082            	{
3083            	    throw XmlValidationError(parser.getLine(),
3084            		"Expected INSTANCEPATH or CLASSPATH element");
3085            	}
3086            	objectWithPath.set(reference, CIMObject(cimInstance));
3087                }
3088                else
3089                {
3090            	CIMClass cimClass;
3091            
3092            	if (!XmlReader::getClassElement(parser, cimClass))
3093            	{
3094            	    throw XmlValidationError(parser.getLine(),
3095 mike  1.23 		"Expected CLASS element");
3096            	}
3097            	objectWithPath.set(reference, CIMObject(cimClass));
3098                }
3099            
3100                expectEndTag(parser, "VALUE.OBJECTWITHPATH");
3101            
3102                return true;
3103            }
3104            
3105            //------------------------------------------------------------------------------
3106            //
3107            // <objectName>: (CLASSNAME|INSTANCENAME)
3108            //
3109            //------------------------------------------------------------------------------
3110            
3111            Boolean XmlReader::getObjectNameElement(
3112                XmlParser& parser, 
3113                CIMReference& objectName)
3114            {
3115                String className;
3116 mike  1.23 
3117                if (getClassNameElement(parser, className, false))
3118                {
3119            	objectName.set(String(), String(), className);
3120            	return true;
3121                }
3122                else if (getInstanceNameElement(parser, objectName))
3123            	return true;
3124                else
3125                {
3126            	throw XmlValidationError(parser.getLine(),
3127            	    "expected CLASSNAME or INSTANCENAME element");
3128                }
3129            
3130                return false;
3131            }
3132            
3133            //------------------------------------------------------------------------------
3134            //
3135            // <!ELEMENT OBJECTPATH (INSTANCEPATH|CLASSPATH)>
3136            //
3137 mike  1.23 //------------------------------------------------------------------------------
3138            
3139            Boolean XmlReader::getObjectPathElement(
3140                XmlParser& parser, 
3141                CIMReference& objectPath)
3142            {
3143                XmlEntry entry;
3144            
3145                if (!testStartTag(parser, entry, "OBJECTPATH"))
3146            	return false;
3147            
3148                if (getClassPathElement(parser, objectPath))
3149                {
3150            	expectEndTag(parser, "OBJECTPATH");
3151            	return true;
3152                }
3153                else if (getInstancePathElement(parser, objectPath))
3154                {
3155            	expectEndTag(parser, "OBJECTPATH");
3156            	return true;
3157                }
3158 mike  1.23     else
3159                {
3160            	throw XmlValidationError(parser.getLine(),
3161            	    "expected INSTANCEPATH or CLASSPATH element");
3162                }
3163            
3164 mike  1.24     PEGASUS_UNREACHABLE ( return false; )
3165 mike  1.25 }
3166            
3167            //------------------------------------------------------------------------------
3168            //
3169            // getEMethodCallStartTag()
3170            //
3171            //------------------------------------------------------------------------------
3172            
3173            Boolean XmlReader::getEMethodCallStartTag(
3174                XmlParser& parser, 
3175                const char*& name)
3176            {
3177                XmlEntry entry;
3178            
3179                if (!testStartTag(parser, entry, "EXPMETHODCALL"))
3180            	return false;
3181            
3182                // Get EXPMETHODCALL.NAME attribute:
3183            
3184                if (!entry.getAttributeValue("NAME", name))
3185            	throw XmlValidationError(parser.getLine(),
3186 mike  1.25 	    "Missing EXPMETHODCALL.NAME attribute");
3187            
3188                return true;
3189            }
3190            
3191            //------------------------------------------------------------------------------
3192            //
3193            // getEMethodResponseStartTag()
3194            //
3195            //------------------------------------------------------------------------------
3196            
3197            Boolean XmlReader::getEMethodResponseStartTag(
3198                XmlParser& parser, 
3199                const char*& name)
3200            {
3201                XmlEntry entry;
3202            
3203                if (!testStartTag(parser, entry, "EXPMETHODRESPONSE"))
3204            	return false;
3205            
3206                // Get EXPMETHODRESPONSE.NAME attribute:
3207 mike  1.25 
3208                if (!entry.getAttributeValue("NAME", name))
3209            	throw XmlValidationError(parser.getLine(),
3210            	    "Missing EXPMETHODRESPONSE.NAME attribute");
3211            
3212                return true;
3213            }
3214            
3215            //------------------------------------------------------------------------------
3216            //
3217            // getMethodCallStartTag()
3218            //
3219            //------------------------------------------------------------------------------
3220            
3221            Boolean XmlReader::getMethodCallStartTag(
3222                XmlParser& parser, 
3223                const char*& name)
3224            {
3225                XmlEntry entry;
3226            
3227                if (!testStartTag(parser, entry, "METHODCALL"))
3228 mike  1.25 	return false;
3229            
3230                // Get METHODCALL.NAME attribute:
3231            
3232                if (!entry.getAttributeValue("NAME", name))
3233            	throw XmlValidationError(parser.getLine(),
3234            	    "Missing METHODCALL.NAME attribute");
3235            
3236                return true;
3237            }
3238            
3239            //------------------------------------------------------------------------------
3240            //
3241            // getMethodResponseStartTag()
3242            //
3243            //------------------------------------------------------------------------------
3244            
3245            Boolean XmlReader::getMethodResponseStartTag(
3246                XmlParser& parser, 
3247                const char*& name)
3248            {
3249 mike  1.25     XmlEntry entry;
3250            
3251                if (!testStartTag(parser, entry, "METHODRESPONSE"))
3252            	return false;
3253            
3254                // Get METHODRESPONSE.NAME attribute:
3255            
3256                if (!entry.getAttributeValue("NAME", name))
3257            	throw XmlValidationError(parser.getLine(),
3258            	    "Missing METHODRESPONSE.NAME attribute");
3259            
3260                return true;
3261            }
3262            
3263            //------------------------------------------------------------------------------
3264            //
3265 kumpf 1.26 // getParamValueElement()
3266            //
3267            // <!ELEMENT PARAMVALUE (VALUE|VALUE.REFERENCE|VALUE.ARRAY|VALUE.REFARRAY)?>
3268            // <!ATTLIST PARAMVALUE
3269            //      %CIMName;
3270            //      %ParamType;>
3271 mike  1.25 //
3272            //------------------------------------------------------------------------------
3273            
3274 kumpf 1.26 Boolean XmlReader::getParamValueElement(
3275 mike  1.25     XmlParser& parser, 
3276 kumpf 1.26     CIMParamValue& paramValue)
3277 mike  1.25 {
3278                XmlEntry entry;
3279 kumpf 1.26     const char* name;
3280                CIMType type;
3281                CIMValue value;
3282 mike  1.25 
3283 kumpf 1.26     if (!testStartTagOrEmptyTag(parser, entry, "PARAMVALUE"))
3284 mike  1.25 	return false;
3285            
3286 kumpf 1.26     Boolean empty = entry.type == XmlEntry::EMPTY_TAG;
3287            
3288                // Get PARAMVALUE.NAME attribute:
3289 mike  1.25 
3290                if (!entry.getAttributeValue("NAME", name))
3291            	throw XmlValidationError(parser.getLine(),
3292            	    "Missing PARAMVALUE.NAME attribute");
3293 kumpf 1.26 
3294                // Get PARAMVALUE.PARAMTYPE attribute:
3295            
3296                type = getCimTypeAttribute(parser.getLine(), entry, "PARAMVALUE",
3297            			       "PARAMTYPE", false);
3298            
3299                if (!empty)
3300                {
3301                    // Parse VALUE.REFERENCE and VALUE.REFARRAY type
3302                    if ( (type == CIMType::REFERENCE) || (type == CIMType::NONE) )
3303                    {
3304            	    CIMReference reference;
3305            	    if (XmlReader::getValueReferenceElement(parser, reference))
3306            	    {
3307            	        value.set(reference);
3308            	        type = CIMType::REFERENCE;
3309            	    }
3310 kumpf 1.28             else if (XmlReader::getValueReferenceArrayElement(parser, value))
3311            	    {
3312            	        type = CIMType::REFERENCE;
3313            	    }
3314 kumpf 1.27             // If type==reference but no VALUE.REFERENCE found, use null value
3315 kumpf 1.26         }
3316            
3317                    // Parse non-reference value
3318                    if ( type != CIMType::REFERENCE )
3319                    {
3320            	    // If we don't know what type the value is, read it as a String
3321                        CIMType effectiveType = type;
3322                        if ( effectiveType == CIMType::NONE)
3323            	    {
3324            		effectiveType = CIMType::STRING;
3325            	    }
3326            
3327                        if ( !XmlReader::getValueArrayElement(parser, effectiveType, value) &&
3328            	         !XmlReader::getValueElement(parser, effectiveType, value) )
3329            	    {
3330            	        value.clear();    // Isn't necessary; should already be cleared
3331            	    }
3332                    }
3333            
3334                    expectEndTag(parser, "PARAMVALUE");
3335                }
3336 kumpf 1.26 
3337 kumpf 1.31     paramValue = CIMParamValue(name, value, Boolean(type!=CIMType::NONE));
3338 kumpf 1.27 
3339                return true;
3340            }
3341            
3342            //------------------------------------------------------------------------------
3343            //
3344            // getReturnValueElement()
3345            //
3346            // <!ELEMENT RETURNVALUE (VALUE|VALUE.REFERENCE)>
3347            // <!ATTLIST RETURNVALUE
3348            //      %ParamType;>
3349            //
3350            //------------------------------------------------------------------------------
3351            
3352            Boolean XmlReader::getReturnValueElement(
3353                XmlParser& parser, 
3354                CIMValue& returnValue)
3355            {
3356                XmlEntry entry;
3357                CIMType type;
3358                CIMValue value;
3359 kumpf 1.27 
3360                if (!testStartTag(parser, entry, "RETURNVALUE"))
3361            	return false;
3362            
3363                // Get RETURNVALUE.PARAMTYPE attribute:
3364                // NOTE: Array type return values are not allowed (2/20/02)
3365            
3366                type = getCimTypeAttribute(parser.getLine(), entry, "RETURNVALUE",
3367            			       "PARAMTYPE", false);
3368            
3369                // Parse VALUE.REFERENCE type
3370                if ( (type == CIMType::REFERENCE) || (type == CIMType::NONE) )
3371                {
3372                    CIMReference reference;
3373                    if (XmlReader::getValueReferenceElement(parser, reference))
3374                    {
3375                        returnValue.set(reference);
3376                        type = CIMType::REFERENCE;
3377                    }
3378                    else if (type == CIMType::REFERENCE)
3379                    {
3380 kumpf 1.27             throw XmlValidationError(parser.getLine(),
3381                            "expected VALUE.REFERENCE element");
3382                    }
3383                }
3384            
3385                // Parse non-reference return value
3386                if ( type != CIMType::REFERENCE )
3387                {
3388                    // If we don't know what type the value is, read it as a String
3389                    if ( type == CIMType::NONE)
3390                    {
3391                        type = CIMType::STRING;
3392                    }
3393            
3394                    if ( !XmlReader::getValueElement(parser, type, returnValue) )
3395                    {
3396                        throw XmlValidationError(parser.getLine(),
3397                            "expected VALUE element");
3398                    }
3399                }
3400            
3401 kumpf 1.27     expectEndTag(parser, "RETURNVALUE");
3402 mike  1.25 
3403                return true;
3404 mike  1.23 }
3405            
3406            PEGASUS_NAMESPACE_END

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2