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

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2