OW_CIMValueCast.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_CIMValueCast.hpp"
00038 #include "OW_Format.hpp"
00039 #include "OW_CIMDataType.hpp"
00040 #include "OW_CIMValue.hpp"
00041 #include "OW_CIMException.hpp"
00042 #include "OW_CIMDateTime.hpp"
00043 #include "OW_CIMObjectPath.hpp"
00044 #include "OW_ExceptionIds.hpp"
00045 
00046 namespace OW_NAMESPACE
00047 {
00048 
00049 OW_DEFINE_EXCEPTION_WITH_ID(ValueCast);
00050 static bool isCompatible(CIMDataType::Type from, CIMDataType::Type to);
00051 static void makeValueArray(CIMValue& theValue);
00052 static CIMValue convertString(const String& strValue,
00053    const CIMDataType& dataType);
00054 static CIMValue convertArray(const CIMValue& value,
00055    const CIMDataType& dataType);
00056 static StringArray convertToStringArray(const CIMValue& value,
00057    bool onlyOne);
00058 
00060 namespace CIMValueCast
00061 {
00062 
00063 CIMValue
00064 castValueToDataType(const CIMValue& value,
00065       const CIMDataType& dataType)
00066 {
00067    try
00068    {
00069       // If NULL data type, then return NULL value.
00070       if (!dataType || !value)
00071       {
00072          return CIMValue(CIMNULL);
00073       }
00074       // If the CIMValue is already what it needs to be, then just return it.
00075       if (value.getType() == dataType.getType()
00076          && value.isArray() == dataType.isArrayType())
00077       {
00078          return value;
00079       }
00080       // If we can't convert to the data type specified in the dataType argument,
00081       // then throw an exception
00082       if (!isCompatible(value.getType(), dataType.getType()))
00083       {
00084          OW_THROWCIMMSG(CIMException::FAILED,
00085             Format("Failed to convert \"%1\" to %2", value.toString(),
00086                dataType.toString()).c_str());
00087       }
00088       // If value is an array, then do special array processing
00089       if (value.isArray())
00090       {
00091          return convertArray(value, dataType);
00092       }
00093       // Convert value to string
00094       String strValue = value.toString();
00095       CIMValue cv(CIMNULL);
00096       cv = convertString(strValue, dataType);
00097       if (dataType.isArrayType())
00098       {
00099          makeValueArray(cv);
00100       }
00101       return cv;
00102    }
00103    catch (const StringConversionException& e)
00104    {
00105       OW_THROWCIM_SUBEX(CIMException::FAILED, e);
00106    }
00107 }
00108 } // end namespace CIMValueCast
00109 
00111 void
00112 makeValueArray(CIMValue& theValue)
00113 {
00114    if (theValue.isArray())
00115    {
00116       return;
00117    }
00118    switch (theValue.getType())
00119    {
00120       case CIMDataType::UINT8:
00121       {
00122          UInt8 v;
00123          theValue.get(v);
00124          theValue = CIMValue(UInt8Array(1, v));
00125          break;
00126       }
00127       case CIMDataType::SINT8:
00128       {
00129          Int8 v;
00130          theValue.get(v);
00131          theValue = CIMValue(Int8Array(1, v));
00132          break;
00133       }
00134       case CIMDataType::UINT16:
00135       {
00136          UInt16 v;
00137          theValue.get(v);
00138          theValue = CIMValue(UInt16Array(1, v));
00139          break;
00140       }
00141       case CIMDataType::SINT16:
00142       {
00143          Int16 v;
00144          theValue.get(v);
00145          theValue = CIMValue(Int16Array(1, v));
00146          break;
00147       }
00148       case CIMDataType::UINT32:
00149       {
00150          UInt32 v;
00151          theValue.get(v);
00152          theValue = CIMValue(UInt32Array(1, v));
00153          break;
00154       }
00155       case CIMDataType::SINT32:
00156       {
00157          Int32 v;
00158          theValue.get(v);
00159          theValue = CIMValue(Int32Array(1, v));
00160          break;
00161       }
00162       case CIMDataType::UINT64:
00163       {
00164          UInt64 v;
00165          theValue.get(v);
00166          theValue = CIMValue(UInt64Array(1, v));
00167          break;
00168       }
00169       case CIMDataType::SINT64:
00170       {
00171          Int64 v;
00172          theValue.get(v);
00173          theValue = CIMValue(Int64Array(1, v));
00174          break;
00175       }
00176       case CIMDataType::STRING:
00177       {
00178          String v;
00179          theValue.get(v);
00180          theValue = CIMValue(StringArray(1, v));
00181          break;
00182       }
00183       case CIMDataType::BOOLEAN:
00184       {
00185          Bool v;
00186          theValue.get(v);
00187          theValue = CIMValue(BoolArray(1, v));
00188          break;
00189       }
00190       case CIMDataType::REAL32:
00191       {
00192          Real32 v;
00193          theValue.get(v);
00194          theValue = CIMValue(Real32Array(1, v));
00195          break;
00196       }
00197       case CIMDataType::REAL64:
00198       {
00199          Real64 v;
00200          theValue.get(v);
00201          theValue = CIMValue(Real64Array(1, v));
00202          break;
00203       }
00204       case CIMDataType::DATETIME:
00205       {
00206          CIMDateTime v(CIMNULL);
00207          theValue.get(v);
00208          theValue = CIMValue(CIMDateTimeArray(1, v));
00209          break;
00210       }
00211       case CIMDataType::CHAR16:
00212       {
00213          Char16 v;
00214          theValue.get(v);
00215          theValue = CIMValue(Char16Array(1, v));
00216          break;
00217       }
00218       case CIMDataType::REFERENCE:
00219       {
00220          CIMObjectPath v(CIMNULL);
00221          theValue.get(v);
00222          theValue = CIMValue(CIMObjectPathArray(1, v));
00223          break;
00224       }
00225       default:
00226          OW_THROW(ValueCastException, Format("Invalid data type: %1",
00227             theValue.getType()).c_str());
00228    }
00229 }
00231 bool
00232 isCompatible(CIMDataType::Type from, CIMDataType::Type to)
00233 {
00234    if (from == to                         // Same data types
00235       || from == CIMDataType::STRING   // String can convert to anything
00236       || to == CIMDataType::STRING)    // Anything can convert to string
00237    {
00238       return true;
00239    }
00240    if (to == CIMDataType::DATETIME
00241       || to == CIMDataType::REFERENCE
00242       || from == CIMDataType::DATETIME
00243       || from == CIMDataType::REFERENCE)
00244    {
00245       // Only string can convert to/from these types, and neither the from or
00246       // to data types are a string type
00247       return false;
00248    }
00249    //---------
00250    // At this point we know we are not converting to/from any DATETIME,
00251    // REFERENCE or STRING data types
00252    //---------
00253    bool fromNumeric = CIMDataType::isNumericType(from);
00254    bool toNumeric = CIMDataType::isNumericType(to);
00255    // If we're converting to any numeric data type
00256    if (toNumeric
00257       || to == CIMDataType::CHAR16
00258       || to == CIMDataType::BOOLEAN)
00259    {
00260       if (fromNumeric
00261          || from == CIMDataType::BOOLEAN
00262          || from == CIMDataType::CHAR16)
00263       {
00264          return true;
00265       }
00266       return false;
00267    }
00268    OW_THROW(ValueCastException, Format("Invalid to datatype: %1", to).c_str());
00269    return false;
00270 }
00272 CIMValue
00273 convertString(const String& strValue, const CIMDataType& dataType)
00274 {
00275    return CIMValue::createSimpleValue(dataType.toString(), strValue);
00276 }
00278 CIMValue
00279 convertArray(const CIMValue& value, const CIMDataType& dataType)
00280 {
00281    CIMValue rcv(CIMNULL);
00282    bool onlyOne = !dataType.isArrayType();
00283    StringArray strArray = convertToStringArray(value, onlyOne);
00284    size_t sz = strArray.size();
00285    if (onlyOne)
00286    {
00287       if (sz)
00288       {
00289          rcv = convertString(strArray[0], dataType);
00290       }
00291       return rcv;
00292    }
00293    switch (dataType.getType())
00294    {
00295       case CIMDataType::UINT8:
00296       {
00297          UInt8Array ra(sz);
00298          for (size_t i = 0; i < sz; i++)
00299          {
00300             ra[i] = strArray[i].toUInt8();
00301          }
00302          rcv = CIMValue(ra);
00303          break;
00304       }
00305       case CIMDataType::SINT8:
00306       {
00307          Int8Array ra(sz);
00308          for (size_t i = 0; i < sz; i++)
00309          {
00310             ra[i] = strArray[i].toInt8();
00311          }
00312          rcv = CIMValue(ra);
00313          break;
00314       }
00315       case CIMDataType::UINT16:
00316       {
00317          UInt16Array ra(sz);
00318          for (size_t i = 0; i < sz; i++)
00319          {
00320             ra[i] = strArray[i].toUInt16();
00321          }
00322          rcv = CIMValue(ra);
00323          break;
00324       }
00325       case CIMDataType::SINT16:
00326       {
00327          Int16Array ra(sz);
00328          for (size_t i = 0; i < sz; i++)
00329          {
00330             ra[i] = strArray[i].toInt16();
00331          }
00332          rcv = CIMValue(ra);
00333          break;
00334       }
00335       case CIMDataType::UINT32:
00336       {
00337          UInt32Array ra(sz);
00338          for (size_t i = 0; i < sz; i++)
00339          {
00340             ra[i] = strArray[i].toUInt32();
00341          }
00342          rcv = CIMValue(ra);
00343          break;
00344       }
00345       case CIMDataType::SINT32:
00346       {
00347          Int32Array ra(sz);
00348          for (size_t i = 0; i < sz; i++)
00349          {
00350             ra[i] = strArray[i].toInt32();
00351          }
00352          rcv = CIMValue(ra);
00353          break;
00354       }
00355       case CIMDataType::UINT64:
00356       {
00357          UInt64Array ra(sz);
00358          for (size_t i = 0; i < sz; i++)
00359          {
00360             ra[i] = strArray[i].toUInt64();
00361          }
00362          rcv = CIMValue(ra);
00363          break;
00364       }
00365       case CIMDataType::SINT64:
00366       {
00367          Int64Array ra(sz);
00368          for (size_t i = 0; i < sz; i++)
00369          {
00370             ra[i] = strArray[i].toInt64();
00371          }
00372          rcv = CIMValue(ra);
00373          break;
00374       }
00375       case CIMDataType::STRING:
00376          rcv = CIMValue(strArray);
00377          break;
00378       case CIMDataType::BOOLEAN:
00379       {
00380          BoolArray ra(sz);
00381          for (size_t i = 0; i < sz; i++)
00382          {
00383             ra[i] = strArray[i].toBool();
00384          }
00385          rcv = CIMValue(ra);
00386          break;
00387       }
00388       case CIMDataType::REAL32:
00389       {
00390          Real32Array ra(sz);
00391          for (size_t i = 0; i < sz; i++)
00392          {
00393             ra[i] = strArray[i].toReal32();
00394          }
00395          rcv = CIMValue(ra);
00396          break;
00397       }
00398       case CIMDataType::REAL64:
00399       {
00400          Real64Array ra(sz);
00401          for (size_t i = 0; i < sz; i++)
00402          {
00403             ra[i] = strArray[i].toReal64();
00404          }
00405          rcv = CIMValue(ra);
00406          break;
00407       }
00408       case CIMDataType::DATETIME:
00409       {
00410          CIMDateTimeArray ra(sz);
00411          for (size_t i = 0; i < sz; i++)
00412          {
00413             ra[i] = CIMDateTime(strArray[i]);
00414          }
00415          rcv = CIMValue(ra);
00416          break;
00417       }
00418       case CIMDataType::CHAR16:
00419       {
00420          Char16Array ra(sz);
00421          for (size_t i = 0; i < sz; i++)
00422          {
00423             ra[i] = Char16(strArray[i]);
00424          }
00425          rcv = CIMValue(ra);
00426          break;
00427       }
00428       case CIMDataType::REFERENCE:
00429       {
00430          CIMObjectPathArray ra(sz);
00431          for (size_t i = 0; i < sz; i++)
00432          {
00433             ra[i] = CIMObjectPath::parse(strArray[i]);
00434          }
00435          rcv = CIMValue(ra);
00436          break;
00437       }
00438       default:
00439          OW_THROW(ValueCastException, "LOGIC ERROR");
00440    }
00441    return rcv;
00442 }
00444 StringArray
00445 convertToStringArray(const CIMValue& value, bool onlyOne)
00446 {
00447    size_t rasize = (onlyOne) ? 1 : value.getArraySize();
00448    StringArray rvra(rasize);
00449    switch (value.getType())
00450    {
00451       case CIMDataType::UINT8:
00452       {
00453          UInt8Array ra;
00454          value.get(ra);
00455          for (size_t i = 0; i < rasize; i++)
00456          {
00457             rvra[i] = String(UInt32(ra[i]));
00458          }
00459          break;
00460       }
00461       case CIMDataType::SINT8:
00462       {
00463          Int8Array ra;
00464          value.get(ra);
00465          for (size_t i = 0; i < rasize; i++)
00466          {
00467             rvra[i] = String(Int32(ra[i]));
00468          }
00469          break;
00470       }
00471       case CIMDataType::UINT16:
00472       {
00473          UInt16Array ra;
00474          value.get(ra);
00475          for (size_t i = 0; i < rasize; i++)
00476          {
00477             rvra[i] = String(UInt32(ra[i]));
00478          }
00479          break;
00480       }
00481       case CIMDataType::SINT16:
00482       {
00483          Int16Array ra;
00484          value.get(ra);
00485          for (size_t i = 0; i < rasize; i++)
00486          {
00487             rvra[i] = String(Int32(ra[i]));
00488          }
00489          break;
00490       }
00491       case CIMDataType::UINT32:
00492       {
00493          UInt32Array ra;
00494          value.get(ra);
00495          for (size_t i = 0; i < rasize; i++)
00496          {
00497             rvra[i] = String(ra[i]);
00498          }
00499          break;
00500       }
00501       case CIMDataType::SINT32:
00502       {
00503          Int32Array ra;
00504          value.get(ra);
00505          for (size_t i = 0; i < rasize; i++)
00506          {
00507             rvra[i] = String(ra[i]);
00508          }
00509          break;
00510       }
00511       case CIMDataType::UINT64:
00512       {
00513          UInt64Array ra;
00514          value.get(ra);
00515          for (size_t i = 0; i < rasize; i++)
00516          {
00517             rvra[i] = String(ra[i]);
00518          }
00519          break;
00520       }
00521       case CIMDataType::SINT64:
00522       {
00523          Int64Array ra;
00524          value.get(ra);
00525          for (size_t i = 0; i < rasize; i++)
00526          {
00527             rvra[i] = String(ra[i]);
00528          }
00529          break;
00530       }
00531       case CIMDataType::STRING:
00532       {
00533          StringArray ra;
00534          value.get(ra);
00535          for (size_t i = 0; i < rasize; i++)
00536          {
00537             rvra[i] = ra[i];
00538          }
00539          break;
00540       }
00541       case CIMDataType::BOOLEAN:
00542       {
00543          BoolArray ra;
00544          value.get(ra);
00545          for (size_t i = 0; i < rasize; i++)
00546          {
00547             rvra[i] = ra[i].toString();
00548          }
00549          break;
00550       }
00551       case CIMDataType::REAL32:
00552       {
00553          Real32Array ra;
00554          value.get(ra);
00555          for (size_t i = 0; i < rasize; i++)
00556          {
00557             rvra[i] = String(Real64(ra[i]));
00558          }
00559          break;
00560       }
00561       case CIMDataType::REAL64:
00562       {
00563          Real64Array ra;
00564          value.get(ra);
00565          for (size_t i = 0; i < rasize; i++)
00566          {
00567             rvra[i] = String(ra[i]);
00568          }
00569          break;
00570       }
00571       case CIMDataType::DATETIME:
00572       {
00573          CIMDateTimeArray ra;
00574          value.get(ra);
00575          for (size_t i = 0; i < rasize; i++)
00576          {
00577             rvra[i] = ra[i].toString();
00578          }
00579          break;
00580       }
00581       case CIMDataType::CHAR16:
00582       {
00583          Char16Array ra;
00584          value.get(ra);
00585          for (size_t i = 0; i < rasize; i++)
00586          {
00587             rvra[i] = ra[i].toString();
00588          }
00589          break;
00590       }
00591       case CIMDataType::REFERENCE:
00592       {
00593          CIMObjectPathArray ra;
00594          value.get(ra);
00595          for (size_t i = 0; i < rasize; i++)
00596          {
00597             rvra[i] = ra[i].toString();
00598          }
00599          break;
00600       }
00601       default:
00602          OW_THROW(ValueCastException, "LOGIC ERROR");
00603    }
00604    return rvra;
00605 }
00606 
00607 } // end namespace OW_NAMESPACE
00608 

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