00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
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       
00070       if (!dataType || !value)
00071       {
00072          return CIMValue(CIMNULL);
00073       }
00074       
00075       if (value.getType() == dataType.getType()
00076          && value.isArray() == dataType.isArrayType())
00077       {
00078          return value;
00079       }
00080       
00081       
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       
00089       if (value.isArray())
00090       {
00091          return convertArray(value, dataType);
00092       }
00093       
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 } 
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                         
00235       || from == CIMDataType::STRING   
00236       || to == CIMDataType::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       
00246       
00247       return false;
00248    }
00249    
00250    
00251    
00252    
00253    bool fromNumeric = CIMDataType::isNumericType(from);
00254    bool toNumeric = CIMDataType::isNumericType(to);
00255    
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 } 
00608