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

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2