OW_CIMtoXML.cpp

Go to the documentation of this file.
00001 /*******************************************************************************
00002 * Copyright (C) 2001-2004 Vintela, Inc. All rights reserved.
00003 *
00004 * Redistribution and use in source and binary forms, with or without
00005 * modification, are permitted provided that the following conditions are met:
00006 *
00007 *  - Redistributions of source code must retain the above copyright notice,
00008 *    this list of conditions and the following disclaimer.
00009 *
00010 *  - Redistributions in binary form must reproduce the above copyright notice,
00011 *    this list of conditions and the following disclaimer in the documentation
00012 *    and/or other materials provided with the distribution.
00013 *
00014 *  - Neither the name of Vintela, Inc. nor the names of its
00015 *    contributors may be used to endorse or promote products derived from this
00016 *    software without specific prior written permission.
00017 *
00018 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
00019 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00020 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00021 * ARE DISCLAIMED. IN NO EVENT SHALL Vintela, Inc. OR THE CONTRIBUTORS
00022 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00023 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00024 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00025 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00026 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00027 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00028 * POSSIBILITY OF SUCH DAMAGE.
00029 *******************************************************************************/
00030 
00036 #include "OW_config.h"
00037 #include "OW_CIMtoXML.hpp"
00038 #include "OW_String.hpp"
00039 #include "OW_XMLEscape.hpp"
00040 #include "OW_Assertion.hpp"
00041 #include "OW_StringStream.hpp"
00042 #include "OW_CIMParamValue.hpp"
00043 #include "OW_CIMNameSpace.hpp"
00044 #include "OW_CIMException.hpp"
00045 #include "OW_CIMQualifierType.hpp"
00046 #include "OW_CIMFlavor.hpp"
00047 #include "OW_CIMObjectPath.hpp"
00048 #include "OW_CIMProperty.hpp"
00049 #include "OW_CIMClass.hpp"
00050 #include "OW_CIMInstance.hpp"
00051 #include "OW_CIMValue.hpp"
00052 #include "OW_CIMScope.hpp"
00053 #include "OW_CIMDateTime.hpp"
00054 #include "OW_CIMUrl.hpp"
00055 #include "OW_CIMQualifier.hpp"
00056 #include "OW_CIMMethod.hpp"
00057 #include "OW_CIMParameter.hpp"
00058 #ifdef OW_HAVE_OSTREAM
00059 #include <ostream>
00060 #else
00061 #include <iostream>
00062 #endif
00063 #include <algorithm>
00064 
00065 #include <cfloat> // for DBL_MANT_DIG and FLT_RADIX
00066 
00067 #ifdef OW_WIN32
00068 #define SNPRINTF _snprintf
00069 #else
00070 #define SNPRINTF snprintf
00071 #endif
00072 
00073 namespace OW_NAMESPACE
00074 {
00075 
00076 using std::ostream;
00078 void CIMNameSpacetoXML(CIMNameSpace const& ns, ostream& ostr)
00079 {
00080    ostr
00081       << "<NAMESPACEPATH><HOST>"
00082       << XMLEscape(ns.getHostUrl().getHost())
00083       << "</HOST>";
00084    LocalCIMNameSpacetoXML(ns, ostr);
00085    
00086    ostr << "</NAMESPACEPATH>";
00087 }
00089 void LocalCIMNameSpacetoXML(CIMNameSpace const& ns, ostream& ostr)
00090 {
00091    String name = ns.getNameSpace();
00092    if (name.empty())
00093    {
00094       OW_THROWCIMMSG(CIMException::FAILED, "Namespace not set");
00095    }
00096    ostr << "<LOCALNAMESPACEPATH>";
00097    for (;;)
00098    {
00099       size_t index = name.indexOf('/');
00100       if (index == String::npos)
00101       {
00102          break;
00103       }
00104       if (index != 0)
00105       {
00106          ostr
00107             << "<NAMESPACE NAME=\""
00108             << XMLEscape(name.substring(0, index))
00109             << "\"></NAMESPACE>";
00110       }
00111       name = name.substring(index+1);
00112    }
00113    
00114    ostr
00115       << "<NAMESPACE NAME=\""
00116       << XMLEscape(name)
00117       << "\"></NAMESPACE>"
00118       << "</LOCALNAMESPACEPATH>";
00119 }
00121 void CIMtoXML(CIMQualifierType const& cqt, ostream& ostr)
00122 {
00123    CIMFlavor fv;
00124    if (cqt.getName().empty())
00125    {
00126       OW_THROWCIMMSG(CIMException::FAILED, "qualifierType must have a name");
00127    }
00128    //
00129    // If type isn't set then the CIMOM has stored a qualifier
00130    // thats bad and an exception is generated
00131    //
00132    if (!cqt.getDataType())
00133    {
00134       String msg("QualifierType (");
00135       msg += cqt.getName();
00136       msg += ") does not have a data type set";
00137       OW_THROWCIMMSG(CIMException::FAILED, msg.c_str());
00138    }
00139    ostr
00140       << "<QUALIFIER.DECLARATION NAME=\""
00141       << cqt.getName()
00142       << "\" TYPE=\"";
00143    CIMtoXML(cqt.getDataType(), ostr);
00144    ostr << "\" ";
00145    if (cqt.getDataType().isArrayType())
00146    {
00147       ostr << "ISARRAY=\"true\" ";
00148    }
00149    else
00150    {
00151       ostr << "ISARRAY=\"false\" ";
00152    }
00153    fv = CIMFlavor(CIMFlavor::ENABLEOVERRIDE);
00154    if (cqt.hasFlavor(fv))
00155    {
00156       // NOT NECESSARY, default is TRUE
00157    }
00158    else
00159    {
00160       fv = CIMFlavor(CIMFlavor::DISABLEOVERRIDE);
00161       if (cqt.hasFlavor(fv))
00162       {
00163          CIMtoXML(fv, ostr);
00164          ostr << "=\"false\" ";
00165       }
00166    }
00167    fv = CIMFlavor(CIMFlavor::TOSUBCLASS);
00168    if (cqt.hasFlavor(fv))
00169    {
00170       // NOT NECESSARY, default is TRUE
00171    }
00172    else
00173    {
00174       fv = CIMFlavor(CIMFlavor::RESTRICTED);
00175       if (cqt.hasFlavor(fv))
00176       {
00177          CIMtoXML(fv, ostr);
00178          ostr << "=\"false\" ";
00179       }
00180    }
00181    fv = CIMFlavor(CIMFlavor::TRANSLATE);
00182    if (cqt.hasFlavor(fv))
00183    {
00184       CIMtoXML(fv, ostr);
00185       ostr << "=\"true\" ";
00186    }
00187    //
00188    //else
00189    // NOT NECESSARY, default is FALSE
00190    ostr << "><SCOPE ";
00191    //
00192    // Write scope information
00193    //
00194    String scope;
00195    bool scopeWritten = false;
00196    bool any = cqt.hasScope(CIMScope(CIMScope::ANY));
00197    if (any || cqt.hasScope(CIMScope(CIMScope::CLASS)))
00198    {
00199       ostr << "CLASS=\"true\" ";
00200       scopeWritten = true;
00201    }
00202    if (any || cqt.hasScope(CIMScope(CIMScope::ASSOCIATION)))
00203    {
00204       ostr << "ASSOCIATION=\"true\" ";
00205       scopeWritten = true;
00206    }
00207    if (any || cqt.hasScope(CIMScope(CIMScope::REFERENCE)))
00208    {
00209       ostr << "REFERENCE=\"true\" ";
00210       scopeWritten = true;
00211    }
00212    if (any || cqt.hasScope(CIMScope(CIMScope::PROPERTY)))
00213    {
00214       ostr << "PROPERTY=\"true\" ";
00215       scopeWritten = true;
00216    }
00217    if (any || cqt.hasScope(CIMScope(CIMScope::METHOD)))
00218    {
00219       ostr << "METHOD=\"true\" ";
00220       scopeWritten = true;
00221    }
00222    if (any || cqt.hasScope(CIMScope(CIMScope::PARAMETER)))
00223    {
00224       ostr << "PARAMETER=\"true\" ";
00225       scopeWritten = true;
00226    }
00227    if (any || cqt.hasScope(CIMScope(CIMScope::INDICATION)))
00228    {
00229       ostr << "INDICATION=\"true\" ";
00230       scopeWritten = true;
00231    }
00232    if (!scopeWritten)
00233    {
00234       String msg("Scope not set on qaulifier type: ");
00235       msg += cqt.getName();
00236       OW_THROWCIMMSG(CIMException::FAILED, msg.c_str());
00237    }
00238    ostr << "></SCOPE>";
00239    if (cqt.getDefaultValue())
00240    {
00241       CIMtoXML(cqt.getDefaultValue(), ostr);
00242    }
00243    ostr << "</QUALIFIER.DECLARATION>";
00244 }
00245 static void
00246 outputKEYVALUE(ostream& ostr, const CIMProperty& cp)
00247 {
00248    CIMDataType dtype = cp.getDataType();
00249    String type;
00250    if (dtype.isArrayType())
00251    {
00252       OW_THROWCIMMSG(CIMException::INVALID_PARAMETER,
00253          "An array cannot be a KEY");
00254    }
00255    if (dtype.isReferenceType())
00256    {
00257       CIMProperty lcp(cp);
00258       // This is sort of a bad thing to do, basically we are taking advantage
00259       // of a side effect of setDataType.  If the type isn't correct then
00260       // the value will be cast to the correct type.  This is to work around
00261       // a problem that may happen if a provider writer sets the value of a
00262       // reference property to a String instead of an CIMObjectPath.
00263       // If the value is a string, the xml that is output will be malformed,
00264       // and the client will throw an exception.
00265       lcp.setDataType(lcp.getDataType());
00266       CIMtoXML(lcp.getValue(), ostr);
00267       return;
00268    }
00269    //
00270    // Regular key value
00271    switch (dtype.getType())
00272    {
00273       case CIMDataType::CHAR16:
00274       case CIMDataType::DATETIME:
00275       case CIMDataType::STRING:
00276          type = "string";
00277          break;
00278       case CIMDataType::BOOLEAN:
00279          type = "boolean";
00280          break;
00281       default:
00282          type = "numeric";
00283    }
00284    CIMValue keyValue = cp.getValue();
00285    if (!keyValue)
00286    {
00287       OW_THROWCIMMSG(CIMException::FAILED, "No key value");
00288    }
00289    ostr
00290       << "<KEYVALUE VALUETYPE=\""
00291       <<  type
00292       << "\">"
00293       << XMLEscape(keyValue.toString())
00294       << "</KEYVALUE>";
00295 }
00297 void CIMClassPathtoXML(CIMObjectPath const& cop, ostream& ostr)
00298 {
00299    if (!cop.isClassPath())
00300    {
00301       OW_THROWCIMMSG(CIMException::INVALID_PARAMETER, "cop is an instance path, not a class path as expected.");
00302    }
00303    if (!cop.getNameSpace().empty())
00304    {
00305       // do <CLASSPATH>
00306       ostr << "<CLASSPATH>";
00307       CIMNameSpacetoXML(cop.getFullNameSpace(),ostr);
00308       ostr << "<CLASSNAME NAME=\"" << cop.getClassName() << "\"/></CLASSPATH>";
00309    }
00310    else
00311    {
00312       // do <CLASSNAME>
00313       ostr << "<CLASSNAME NAME=\"" << cop.getClassName() << "\"/>";
00314    }
00315 }
00317 // This isn't used.  If we ever need it we can uncomment it.
00318 // void CIMLocalClassPathtoXML(CIMObjectPath const& cop, ostream& ostr)
00319 // {
00320 //     if (!cop.isClassPath())
00321 //     {
00322 //         OW_THROWCIMMSG(CIMException::INVALID_PARAMETER, "cop is an instance path, not a class path as expected.");
00323 //     }
00324 //
00325 //     if (!cop.getNameSpace().empty())
00326 //     {
00327 //         // do <LOCALCLASSPATH>
00328 //         ostr << "<LOCALCLASSPATH>";
00329 //         CIMtoXML(cop.getFullNameSpace(),ostr,CIMtoXMLFlags::doLocal);
00330 //         ostr << "<CLASSNAME NAME=\"" << cop.getObjectName() << "\"/></LOCALCLASSPATH>";
00331 //     }
00332 //     else
00333 //     {
00334 //         // do <CLASSNAME>
00335 //         ostr << "<CLASSNAME NAME=\"" << cop.getObjectName() << "\"/>";
00336 //     }
00337 // }
00339 // void
00340 // CIMClassPathtoXML(CIMObjectPath const& cop, std::ostream& ostr)
00341 // {
00342 //     if (!cop.isClassPath())
00343 //     {
00344 //         OW_THROWCIMMSG(CIMException::INVALID_PARAMETER, "cop is an instance path, not a class path as expected.");
00345 //     }
00346 //
00347 //     ostr << "<CLASSPATH>";
00348 //     CIMtoXML(cop.getFullNameSpace(), ostr, CIMtoXMLFlags::dontDoLocal);
00349 //
00350 //     ostr << "<CLASSNAME NAME=\"";
00351 //     ostr << cop.getObjectName() << "\">";
00352 //
00353 //     ostr << "</CLASSNAME>";
00354 //
00355 //     ostr << "</CLASSPATH>\n";
00356 // }
00358 void CIMInstancePathtoXML(CIMObjectPath const& cop, ostream& ostr)
00359 {
00360    //
00361    // Instance path
00362    //
00363    bool outputInstancePath = !cop.getNameSpace().empty();
00364    if (outputInstancePath)
00365    {
00366       ostr << "<INSTANCEPATH>";
00367       CIMNameSpacetoXML(cop.getFullNameSpace(), ostr);
00368    }
00369    CIMInstanceNametoXML(cop, ostr);
00370    if (outputInstancePath)
00371    {
00372       ostr << "</INSTANCEPATH>";
00373    }
00374 }
00376 void CIMLocalInstancePathtoXML(CIMObjectPath const& cop, ostream& ostr)
00377 {
00378    //
00379    // Local Instance path
00380    //
00381    ostr << "<LOCALINSTANCEPATH>";
00382    LocalCIMNameSpacetoXML(cop.getFullNameSpace(), ostr);
00383    CIMInstanceNametoXML(cop, ostr);
00384    ostr << "</LOCALINSTANCEPATH>";
00385 }
00387 void CIMInstanceNametoXML(CIMObjectPath const& cop, ostream& ostr)
00388 {
00389    ostr << "<INSTANCENAME CLASSNAME=\"";
00390    ostr << cop.getClassName() << "\">";
00391    //
00392    // If keys > 1 then must use KEYBINDING - we also use it for
00393    // the key == 1 case - most implementations can't cope with
00394    // a single KEYVALUE without a KEYBINDING element
00395    //
00396    if (cop.isInstancePath())
00397    {
00398       size_t numkeys = cop.getKeys().size();
00399       for (size_t i = 0; i < numkeys; i++)
00400       {
00401          CIMProperty cp = cop.getKeys()[i];
00402          ostr << "<KEYBINDING NAME=\"";
00403          ostr << cp.getName() << "\">";
00404          outputKEYVALUE(ostr, cp);
00405          ostr << "</KEYBINDING>";
00406       }
00407    }
00408    else
00409    {
00410       // A singleton, a class without keys
00411    }
00412    ostr << "</INSTANCENAME>";
00413 }
00415 void CIMtoXML(CIMClass const& cc, ostream& ostr)
00416 {
00417    if (cc.getName().empty())
00418    {
00419       OW_THROWCIMMSG(CIMException::FAILED, "class must have name");
00420    }
00421    ostr << "<CLASS NAME=\"";
00422    ostr << cc.getName();
00423    if (!cc.getSuperClass().empty())
00424    {
00425       ostr << "\" SUPERCLASS=\"";
00426       ostr << cc.getSuperClass();
00427    }
00428 
00429    ostr << "\">";
00430    const CIMQualifierArray& ccquals = cc.getQualifiers();
00431    for (size_t i = 0; i < ccquals.size(); i++)
00432    {
00433       CIMtoXML(ccquals[i], ostr);
00434    }
00435    const CIMPropertyArray& props = cc.getAllProperties();
00436    for (size_t i = 0; i < props.size(); i++)
00437    {
00438       CIMtoXML(props[i], ostr);
00439    }
00440    const CIMMethodArray& meths = cc.getAllMethods();
00441    for (size_t i = 0; i < meths.size(); i++)
00442    {
00443       CIMtoXML(meths[i], ostr);
00444    }
00445    ostr << "</CLASS>";
00446 }
00448 void CIMInstancetoXML(CIMInstance const& ci, ostream& ostr)
00449 {
00450    if (ci.getClassName().empty())
00451    {
00452       OW_THROWCIMMSG(CIMException::FAILED, "instance has no class name");
00453    }
00454    ostr << "<INSTANCE CLASSNAME=\"";
00455    ostr << ci.getClassName();
00456 
00457    String lang = ci.getLanguage();
00458    if (!lang.empty())
00459    {
00460       ostr << "\" xml:lang=\"";
00461       ostr << lang;
00462    }
00463    ostr << "\">";
00464 
00465    //
00466    // Process qualifiers
00467    //
00468    for (size_t i = 0; i < ci.getQualifiers().size(); i++)
00469    {
00470       CIMtoXML(ci.getQualifiers()[i], ostr);
00471    }
00472    CIMPropertyArray pra = ci.getProperties();
00473    for (size_t i = 0; i < pra.size(); i++)
00474    {
00475       CIMtoXML(pra[i],ostr);
00476    }
00477    ostr << "</INSTANCE>";
00478 }
00480 void CIMInstanceNameAndInstancetoXML(CIMInstance const& instance,
00481    ostream& ostr, CIMObjectPath const& instanceName)
00482 {
00483    CIMInstanceNametoXML(instanceName, ostr);
00484    CIMInstancetoXML(instance, ostr);
00485 }
00487 void CIMInstancePathAndInstancetoXML(CIMInstance const& instance,
00488    ostream& ostr, CIMObjectPath const& instancePath)
00489 {
00490    CIMInstancePathtoXML(instancePath, ostr);
00491    CIMInstancetoXML(instance, ostr);
00492 }
00494 template<class T>
00495 static void raToXml(ostream& out, const Array<T>& ra)
00496 {
00497    out << "<VALUE.ARRAY>";
00498    for (size_t i = 0; i < ra.size(); i++)
00499    {
00500       out << "<VALUE>";
00501       out << ra[i];
00502       out << "</VALUE>";
00503    }
00504    out << "</VALUE.ARRAY>";
00505 }
00506 
00508 template<class T>
00509 static void realArrayToXml(ostream& out, const Array<T>& ra)
00510 {
00511    out << "<VALUE.ARRAY>";
00512    for (size_t i = 0; i < ra.size(); i++)
00513    {
00514       out << "<VALUE>";
00515       out << String(ra[i]); // operator<< doesn't use the right precision by default,
00516       // and it's just easier to let the String constructor do it right for us.
00517       out << "</VALUE>";
00518    }
00519    out << "</VALUE.ARRAY>";
00520 }
00522 template <typename T>
00523 static void valueToXML(T const& x, ostream& out)
00524 {
00525    CIMtoXML(x, out);
00526 }
00527 static void valueToXML(CIMObjectPath const& x, ostream& out)
00528 {
00529    if (x.getFullNameSpace().isLocal())
00530    {
00531       if (x.getNameSpace().empty())
00532       {
00533          CIMInstanceNametoXML(x, out);
00534       }
00535       else
00536       {
00537          CIMLocalInstancePathtoXML(x, out);
00538       }
00539    }
00540    else
00541    {
00542       CIMInstancePathtoXML(x, out);
00543    }
00544 }
00545 static void raToXmlCOP(ostream& out, const Array<CIMObjectPath>& ra)
00546 {
00547    out << "<VALUE.REFARRAY>";
00548    for (size_t i = 0; i < ra.size(); i++)
00549    {
00550       out << "<VALUE.REFERENCE>";
00551       valueToXML(ra[i], out);
00552       out << "</VALUE.REFERENCE>";
00553    }
00554    out << "</VALUE.REFARRAY>";
00555 }
00556 static void raToXmlSA(ostream& out, const Array<String>& ra)
00557 {
00558    out << "<VALUE.ARRAY>";
00559    for (size_t i = 0; i < ra.size(); i++)
00560    {
00561       out << "<VALUE>";
00562       out << XMLEscape(ra[i]);
00563       out << "</VALUE>";
00564    }
00565    out << "</VALUE.ARRAY>";
00566 }
00567 static void raToXmlChar16(ostream& out, const Array<Char16>& ra)
00568 {
00569    out << "<VALUE.ARRAY>";
00570    for (size_t i = 0; i < ra.size(); i++)
00571    {
00572       out << "<VALUE>";
00573       out << XMLEscape(ra[i].toString());
00574       out << "</VALUE>";
00575    }
00576    out << "</VALUE.ARRAY>";
00577 }
00578 void raToXmlNumeric(ostream& out, const Array<Int8>& ra)
00579 {
00580    out << "<VALUE.ARRAY>";
00581    for (size_t i = 0; i < ra.size(); i++)
00582    {
00583       out << "<VALUE>";
00584       out << Int32(ra[i]);
00585       out << "</VALUE>";
00586    }
00587    out << "</VALUE.ARRAY>";
00588 }
00589 void raToXmlNumeric(ostream& out, const Array<UInt8>& ra)
00590 {
00591    out << "<VALUE.ARRAY>";
00592    for (size_t i = 0; i < ra.size(); i++)
00593    {
00594       out << "<VALUE>";
00595       out << UInt32(ra[i]);
00596       out << "</VALUE>";
00597    }
00598    out << "</VALUE.ARRAY>";
00599 }
00601 void CIMtoXML(CIMValue const& cv, ostream& out)
00602 {
00603    if (!cv)
00604    {
00605       OW_THROWCIMMSG(CIMException::FAILED, "CIM value is NULL");
00606    }
00607    if (cv.isArray())
00608    {
00609       switch (cv.getType())
00610       {
00611          case CIMDataType::BOOLEAN:
00612          {
00613             BoolArray a;
00614             cv.get(a);
00615             raToXml(out, a);
00616             break;
00617          }
00618          case CIMDataType::UINT8:
00619          {
00620             UInt8Array a;
00621             cv.get(a);
00622             raToXmlNumeric(out, a);
00623             break;
00624          }
00625          case CIMDataType::SINT8:
00626          {
00627             Int8Array a;
00628             cv.get(a);
00629             raToXmlNumeric(out, a);
00630             break;
00631          }
00632          // ATTN: UTF8
00633          case CIMDataType::CHAR16:
00634          {
00635             Char16Array a;
00636             cv.get(a);
00637             raToXmlChar16(out, a);
00638             break;
00639          }
00640          case CIMDataType::UINT16:
00641          {
00642             UInt16Array a;
00643             cv.get(a);
00644             raToXml(out, a);
00645             break;
00646          }
00647          case CIMDataType::SINT16:
00648          {
00649             Int16Array a;
00650             cv.get(a);
00651             raToXml(out, a);
00652             break;
00653          }
00654          case CIMDataType::UINT32:
00655          {
00656             UInt32Array a;
00657             cv.get(a);
00658             raToXml(out, a);
00659             break;
00660          }
00661          case CIMDataType::SINT32:
00662          {
00663             Int32Array a;
00664             cv.get(a);
00665             raToXml(out, a);
00666             break;
00667          }
00668          case CIMDataType::UINT64:
00669          {
00670             UInt64Array a;
00671             cv.get(a);
00672             raToXml(out, a);
00673             break;
00674          }
00675          case CIMDataType::SINT64:
00676          {
00677             Int64Array a;
00678             cv.get(a);
00679             raToXml(out, a);
00680             break;
00681          }
00682          case CIMDataType::REAL32:
00683          {
00684             Real32Array a;
00685             cv.get(a);
00686             realArrayToXml(out, a);
00687             break;
00688          }
00689          case CIMDataType::REAL64:
00690          {
00691             Real64Array a;
00692             cv.get(a);
00693             realArrayToXml(out, a);
00694             break;
00695          }
00696          case CIMDataType::STRING:
00697          {
00698             StringArray a;
00699             cv.get(a);
00700             raToXmlSA(out, a);
00701             break;
00702          }
00703          case CIMDataType::DATETIME:
00704          {
00705             CIMDateTimeArray a;
00706             cv.get(a);
00707             raToXml(out, a);
00708             break;
00709          }
00710          case CIMDataType::REFERENCE:
00711          {
00712             CIMObjectPathArray a;
00713             cv.get(a);
00714             raToXmlCOP(out, a);
00715             break;
00716          }
00717          
00718          case CIMDataType::EMBEDDEDCLASS:
00719          {
00720             CIMClassArray ca;
00721             cv.get(ca);
00722             StringArray sa;
00723             for (size_t i = 0; i < ca.size(); ++i)
00724             {
00725                OStringStream ss;
00726                CIMtoXML(ca[i], ss);
00727                sa.push_back(ss.toString());
00728             }
00729             raToXmlSA(out, sa);
00730             break;
00731          }
00732          
00733          case CIMDataType::EMBEDDEDINSTANCE:
00734          {
00735             CIMInstanceArray ia;
00736             cv.get(ia);
00737             StringArray sa;
00738             for (size_t i = 0; i < ia.size(); ++i)
00739             {
00740                OStringStream ss;
00741                CIMInstancetoXML(ia[i],ss);
00742                sa.push_back(ss.toString());
00743             }
00744             raToXmlSA(out, sa);
00745             break;
00746          }
00747          default:
00748             OW_ASSERT(0);
00749       }
00750    }
00751    else if (cv.getType() == CIMDataType::REFERENCE)
00752    {
00753       out << "<VALUE.REFERENCE>";
00754       CIMObjectPath a(CIMNULL);
00755       cv.get(a);
00756       if (a.getFullNameSpace().isLocal())
00757       {
00758          if (a.getNameSpace().empty())
00759          {
00760             CIMInstanceNametoXML(a, out);
00761          }
00762          else
00763          {
00764             CIMLocalInstancePathtoXML(a, out);
00765          }
00766       }
00767       else
00768       {
00769          CIMInstancePathtoXML(a, out);
00770       }
00771       out << "</VALUE.REFERENCE>";
00772    }
00773    else
00774    {
00775       out << "<VALUE>";
00776       switch (cv.getType())
00777       {
00778          case CIMDataType::BOOLEAN:
00779          case CIMDataType::UINT8:
00780          case CIMDataType::SINT8:
00781          case CIMDataType::UINT16:
00782          case CIMDataType::SINT16:
00783          case CIMDataType::UINT32:
00784          case CIMDataType::SINT32:
00785          case CIMDataType::UINT64:
00786          case CIMDataType::SINT64:
00787          case CIMDataType::DATETIME:
00788          {
00789             out << cv.toString();
00790             break;
00791          }
00792          case CIMDataType::REAL32:
00793          {
00794             char tmpbuf[128];
00795 #if FLT_RADIX == 2
00796 #if defined(OW_REAL32_IS_FLOAT)
00797 				::SNPRINTF(tmpbuf, sizeof(tmpbuf), "%.*e", FLT_MANT_DIG * 3 / 10 + 1, static_cast<double>(cv.toReal32()));
00798 #elif defined(OW_REAL32_IS_DOUBLE)
00799 				::SNPRINTF(tmpbuf, sizeof(tmpbuf), "%.*e", DBL_MANT_DIG * 3 / 10 + 1, cv.toReal32());
00800 #endif
00801 #else
00802 #error "The formula for computing the number of digits of precision for a floating point needs to be implmented. It's ceiling(bits * log(FLT_RADIX) / log(10))"
00803 #endif
00804             out << tmpbuf;
00805             break;
00806          }
00807          case CIMDataType::REAL64:
00808          {
00809             char tmpbuf[128];
00810 #if FLT_RADIX == 2
00811 #if defined(OW_REAL64_IS_DOUBLE)
00812 				::SNPRINTF(tmpbuf, sizeof(tmpbuf), "%.*e", DBL_MANT_DIG * 3 / 10 + 1, cv.toReal64());
00813 #elif defined(OW_REAL64_IS_LONG_DOUBLE)
00814 				::SNPRINTF(tmpbuf, sizeof(tmpbuf), "%.*Le", LDBL_MANT_DIG * 3 / 10 + 1, cv.toReal64());
00815 #endif
00816 #else
00817 #error "The formula for computing the number of digits of precision for a floating point needs to be implmented. It's ceiling(bits * log(FLT_RADIX) / log(10))"
00818 #endif
00819             out << tmpbuf;
00820             break;
00821          }
00822          case CIMDataType::CHAR16:
00823          case CIMDataType::STRING:
00824          {
00825             out << XMLEscape(cv.toString());
00826             break;
00827          }
00828          
00829          case CIMDataType::EMBEDDEDCLASS:
00830          {
00831             CIMClass cc(CIMNULL);
00832             cv.get(cc);
00833             String s;
00834             OStringStream ss;
00835             CIMtoXML(cc, ss);
00836             out << XMLEscape(ss.toString());
00837             break;
00838          }
00839          
00840          case CIMDataType::EMBEDDEDINSTANCE:
00841          {
00842             CIMInstance i(CIMNULL);
00843             cv.get(i);
00844             String s;
00845             OStringStream ss;
00846             CIMInstancetoXML(i,ss);
00847             out << XMLEscape(ss.toString());
00848             break;
00849          }
00850          default:
00851             OW_ASSERT(0);
00852       }
00853       out << "</VALUE>";
00854    }
00855 }
00857 void
00858 CIMtoXML(CIMDataType const& cdt, ostream& ostr)
00859 {
00860    switch (cdt.getType())
00861    {
00862       case CIMDataType::INVALID:
00863          OW_THROWCIMMSG(CIMException::FAILED,
00864             "Invalid data type for toXML operation");
00865          break;
00866       // special case for this since CIMDataType::toString() returns REF (appropriate for MOF)
00867       case CIMDataType::REFERENCE:
00868          ostr << "reference";
00869          break;
00870       default:
00871          ostr << cdt.toString();
00872          break;
00873    }
00874 }
00876 void
00877 CIMtoXML(CIMFlavor const& cf, ostream& ostr)
00878 {
00879    const char* strf;
00880    switch (cf.getFlavor())
00881    {
00882       case CIMFlavor::ENABLEOVERRIDE: strf = "OVERRIDABLE"; break;
00883       case CIMFlavor::DISABLEOVERRIDE: strf = "OVERRIDABLE"; break;
00884       case CIMFlavor::TOSUBCLASS: strf = "TOSUBCLASS"; break;
00885       case CIMFlavor::RESTRICTED: strf = "TOSUBCLASS"; break;
00886       case CIMFlavor::TRANSLATE: strf = "TRANSLATABLE"; break;
00887       default: strf = "BAD FLAVOR"; break;
00888    }
00889    ostr << strf;
00890 }
00892 void
00893 CIMtoXML(CIMQualifier const& cq, ostream& ostr)
00894 {
00895    CIMFlavor fv;
00896    
00897    if (cq.getName().empty())
00898    {
00899       OW_THROWCIMMSG(CIMException::FAILED, "qualifier must have a name");
00900    }
00901    CIMValue dv = cq.getDefaults().getDefaultValue();
00902    CIMDataType dt = cq.getDefaults().getDataType();
00903    CIMValue cv = cq.getValue();
00904    if (!cv)
00905    {
00906       cv = dv;
00907    }
00908    if (cv)
00909    {
00910       if (cv.isArray())
00911       {
00912          dt = CIMDataType(cv.getType(),cv.getArraySize());
00913       }
00914       else
00915       {
00916          dt = CIMDataType(cv.getType());
00917       }
00918    }
00919    OW_ASSERT(dt);
00920    ostr
00921       << "<QUALIFIER NAME=\""
00922       << cq.getName()
00923       << "\" TYPE=\"";
00924    CIMtoXML(dt,ostr);
00925    ostr << "\" ";
00926    if (cq.getPropagated())
00927    {
00928       ostr << "PROPAGATED=\"true\" ";
00929    }
00930    //
00931    // Create flavors
00932    //
00933    fv = CIMFlavor(CIMFlavor::ENABLEOVERRIDE);
00934    if (cq.hasFlavor(fv))
00935    {
00936       //
00937       // Not needed, because OVERRIDABLE defaults to true!
00938    }
00939    else
00940    {
00941       fv = CIMFlavor(CIMFlavor::DISABLEOVERRIDE);
00942       if (cq.hasFlavor(fv))
00943       {
00944          CIMtoXML(fv, ostr);
00945          ostr <<  "=\"false\" ";
00946       }
00947    }
00948    fv = CIMFlavor(CIMFlavor::TOSUBCLASS);
00949    if (cq.hasFlavor(fv))
00950    {
00951       //
00952       // Not needed, because TOSUBCLASS defaults to true!
00953    }
00954    else
00955    {
00956       fv = CIMFlavor(CIMFlavor::RESTRICTED);
00957       if (cq.hasFlavor(fv))
00958       {
00959          CIMtoXML(fv, ostr);
00960          ostr <<  "=\"false\" ";
00961       }
00962    }
00963    // This is a bug in the spec, but we still support it for backward compatibility.
00964    //fv = CIMFlavor(CIMFlavor::TOINSTANCE);
00965    //if (cq.hasFlavor(fv))
00966    //{
00967    // CIMtoXML(fv, ostr);
00968    // ostr << "=\"true\" ";
00969    //}
00970    //else
00971    //{
00972       //
00973       // Not needed, because TOINSTANCE defaults to false!
00974    //}
00975    fv = CIMFlavor(CIMFlavor::TRANSLATE);
00976    if (cq.hasFlavor(fv))
00977    {
00978       CIMtoXML(fv, ostr);
00979       ostr << "=\"true\" ";
00980    }
00981    else
00982    {
00983       //
00984       // Not needed, because TRANSLATABLE defaults to false!
00985    }
00986 
00987    String lang = cq.getLanguage();
00988    if (!lang.empty())
00989    {
00990       ostr << " xml:lang=\"";
00991       ostr << lang;
00992       ostr << '\"';
00993    }
00994 
00995    ostr << '>';
00996    if (cv)
00997    {
00998       CIMtoXML(cv, ostr);
00999    }
01000    ostr << "</QUALIFIER>";
01001 }
01003 void
01004 CIMtoXML(CIMProperty const& cp, ostream& ostr)
01005 {
01006    bool isArray = false;
01007    bool isRef = false;
01008    if (cp.getName().empty())
01009    {
01010       OW_THROWCIMMSG(CIMException::FAILED, "property must have a name");
01011    }
01012    if (cp.getDataType())
01013    {
01014       isArray = cp.getDataType().isArrayType();
01015       isRef = cp.getDataType().isReferenceType();
01016       if (isArray)
01017       {
01018          ostr
01019             <<  "<PROPERTY.ARRAY NAME=\""
01020             <<  cp.getName()
01021             << "\" TYPE=\"";
01022          CIMtoXML(cp.getDataType(), ostr);
01023          ostr << "\" ";
01024          if (cp.getDataType().getSize() != -1)
01025          {
01026             ostr
01027                << "ARRAYSIZE=\""
01028                << cp.getDataType().getSize()
01029                << "\" ";
01030          }
01031       }
01032       else if (isRef)
01033       {
01034          ostr
01035             << "<PROPERTY.REFERENCE NAME=\""
01036             << cp.getName()
01037             << "\" REFERENCECLASS=\""
01038             << cp.getDataType().getRefClassName()
01039             << "\" ";
01040       }
01041       else
01042       {
01043          ostr
01044             << "<PROPERTY NAME=\""
01045             << cp.getName()
01046             << "\" TYPE=\"";
01047          CIMtoXML(cp.getDataType(), ostr);
01048          ostr << "\" ";
01049       }
01050    }
01051    else
01052    {
01053       String msg("Property ");
01054       msg += cp.getName();
01055       msg += " has no type defined";
01056       OW_THROWCIMMSG(CIMException::FAILED, msg.c_str());
01057    }
01058    if (!cp.getOriginClass().empty())
01059    {
01060       ostr
01061          << "CLASSORIGIN=\""
01062          << cp.getOriginClass()
01063          << "\" ";
01064    }
01065    if (cp.getPropagated())
01066    {
01067       ostr << "PROPAGATED=\"true\" ";
01068    }
01069    
01070    CIMValue val = cp.getValue();
01071    if (cp.getDataType().isEmbeddedObjectType() || (val && val.getCIMDataType().isEmbeddedObjectType()))
01072    {
01073       ostr << "EmbeddedObject=\"object\" ";
01074    }
01075 
01076    ostr << '>';
01077    for (size_t i = 0; i < cp.getQualifiers().size(); i++)
01078    {
01079       CIMtoXML(cp.getQualifiers()[i], ostr);
01080    }
01081 
01082    if (val)
01083    {
01084       // if there isn't an EmbeddedObject qualifier on an embedded object, then output one.
01085       if (val.getType() == CIMDataType::EMBEDDEDINSTANCE || val.getType() == CIMDataType::EMBEDDEDCLASS)
01086       {
01087          if (!cp.getQualifier(CIMQualifier::CIM_QUAL_EMBEDDEDOBJECT))
01088          {
01089             CIMQualifier embeddedObject(CIMQualifier::CIM_QUAL_EMBEDDEDOBJECT);
01090             embeddedObject.setValue(CIMValue(true));
01091             CIMtoXML(embeddedObject, ostr);
01092          }
01093       }
01094 
01095       CIMtoXML(val, ostr);
01096    }
01097    if (isArray)
01098    {
01099       ostr << "</PROPERTY.ARRAY>";
01100    }
01101    else if (isRef)
01102    {
01103       ostr << "</PROPERTY.REFERENCE>";
01104    }
01105    else
01106    {
01107       ostr << "</PROPERTY>";
01108    }
01109 }
01110             
01112 void
01113 CIMtoXML(CIMMethod const& cm, ostream& ostr)
01114 {
01115    ostr << "<METHOD ";
01116    if (cm.getName().empty())
01117    {
01118       OW_THROWCIMMSG(CIMException::FAILED, "method must have a name");
01119    }
01120    ostr
01121       << "NAME=\""
01122       << cm.getName()
01123       << "\" ";
01124    if (cm.getReturnType())
01125    {
01126       ostr << "TYPE=\"";
01127       CIMtoXML(cm.getReturnType(),ostr);
01128       ostr << "\" ";
01129    }
01130    if (!cm.getOriginClass().empty())
01131    {
01132       ostr
01133          << "CLASSORIGIN=\""
01134          << cm.getOriginClass()
01135          << "\" ";
01136    }
01137    if (cm.getPropagated())
01138    {
01139       ostr << "PROPAGATED=\"true\" ";
01140    }
01141    ostr << '>';
01142    for (size_t i = 0; i < cm.getQualifiers().size(); i++)
01143    {
01144       CIMtoXML(cm.getQualifiers()[i], ostr);
01145    }
01146    for (size_t i = 0; i < cm.getParameters().size(); i++)
01147    {
01148       CIMtoXML(cm.getParameters()[i], ostr);
01149    }
01150    ostr << "</METHOD>";
01151 }
01152             
01154 static void
01155 qualifierXML(CIMParameter const& cp, ostream& ostr)
01156 {
01157    if (cp.getQualifiers().size() > 0)
01158    {
01159       int sz = cp.getQualifiers().size();
01160       for (int i = 0; i < sz; i++)
01161       {
01162          CIMtoXML(cp.getQualifiers()[i], ostr);
01163       }
01164    }
01165 }
01167 void
01168 CIMtoXML(CIMParameter const& cp, ostream& ostr)
01169 {
01170    if (cp.getName().empty())
01171    {
01172       OW_THROWCIMMSG(CIMException::INVALID_PARAMETER,
01173          "parameter must have a name");
01174    }
01175    if (!cp.getType())
01176    {
01177       OW_THROWCIMMSG(CIMException::INVALID_PARAMETER,
01178          "parameter must have a valid data type");
01179    }
01180    bool isArray = cp.getType().isArrayType();
01181    if (cp.getType().isReferenceType())
01182    {
01183       //
01184       // Data type is a reference
01185       //
01186       String classref = cp.getType().getRefClassName();
01187       if (!classref.empty())
01188       {
01189          classref = "REFERENCECLASS=\"" + classref + "\"";
01190       }
01191       if (isArray)
01192       {
01193          if (cp.getType().getSize() == -1)
01194          {
01195             ostr
01196                << "<PARAMETER.REFARRAY "
01197                << classref
01198                << " NAME=\""
01199                << cp.getName()
01200                << "\">";
01201             qualifierXML(cp, ostr);
01202             ostr << "</PARAMETER.REFARRAY>";
01203          }
01204          else
01205          {
01206             ostr
01207                << "<PARAMETER.REFARRAY "
01208                << classref
01209                << " NAME=\""
01210                << cp.getName()
01211                << "\""
01212                << " ARRAYSIZE=\""
01213                << cp.getType().getSize()
01214                << "\">";
01215             qualifierXML(cp, ostr);
01216             ostr << "</PARAMETER.REFARRAY>";
01217          }
01218       }
01219       else
01220       {
01221          ostr
01222             << "<PARAMETER.REFERENCE "
01223             << classref
01224             << " NAME=\""
01225             << cp.getName()
01226             << "\">";
01227          qualifierXML(cp, ostr);
01228          ostr << "</PARAMETER.REFERENCE>";
01229       }
01230    }
01231    else
01232    {
01233       // Data type is not a ref
01234       if (isArray)
01235       {
01236          ostr << "<PARAMETER.ARRAY TYPE=\"";
01237          CIMtoXML(cp.getType(), ostr);
01238          ostr << "\" NAME=\"" << cp.getName();
01239          if (cp.getType().getSize() != -1)
01240          {
01241             ostr
01242                << "\" ARRAYSIZE=\""
01243                << cp.getType().getSize();
01244          }
01245          ostr << "\">";
01246          qualifierXML(cp, ostr);
01247          ostr << "</PARAMETER.ARRAY>";
01248       }
01249       else
01250       {
01251          ostr << "<PARAMETER TYPE=\"";
01252          CIMtoXML(cp.getType(), ostr);
01253          ostr
01254             << "\"  NAME=\""
01255             << cp.getName()
01256             << "\">";
01257          qualifierXML(cp, ostr);
01258          ostr << "</PARAMETER>";
01259       }
01260    }
01261 }
01263 void
01264 CIMParamValueToXML(CIMParamValue const& pv, std::ostream& ostr)
01265 {
01266    ostr << "<PARAMVALUE NAME=\"" << pv.getName() << "\"";
01267    if (pv.getValue())
01268    {
01269       String type = pv.getValue().getCIMDataType().toString();
01270       if (type == "REF")
01271       {
01272          type = "reference";
01273       }
01274       ostr << " PARAMTYPE=\"" << type << "\"";
01275       
01276       if (pv.getValue().getCIMDataType().isEmbeddedObjectType())
01277       {
01278          ostr << " EmbeddedObject=\"object\"";
01279       }
01280 
01281       ostr << ">";
01282       CIMtoXML(pv.getValue(), ostr);
01283    }
01284    else
01285    {
01286       ostr << '>';
01287    }
01288    ostr << "</PARAMVALUE>";
01289 }
01290 
01291 } // end namespace OW_NAMESPACE
01292 

Generated on Thu Feb 9 08:47:55 2006 for openwbem by  doxygen 1.4.6