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

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

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2