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