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

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2