SmbiosXml_libxml2.cpp

Go to the documentation of this file.
00001 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
00002  * vim:expandtab:autoindent:tabstop=4:shiftwidth=4:filetype=c:cindent:textwidth=0:
00003  *
00004  * Copyright (C) 2005 Dell Inc.
00005  *  by Michael Brown <Michael_E_Brown@dell.com>
00006  * Licensed under the Open Software License version 2.1
00007  *
00008  * Alternatively, you can redistribute it and/or modify
00009  * it under the terms of the GNU General Public License as published
00010  * by the Free Software Foundation; either version 2 of the License,
00011  * or (at your option) any later version.
00012 
00013  * This program is distributed in the hope that it will be useful, but
00014  * WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00016  * See the GNU General Public License for more details.
00017  */
00018 
00019 #ifdef EXPERIMENTAL_NOT_WORKING_DONT_EVEN_TRY_IT
00020 
00021 // compat header should always be first header if including system headers
00022 #define LIBSMBIOS_SOURCE
00023 #include "smbios/compat.h"
00024 
00025 #include <sstream>
00026 #include <iomanip>
00027 
00028 #include "SmbiosXmlImpl_xerces.h"
00029 #include "StdSmbiosXml.h"
00030 #include "../common/FactoryImpl.h"
00031 #include "../smbios/SmbiosImpl.h"
00032 #include "../common/XmlUtils.h"
00033 
00034 // message.h should be included last.
00035 #include "smbios/message.h"
00036 
00037 XERCES_CPP_NAMESPACE_USE;
00038 using namespace std;
00039 using namespace smbiosLowlevel;
00040 using namespace xmlutils;
00041 
00042 namespace smbios
00043 {
00044     //
00045     // FACTORY
00046     //
00047 
00048     class SmbiosXmlFactoryImpl: public virtual SmbiosFactoryImpl, public virtual SmbiosXmlFactory
00049     {
00050     public:
00051         static SmbiosFactory *getFactory();
00052         virtual ISmbiosTable *makeNew();
00053 
00054         using SmbiosFactoryImpl::reset;
00055         using SmbiosFactoryImpl::getSingleton;
00056     };
00057 
00058 
00059     ISmbiosTable *SmbiosXmlFactoryImpl::makeNew()
00060     {
00061         // stupid, ugly hack to supress (C4800) warning on msvc++
00062         bool strict = getParameterNum("strictValidation") ? 1 : 0;
00063 
00064         SmbiosTableXml *table = 0;
00065 
00066         std::vector<SmbiosStrategy *> strategies;
00067 
00068         if (mode == AutoDetectMode)
00069         {
00070             strategies.push_back( new SmbiosMemoryStrategy(getParameterNum("offset")) );
00071 #ifdef LIBSMBIOS_PLATFORM_WIN32
00072             strategies.push_back( new SmbiosWinGetFirmwareTableStrategy() );
00073             strategies.push_back( new SmbiosWinWMIStrategy() );
00074 #endif
00075         }
00076         else if (mode == UnitTestMode)
00077         {
00078             strategies.push_back( new SmbiosMemoryStrategy(getParameterNum("offset")) );
00079         }
00080         else
00081         {
00082         throw NotImplementedImpl(_("Unknown smbios factory mode requested"));
00083         }
00084 
00085 
00086         table = new SmbiosTableXml( 
00087                 strategies,
00088                 strict 
00089             );
00090         table->setXmlFilePath( getParameterString("xmlFile") );
00091         table->initializeWorkaround();
00092         return table;
00093     }
00094 
00095     SmbiosFactory *SmbiosXmlFactory::getFactory()
00096     {
00097         // simply forward to implementation
00098         return SmbiosXmlFactoryImpl::getFactory();
00099     }
00100 
00101     SmbiosFactory *SmbiosXmlFactoryImpl::getFactory()
00102     {
00103         if( _instance == 0 )
00104         {
00105             _instance = new SmbiosXmlFactoryImpl();
00106         }
00107         return _instance;
00108     }
00109 
00110 
00111 
00112     // if user give us a file with smbios xml information, use that
00113     // if there are any problems parsing the doc, or if they do not give us a
00114     // filename, use the built-in xml stuff.
00115     DOMDocument *getSmbiosXmlDoc( DOMBuilder *parser, std::string &xmlFile )
00116     {
00117         DOMDocument *doc = 0;
00118 
00119         try
00120         {
00121             doc = parser->parseURI( xmlFile.c_str() );
00122         }
00123         // catch std::exception and below. Anything else is likely very
00124         // serious and should pass up raw.
00125         catch( const std::exception & )
00126         {
00127             cerr << "Error during Xerces-c parsing.\n";
00128             cerr << "Falling back to builtin XML." << endl;
00129         }
00130 
00131         // fall back to built-in xml file on any kind of error
00132         if( doc == 0 )
00133         {
00134             try
00135             {
00136                 // create SAX input source
00137                 MemBufInputSource* memBufIs = new MemBufInputSource(
00138                                                   reinterpret_cast<const XMLByte*>(stdXml),
00139                                                   strlen(stdXml),
00140                                                   "standard_xml",
00141                                                   false
00142                                               );
00143 
00144                 // wrap it with a DOM input source. DOM wrapper adopts the
00145                 // SAX, no need to delete.
00146                 DOMInputSource* Is = new Wrapper4InputSource( memBufIs );
00147 
00148                 doc = parser->parse( *Is );
00149 
00150                 delete Is;
00151             }
00152             // catch std::exception and below. Anything else is likely very
00153             // serious and should pass up raw.
00154             catch( const std::exception & )
00155             {
00156                 cerr << "Error during Xerces-c parsing builin XML.\n";
00157                 cerr << "This is really bad and probably not recoverable." << endl;
00158                 throw ParseExceptionImpl("problem parsing xml file.");
00159             }
00160 
00161         }
00162 
00163         return doc;
00164     }
00165 
00166     void validateSmbiosXmlDoc( DOMDocument *doc )
00167     {
00168         if( doc )
00169         {
00170             DOMElement *root = doc->getDocumentElement();
00171 
00172             // This is pretty much the only checking we do
00173             // to ensure that the XML is valid.
00174             // maybe add some kind of schema validation in the future.
00175             string name = safeXMLChToString( root->getNodeName() );
00176             if ( ! (name == "STRUCTUREDEFS") )
00177                 throw ParseExceptionImpl("problem parsing xml file. root doc name not STRUCTUREDEFS.");
00178         }
00179     }
00180 
00181     unsigned int parseLengthStr(string size)
00182     {
00183        if (size == "BYTE")
00184            return 1;
00185        else if (size == "WORD")
00186            return 2;
00187        else if (size == "DWORD")
00188            return 4;
00189        else if (size == "QWORD")
00190            return 8;
00191        else 
00192            return strtol(size.c_str(), NULL, 0);
00193 
00194        throw ParseExceptionImpl("Error parsing length information xml file. Invalid value." );
00195        return 0;
00196     }
00197 
00198     void verifyElementAttr( DOMElement *element, const string elementName, const string value )
00199     {
00200         string xmlValue = safeGetAttribute( element, elementName );
00201         if( value != xmlValue )
00202             throw ParseExceptionImpl("could not verify element attribute.");
00203     }
00204 
00205     // sneaky... :-)
00206     void verifyElementAttr( DOMElement *element, const string elementName, unsigned int size )
00207     {
00208         string xmlValue = safeGetAttribute( element, elementName );
00209         if( size != parseLengthStr(xmlValue) )
00210             throw ParseExceptionImpl("could not verify element attribute was correct size.");
00211     }
00212 
00213     int getTypeForString( DOMDocument *doc, const string searchForDesc )
00214     {
00215         // find element with this description
00216         DOMElement *elem = findElement( doc->getDocumentElement(), "STRUCTURE", "description", searchForDesc );
00217 
00218         // return the type as an INT.
00219         return strtol( safeGetAttribute( elem, "type" ).c_str(), 0, 0);
00220     }
00221 
00222     const string getStringForType(const DOMDocument *doc, const int searchForType )
00223     {
00224         // find matching element
00225         DOMElement *elem = 0;
00226         try
00227         {
00228             elem = findElementWithNumericAttr( doc->getDocumentElement(), "STRUCTURE", "type", searchForType);
00229         }
00230         catch(const NotFound &)
00231         {
00232             elem = findElement( doc->getDocumentElement(), "STRUCTURE", "type", "unknown");
00233         }
00234 
00235         // extract the description
00236         return safeGetAttribute( elem, "description");
00237     }
00238 
00239     //
00240     // MEMBER FUNCTIONS
00241     //
00242 
00243     // CONSTRUCTORS
00244     //
00245     // REGULAR CONSTRUCTOR
00246     SmbiosTableXml::SmbiosTableXml()
00247             : SmbiosTable(), xmlFile(""), parser(0), doc(0), xmlInitialized(false)
00248     {
00249         setXmlFilePath(xmlFile);
00250     }
00251 
00252     SmbiosTableXml::SmbiosTableXml(std::vector<SmbiosStrategy *> initStrategyList, bool strictValidation)
00253             : SmbiosTable(initStrategyList, strictValidation), xmlFile(""), parser(0), doc(0), xmlInitialized(false)
00254     {
00255         setXmlFilePath(xmlFile);
00256     }
00257 
00258     // DESTRUCTOR
00259     SmbiosTableXml::~SmbiosTableXml()
00260     {
00261         if(parser)
00262         {
00263             parser->release();
00264             parser = 0;
00265             doc = 0;
00266         }
00267         if( xmlInitialized )
00268             XMLPlatformUtils::Terminate();
00269     }
00270 
00271     ISmbiosItem &SmbiosTableXml::makeItem(const void *header) const
00272     {
00273         // not exception safe yet.
00274         const smbios_structure_header *structure =
00275             reinterpret_cast<const smbios_structure_header *>(header);
00276         SmbiosItemXml *item = new SmbiosItemXml( structure );
00277         item->setXmlFilePath( xmlFile, doc );
00278         if( ! initializing )
00279         {
00280             dynamic_cast<SmbiosItem*>(item)->fixup( workaround.get() );
00281         }
00282         return *item;
00283     }
00284 
00285 
00286     // good exception guarantee.
00287     // either we allocate new stuff, the new stuff validates, and we
00288     // set ourselves up with the new stuff, or we keep whatever we
00289     // used to have and raise the exception.
00290     void SmbiosTableXml::setXmlFilePath( std::string newFile )
00291     {
00292         try
00293         {
00294             // Initialize XML DOM subsystem
00295             if( ! xmlInitialized )
00296                 XMLPlatformUtils::Initialize();
00297 
00298             xmlInitialized = true;
00299 
00300             DOMBuilder *newParser = getParser();
00301             DOMDocument *newdoc = getSmbiosXmlDoc( newParser, newFile );
00302             validateSmbiosXmlDoc( newdoc );
00303             // if we get to this point, that means the
00304             // new doc exists and is valid.
00305 
00306             // clean up any old messes we may have laying around.
00307             // release old parser if one is allocated.
00308             DOMBuilder *oldParser = parser;
00309 
00310             parser = newParser;
00311             xmlFile = newFile;
00312             doc = newdoc;
00313 
00314             if( oldParser )
00315             {
00316                 oldParser->release(); //hopefully this doesn't throw, or we have a problem. :-)
00317             }
00318         }
00319         catch(const XMLException &toCatch)
00320         {
00321             cerr << "Error during Xerces-c Initialization.\n"
00322             << "  Exception message:"
00323             << toCatch.getMessage() << endl;
00324             throw ParseExceptionImpl("xerces initialization failed.");
00325         }
00326     }
00327 
00328     const DOMDocument *SmbiosTableXml::getXmlDoc() const
00329     {
00330         return doc;
00331     }
00332 
00333     int SmbiosTableXml::getTypeForString( const string searchForDesc ) const
00334     {
00335         return smbios::getTypeForString( doc, searchForDesc );
00336     }
00337 
00338     // only used by unit test code.
00339     const string SmbiosTableXml::getStringForType( const int searchForType ) const
00340     {
00341         return smbios::getStringForType( doc, searchForType );
00342     }
00343 
00344     // we were passed a string. convert to a number by looking up the
00345     // type for this string in the XML File
00346     // forward to base class operator[]
00347     SmbiosTable::iterator SmbiosTableXml::operator[] (const string &searchFor)
00348     {
00349         int type = getTypeForString( searchFor );
00350         return SmbiosTable::iterator (this, type);
00351     }
00352 
00353     // we were passed a string. convert to a number by looking up the
00354     // type for this string in the XML File
00355     // forward to base class operator[]
00356     SmbiosTable::const_iterator SmbiosTableXml::operator[](const string &searchFor) const
00357     {
00358         // this == const SmbiosTable();
00359         int type = getTypeForString( searchFor );
00360         return SmbiosTable::const_iterator (this, type);
00361     }
00362 
00363 
00364     //
00365     // SmbiosItemXml members
00366     //
00367     void SmbiosItemXml::setXmlFilePath( const std::string newFile,  XERCES_CPP_NAMESPACE_QUALIFIER DOMDocument *newDoc )
00368     {
00369         xmlFile = newFile;
00370         doc = newDoc;
00371     }
00372 
00373     u8 SmbiosItemXml::getU8( const string fieldName ) const
00374     {
00375         DOMElement *element = 0;
00376 
00377         // get the element corresponding to the STRUCTURE user specified
00378         DOMElement *Structure = findElementWithNumericAttr( doc->getDocumentElement(), "STRUCTURE", "type", getType() );
00379         element = findElement( Structure, "FIELD", "name", fieldName );
00380 
00381         // Is this the correct length?
00382         verifyElementAttr( element, "length", 1 );
00383 
00384         // call parent method to get actual data. :-)
00385         return SmbiosItem::getU8( getNumberFromXmlAttr(element, "offset", 0) );
00386     }
00387 
00388     u16 SmbiosItemXml::getU16( const string fieldName ) const
00389     {
00390         DOMElement *element = 0;
00391 
00392         // get the element corresponding to the STRUCTURE user specified
00393         DOMElement *Structure = findElementWithNumericAttr( doc->getDocumentElement(), "STRUCTURE", "type", getType() );
00394         element = findElement( Structure, "FIELD", "name", fieldName );
00395 
00396         // Is this the correct length?
00397         verifyElementAttr( element, "length", 2 );
00398 
00399         // call parent method to get actual data. :-)
00400         return SmbiosItem::getU16( getNumberFromXmlAttr(element, "offset", 0) );
00401     }
00402 
00403     u32 SmbiosItemXml::getU32( const string fieldName ) const
00404     {
00405         DOMElement *element = 0;
00406 
00407         // get the element corresponding to the STRUCTURE user specified
00408         DOMElement *Structure = findElementWithNumericAttr( doc->getDocumentElement(), "STRUCTURE", "type", getType() );
00409         element = findElement( Structure, "FIELD", "name", fieldName );
00410 
00411         // Is this the correct length?
00412         verifyElementAttr( element, "length", 4 );
00413 
00414         // call parent method to get actual data. :-)
00415         return SmbiosItem::getU32( getNumberFromXmlAttr(element, "offset", 0) );
00416     }
00417 
00418     u64 SmbiosItemXml::getU64( const string fieldName ) const
00419     {
00420         DOMElement *element = 0;
00421 
00422         // get the element corresponding to the STRUCTURE user specified
00423         DOMElement *Structure = findElementWithNumericAttr( doc->getDocumentElement(), "STRUCTURE", "type", getType() );
00424         element = findElement( Structure, "FIELD", "name", fieldName );
00425 
00426         // Is this the correct length?
00427         verifyElementAttr( element, "length", 8 );
00428 
00429         // call parent method to get actual data. :-)
00430         return SmbiosItem::getU64( getNumberFromXmlAttr(element, "offset", 0) );
00431     }
00432 
00433     u32 SmbiosItemXml::getBitfield( const string field, const string bitField) const
00434     {
00435         DOMElement *bitElement = 0;
00436         DOMElement *fieldElement = 0;
00437 
00438         try
00439         {
00440             DOMElement *Structure = findElementWithNumericAttr( doc->getDocumentElement(), "STRUCTURE", "type", getType() );
00441             fieldElement = findElement( Structure, "FIELD", "name", field );
00442             bitElement = findElement( fieldElement, "BITS", "name", bitField );
00443         }
00444         catch (const NotFound & )
00445         {
00446             throw ParseExceptionImpl("could not fine bitfield name in xml file.");
00447         }
00448 
00449         // Is this the correct length?
00450         string length = safeGetAttribute( fieldElement, "length" );
00451         unsigned int lengthVal = 0;
00452         lengthVal = parseLengthStr(length);
00453 
00454         // call parent method to get actual data. :-)
00455         return SmbiosItem::getBitfield(
00456                    getNumberFromXmlAttr(fieldElement, "offset", 0),
00457                    lengthVal,
00458                    getNumberFromXmlAttr(bitElement, "lsb", 0),
00459                    getNumberFromXmlAttr(bitElement, "msb", 0)
00460                );
00461     }
00462 
00463     const char* SmbiosItemXml::getString( const string fieldName ) const
00464     {
00465         DOMElement *element = 0;
00466 
00467         // get the element corresponding to the STRUCTURE user specified
00468         DOMElement *Structure = findElementWithNumericAttr( doc->getDocumentElement(), "STRUCTURE", "type", getType() );
00469         element = findElement( Structure, "FIELD", "name", fieldName );
00470 
00471         // Is this the correct length?
00472         verifyElementAttr( element, "length", 1 );
00473 
00474         // Is this an actual string?
00475         verifyElementAttr( element, "usage", "STRING" );
00476 
00477         // call parent method to get actual data. :-)
00478         return SmbiosItem::getString( getNumberFromXmlAttr(element, "offset", 0) );
00479     }
00480 
00481 
00482     void printStructureField( std::ostream &cout, const DOMNode *node, const ISmbiosItem &item )
00483     {
00484         std::ios::fmtflags old_opts = cout.flags ();
00485         try
00486         {
00487             unsigned int length = parseLengthStr(safeGetAttribute( node, "length" ));
00488             string strOffset = safeGetAttribute( node, "offset" );
00489             unsigned int offset = strtol( strOffset.c_str(), 0, 0 );
00490 
00491             string usage = safeGetAttribute( node, "usage" );
00492             if (usage == "STRING")
00493             {
00494                 try
00495                 {
00496                     cout << item.getString( offset );
00497                 }
00498                 catch(const StringUnavailable &)
00499                 {
00500                 }
00501             }
00502             else
00503             {
00504                 cout << hex << "0x";
00505                 for(unsigned int i=0;i<length; i++)
00506                 {
00507                     cout << setfill('0') << setw(2) << 
00508                         static_cast<int>(item.getU8(offset + length - i - 1));
00509                 }
00510             }
00511         }
00512         catch( const std::exception & )
00513         {
00514             cout.flags (old_opts);
00515             throw;
00516         }
00517         cout.flags (old_opts);
00518     }
00519 
00520     std::ostream &SmbiosItemXml::streamify( std::ostream &cout ) const
00521     {
00522         // If we don't have a ref to XML file, we cannot find this info
00523         if( ! doc )
00524             return SmbiosItem::streamify(cout);
00525 
00526         if (header == 0)
00527         {
00528             // TODO: this should be an exception...
00529             cout << "operator << on an uninitialized SmbiosItem!";
00530             return cout;
00531         }
00532 
00533         std::ios::fmtflags old_opts = cout.flags ();
00534 
00535         DOMElement *Structure = 0;
00536         cout << "DMI BLOCK: " << flush;
00537         try
00538         {
00539             cout << smbios::getStringForType( doc, getType() ) << endl;;
00540             Structure = findElementWithNumericAttr( doc->getDocumentElement(), "STRUCTURE", "type", getType());
00541         }
00542         catch ( const NotFound & )
00543         {
00544             Structure = findElement(doc->getDocumentElement(), "STRUCTURE", "type", "unknown");
00545         }
00546 
00547         XMLCh *tagName = X("FIELD"); // NEED TO 'release' !!!
00548         DOMNodeList *fieldList = Structure->getElementsByTagName(tagName);
00549         XMLString::release(&tagName);
00550 
00551         if( !fieldList )
00552             return cout;
00553 
00554         int length = fieldList->getLength();
00555         for( int index = 0; index < length; ++index )
00556         {
00557             DOMNode *node = fieldList->item( index );
00558             if( node->getNodeType() == DOMNode::ELEMENT_NODE )
00559             {
00560                 ostringstream tmpBuf("");
00561                 tmpBuf << "\t";
00562                 tmpBuf << safeGetAttribute( node, "name" );
00563                 tmpBuf << ": \t" ;
00564                 try
00565                 {
00566                     printStructureField( tmpBuf, node, *this );
00567                 }
00568                 catch(const exception &)
00569                 {
00570                     continue;
00571                 }
00572                 cout << tmpBuf.str() << endl;
00573             }
00574         }
00575 
00576         cout.flags (old_opts);
00577         return cout;
00578     }
00579 
00580     std::ostream &SmbiosTableXml::streamify(ostream & cout) const
00581     {
00582         cout << "\nSMBIOS table " << endl;
00583         cout << "\tversion    : ";
00584         cout << static_cast<int>(table_header.major_ver) << ".";
00585         cout << static_cast<int>(table_header.minor_ver) << endl;
00586         cout << hex ;
00587         cout << "\taddress    : " << table_header.table_address << endl;
00588         cout << dec;
00589         cout << "\tlength     : " << table_header.table_length << endl;
00590         cout << "\tnum structs: " << table_header.table_num_structs << endl;
00591         cout << endl;
00592 
00593         SmbiosTable::const_iterator position = begin();
00594         while (position != end())
00595         {
00596              cout << *position << endl;
00597             ++position;
00598         }
00599         return cout;
00600     }
00601 
00602 
00603 /******************************************************************************
00604   *       XML OUTPUT FUNCTIONS                                                *
00605   ****************************************************************************/
00606     bool isBitSet(const ISmbiosItem *itemPtr, unsigned int offset, unsigned int bitToTest)
00607     {
00608         bool retval = false;
00609 
00610         unsigned int byte = bitToTest / 8;
00611         u8 fieldValue = itemPtr->getU8( offset + byte );
00612         if (fieldValue & (1 << (bitToTest%8)))
00613             retval = true;
00614 
00615         return retval;
00616     }
00617 
00618     void parseStructureField (DOMElement *inNode, const ISmbiosItem &itemRef,std::ostream &cout) 
00619     { 
00620         string strOffset = safeGetAttribute( inNode, "offset" );
00621         unsigned int offset = strtol( strOffset.c_str(), 0, 0 );
00622 
00623         XMLCh *bitName = X("BITS"); // NEED TO 'release' !!!
00624         DOMNodeList *bitList = inNode->getElementsByTagName(bitName);
00625         XMLString::release(&bitName);
00626 
00627         unsigned int size = parseLengthStr(safeGetAttribute (inNode ,"length"));
00628 
00629         // if whole-FIELD is ENUM, short-circuit parsing below
00630         string type= safeGetAttribute(inNode ,"usage");
00631         bool isEnum = false;
00632         bool isBitfield = false;
00633         if( type == "ENUM" )
00634             isEnum = true;
00635         if( type == "BITFIELD" )
00636             isBitfield = true;
00637 
00638         cout << "    " << BeginTag(safeGetAttribute( inNode, "name" )) << endl;
00639         cout << "        " << BeginTag("raw_data");
00640         printStructureField(cout, inNode, itemRef);
00641         cout << EndTag("raw_data") << endl;
00642 
00643         if(bitList->getLength() && (isBitfield || isEnum))
00644             cout << "        " << BeginTag("interpreted_data") << endl;
00645 
00646 
00647         for( unsigned int index = 0; index < bitList->getLength(); ++index )
00648         {
00649             std::ios::fmtflags old_opts = cout.flags ();
00650             DOMNode *node = bitList->item( index );
00651             if( node->getNodeType() != DOMNode::ELEMENT_NODE )
00652                 continue;
00653 
00654             string lsbStr= safeGetAttribute(node ,"lsb");
00655             if(lsbStr == "") lsbStr = "0";
00656             unsigned int lsb = strtoul(lsbStr.c_str(), NULL, 0);
00657 
00658             string msbStr = safeGetAttribute(node ,"msb");
00659             unsigned int msb = 0;
00660             if(msbStr == "")
00661                 msb = size * 8 - 1;
00662             else
00663                 msb = strtoul(msbStr.c_str(), NULL, 0);
00664 
00665             string type= safeGetAttribute(node ,"type");
00666             if( type == "ENUM" || isEnum )
00667             {
00668                 u32 bitValue = itemRef.getBitfield (offset, size, lsb, msb );
00669 
00670                 cout << "            " << BeginTag("EnumValue");
00671                 try
00672                 {
00673                     DOMNode *mapValue = findElementWithNumericAttr( castNode2Element(node), "MAP", "value", bitValue );
00674                     cout << safeGetAttribute(mapValue, "meaning");
00675                 }
00676                 catch(const NotFound &)
00677                 {
00678                     cout << "UNKNOWN enumeration value: " << bitValue;
00679                 }
00680 
00681                 cout << EndTag("EnumValue") << endl;
00682             }
00683             else if (isBitfield)
00684             {
00685                 if( lsb == msb )
00686                 {
00687                     if(isBitSet(&itemRef, offset, lsb))
00688                     {
00689                         cout << "            " << BeginTag("EnabledBit");
00690                         cout << safeGetAttribute( node, "name" );
00691                         cout << EndTag("EnabledBit") << endl;
00692                     }
00693                     else
00694                     {
00695                         cout << "            " << BeginTag("DisabledBit");
00696                         cout << safeGetAttribute( node, "name" );
00697                         cout << EndTag("DisabledBit") << endl;
00698                     }
00699                 }
00700                 else
00701                 {
00702                         cout << "            " << BeginTag("MultiBits");
00703                         cout << "0x" << hex << static_cast<long>(itemRef.getBitfield(offset, size, lsb, msb));
00704                         cout << EndTag("MultiBits") << endl;
00705                 }
00706             }
00707             else
00708             {
00709                 // normal value that may have 'default' data. try to look 
00710                 // up default name, fall back to just printing value
00711                 u32 bitValue = itemRef.getBitfield (offset, size, lsb, msb );
00712                 try
00713                 {
00714                     DOMNode *mapValue = findElementWithNumericAttr( castNode2Element(node), "MAP", "value", bitValue );
00715                     cout << "        " << BeginTag("interpreted_data") << endl;
00716                     cout << "            " << BeginTag("RawValueMeaning");
00717                     cout << safeGetAttribute(mapValue, "meaning");
00718                     cout << EndTag("RawValueMeaning") << endl;
00719                     cout << "        " << EndTag("interpreted_data") << endl;
00720                 }
00721                 catch(const NotFound &)
00722                 {
00723                 }
00724             }
00725             cout.flags (old_opts);
00726         }
00727 
00728         if(bitList->getLength() && (isBitfield || isEnum))
00729             cout << "        " << EndTag("interpreted_data") << endl;
00730 
00731         cout << "    " << EndTag(safeGetAttribute( inNode, "name" )) << endl;
00732     } 
00733 
00734      // this will output one structure at a time as passed to std out
00735     std::ostream &toXmlString(const ISmbiosItem &item,const DOMDocument *doc, DOMDocument *oDoc, std::ostream &cout)
00736     {
00737         (void)(oDoc);
00738 
00739         std::ios::fmtflags old_opts = cout.flags ();
00740 
00741         // If we don't have a ref to XML file, we cannot find this info
00742         if( ! doc )
00743             return cout;
00744 
00745         DOMElement *Structure = 0;
00746         try
00747         { // find the structure TAG in std_xml to begin iteration
00748             Structure = findElementWithNumericAttr(doc->getDocumentElement(), "STRUCTURE", "type", item.getType());
00749         }
00750         catch (const NotFound &)
00751         {
00752             Structure = findElement(doc->getDocumentElement(), "STRUCTURE", "type", "unknown");
00753         }
00754 
00755         cout << BeginTag(smbios::getStringForType(doc, item.getType())) << endl;
00756 
00757         XMLCh *tagName = X("FIELD"); // NEED TO 'release' !!!
00758         DOMNodeList *fieldList = Structure->getElementsByTagName(tagName);
00759         XMLString::release(&tagName);
00760 
00761         // in this loop we will iterate through the Structures's  subtags as attributes
00762         for( unsigned int index = 0; index < fieldList->getLength(); ++index )
00763         {
00764             DOMNode *node = fieldList->item( index );
00765             if( node->getNodeType() == DOMNode::ELEMENT_NODE )
00766             {
00767                 ostringstream tmpBuf("");
00768                 try
00769                 {
00770                     parseStructureField(castNode2Element(node),item,tmpBuf);
00771                 }
00772                 catch(const exception &)
00773                 {
00774                     continue;
00775                 }
00776                 cout << tmpBuf.str();
00777             }
00778         }
00779 
00780         // close root tag
00781         cout << EndTag(smbios::getStringForType( doc, item.getType() ) ) << endl;
00782 
00783         cout.flags (old_opts);
00784         return cout;
00785 
00786     } 
00787 
00788 
00789     /******************
00790         TABLE OUTPUT
00791       ****************/
00792 
00793      // here is where we will do the XML output
00794     std::ostream &toXmlString(const ISmbiosTable &table, ostream & cout)
00795     {
00796         SmbiosTable::const_iterator position = table.begin();
00797         const DOMDocument *doc = dynamic_cast<const SmbiosTableXml *>(& table)->getXmlDoc();
00798         while (position != table.end())
00799         {
00800             toXmlString(*position, doc, 0, cout);
00801             ++position;
00802         }
00803         return cout;
00804      }
00805    
00806 
00807 }
00808 #endif /* experimental */

Generated on Tue Jan 17 02:59:08 2006 for SMBIOS Library by  doxygen 1.4.6