Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

859 lines
19 KiB

  1. /*++
  2. Copyright (C) 1996-2001 Microsoft Corporation
  3. Module Name:
  4. Abstract:
  5. History:
  6. --*/
  7. #include "precomp.h"
  8. #include <stdlib.h>
  9. #include <stdio.h>
  10. #include <assert.h>
  11. #include <wbemcli.h>
  12. #include "cimval.h"
  13. BOOL SecondsToInterval( long double ldbSeconds, LPWSTR wszText )
  14. {
  15. int nDay, nHour, nMinute, nSecond, nMicro;
  16. nDay = int(ldbSeconds / 86400);
  17. ldbSeconds -= nDay * 86400;
  18. nHour = int(ldbSeconds / 3600);
  19. ldbSeconds -= nHour * 3600;
  20. nMinute = int(ldbSeconds / 60);
  21. ldbSeconds -= nMinute * 60;
  22. nSecond = int(ldbSeconds);
  23. ldbSeconds -= nSecond;
  24. nMicro = int(ldbSeconds * 1000000);
  25. swprintf( wszText, L"%08.8d%02.2d%02.2d%02.2d.%06.6d:000",
  26. nDay, nHour, nMinute, nSecond, nMicro );
  27. return TRUE;
  28. }
  29. // this should be a WBEM common thing ...
  30. BOOL FileTimeToDateTime( FILETIME* pft, LPWSTR wszText )
  31. {
  32. SYSTEMTIME st;
  33. __int64 llnss = *(__int64*)pft;
  34. if ( !FileTimeToSystemTime( pft, &st ) )
  35. {
  36. return FALSE;
  37. }
  38. //
  39. // have to account for microseconds as well (probably a much better way
  40. // to do this.)
  41. //
  42. st.wMilliseconds = 0;
  43. FILETIME ft;
  44. if ( !SystemTimeToFileTime( &st, &ft ) )
  45. {
  46. return FALSE;
  47. }
  48. __int64 llnss2 = *(__int64*)&ft;
  49. int nMicro = int((llnss - llnss2)/10);
  50. swprintf( wszText,
  51. L"%04.4d%02.2d%02.2d%02.2d%02.2d%02.2d.%06.6d+000",
  52. st.wYear, st.wMonth, st.wDay, st.wHour,
  53. st.wMinute, st.wSecond, nMicro );
  54. return TRUE;
  55. }
  56. BOOL SecondsToDateTime( long double ldbSeconds, LPWSTR wszText )
  57. {
  58. FILETIME* pft;
  59. __int64 llnss = __int64(ldbSeconds * 10000000);
  60. pft = (FILETIME*)&llnss;
  61. return FileTimeToDateTime( pft, wszText );
  62. }
  63. BOOL IntervalToSeconds( LPCWSTR wszText, long double& rldbSeconds )
  64. {
  65. int nDay, nHour, nMinute, nSecond, nMicro;
  66. int nRes = swscanf( wszText, L"%8d%2d%2d%2d.%6d",
  67. &nDay, &nHour, &nMinute, &nSecond, &nMicro );
  68. if ( nRes != 5 )
  69. {
  70. return FALSE;
  71. }
  72. rldbSeconds = nSecond + 60*nMinute + 3600*nHour + 86400*nDay;
  73. rldbSeconds += nMicro / 1000000.0;
  74. return TRUE;
  75. }
  76. BOOL DateTimeToSeconds( LPCWSTR wszText, long double& rldbSeconds )
  77. {
  78. WORD nYear, nMonth, nDay, nHour, nMinute, nSecond, nMicro, nOffset;
  79. WCHAR wchSep;
  80. int nRes = swscanf( wszText, L"%4d%2d%2d%2d%2d%2d.%6d%c%3d",
  81. &nYear, &nMonth, &nDay, &nHour, &nMinute,
  82. &nSecond, &nMicro, &wchSep, &nOffset );
  83. if(nRes != 9)
  84. {
  85. return FALSE;
  86. }
  87. int nSign;
  88. if( wchSep == L'+' )
  89. {
  90. nSign = -1;
  91. }
  92. else if ( wchSep == L'-' )
  93. {
  94. nSign = 1;
  95. }
  96. else
  97. {
  98. return FALSE;
  99. }
  100. // Convert it to SYSTEMTIME
  101. // ========================
  102. SYSTEMTIME st;
  103. st.wYear = nYear;
  104. st.wMonth = nMonth;
  105. st.wDay = nDay;
  106. st.wHour = nHour;
  107. st.wMinute = nMinute;
  108. st.wSecond = nSecond;
  109. st.wMilliseconds = 0;
  110. //
  111. // convert SYSTEMTIME to FILETIME
  112. //
  113. FILETIME ft;
  114. if ( !SystemTimeToFileTime( &st, &ft ) )
  115. {
  116. return FALSE;
  117. }
  118. rldbSeconds = (long double)*(__int64*)&ft;
  119. rldbSeconds += nMicro*10;
  120. rldbSeconds /= 10000000;
  121. // Now adjust for the offset
  122. // =========================
  123. rldbSeconds += nSign * nOffset * 60;
  124. return TRUE;
  125. }
  126. BOOL DMTFToSeconds( LPCWSTR wszText, long double& rldbSeconds )
  127. {
  128. if( wcslen(wszText) != 25 )
  129. {
  130. return FALSE;
  131. }
  132. if ( wszText[21] != ':' )
  133. {
  134. return DateTimeToSeconds( wszText, rldbSeconds );
  135. }
  136. return IntervalToSeconds( wszText, rldbSeconds );
  137. }
  138. CCimValue::CCimValue( ) : m_eType( e_Int ), m_iVal( 0 ) { }
  139. HRESULT CCimValue::GetValue( VARIANT& rvValue, ULONG lCimType )
  140. {
  141. VariantInit( &rvValue );
  142. WCHAR achBuff[255];
  143. BOOL bRes;
  144. switch( lCimType )
  145. {
  146. case CIM_SINT8:
  147. case CIM_SINT16:
  148. case CIM_SINT32:
  149. case CIM_BOOLEAN:
  150. CoerceToInt();
  151. V_VT(&rvValue) = VT_I4;
  152. V_I4(&rvValue) = m_iVal;
  153. break;
  154. case CIM_UINT8:
  155. case CIM_UINT16:
  156. case CIM_UINT32:
  157. CoerceToUnsignedInt();
  158. V_VT(&rvValue) = VT_I4;
  159. V_I4(&rvValue) = m_uiVal;
  160. break;
  161. case CIM_SINT64:
  162. case CIM_STRING:
  163. CoerceToLong();
  164. _i64tow( m_lVal, achBuff, 10 );
  165. V_VT(&rvValue) = VT_BSTR;
  166. V_BSTR(&rvValue) = SysAllocString(achBuff);
  167. break;
  168. case CIM_REAL32:
  169. CoerceToFloat();
  170. V_VT(&rvValue) = VT_R4;
  171. V_R4(&rvValue) = m_fVal;
  172. break;
  173. case CIM_REAL64:
  174. CoerceToDouble();
  175. V_VT(&rvValue) = VT_R8;
  176. V_R8(&rvValue) = m_dbVal;
  177. break;
  178. case CIM_UINT64:
  179. CoerceToUnsignedLong();
  180. _ui64tow( m_ulVal, achBuff, 10 );
  181. V_VT(&rvValue) = VT_BSTR;
  182. V_BSTR(&rvValue) = SysAllocString(achBuff);
  183. break;
  184. case CIM_INTERVAL:
  185. CoerceToLongDouble();
  186. bRes = SecondsToInterval( m_ldbVal, achBuff );
  187. if ( !bRes ) { return WBEM_E_TYPE_MISMATCH; }
  188. V_VT(&rvValue) = VT_BSTR;
  189. V_BSTR(&rvValue) = SysAllocString(achBuff);
  190. break;
  191. case CIM_DATETIME:
  192. CoerceToLongDouble();
  193. bRes = SecondsToDateTime( m_ldbVal, achBuff );
  194. if ( !bRes ) { return WBEM_E_TYPE_MISMATCH; }
  195. V_VT(&rvValue) = VT_BSTR;
  196. V_BSTR(&rvValue) = SysAllocString(achBuff);
  197. break;
  198. default:
  199. return WBEM_E_TYPE_MISMATCH;
  200. };
  201. return WBEM_S_NO_ERROR;
  202. }
  203. HRESULT CCimValue::SetValue( VARIANT& rvValue, ULONG lCimType )
  204. {
  205. HRESULT hr;
  206. VARIANT vValue;
  207. VariantInit( &vValue );
  208. if ( lCimType == CIM_EMPTY )
  209. {
  210. //
  211. // must be a numeric value.
  212. //
  213. switch( V_VT(&rvValue) )
  214. {
  215. case VT_R4:
  216. m_eType = e_Float;
  217. m_fVal = V_R4(&rvValue);
  218. break;
  219. case VT_R8:
  220. m_eType = e_Double;
  221. m_dbVal = V_R8(&rvValue);
  222. break;
  223. case VT_BSTR:
  224. m_lVal = (__int64)_wtoi64( V_BSTR(&rvValue) );
  225. break;
  226. default:
  227. hr = VariantChangeType( &vValue, &rvValue, 0, VT_I4 );
  228. if ( FAILED(hr) ) return WBEM_E_TYPE_MISMATCH;
  229. m_eType = e_Int;
  230. m_iVal = V_I4(&vValue);
  231. };
  232. return WBEM_S_NO_ERROR;
  233. }
  234. switch( lCimType )
  235. {
  236. case CIM_SINT8:
  237. case CIM_SINT16:
  238. case CIM_SINT32:
  239. case CIM_BOOLEAN:
  240. hr = VariantChangeType( &vValue, &rvValue, 0, VT_I4 );
  241. if ( FAILED(hr) ) return WBEM_E_TYPE_MISMATCH;
  242. m_eType = e_Int;
  243. m_iVal = V_I4(&vValue);
  244. break;
  245. case CIM_UINT8:
  246. case CIM_UINT16:
  247. case CIM_UINT32:
  248. hr = VariantChangeType( &vValue, &rvValue, 0, VT_UI4 );
  249. if ( FAILED(hr) ) return WBEM_E_TYPE_MISMATCH;
  250. m_eType = e_UnsignedInt;
  251. m_uiVal = V_UI4(&vValue);
  252. break;
  253. case CIM_SINT64:
  254. case CIM_STRING:
  255. if ( V_VT(&rvValue) == VT_BSTR )
  256. {
  257. m_lVal = _wtoi64( V_BSTR(&rvValue) );
  258. }
  259. else
  260. {
  261. return WBEM_E_TYPE_MISMATCH;
  262. }
  263. m_eType = e_Long;
  264. break;
  265. case CIM_UINT64:
  266. if ( V_VT(&rvValue) == VT_BSTR )
  267. {
  268. m_ulVal = (unsigned __int64)_wtoi64( V_BSTR(&rvValue) );
  269. }
  270. else
  271. {
  272. return WBEM_E_TYPE_MISMATCH;
  273. }
  274. m_eType = e_UnsignedLong;
  275. break;
  276. case CIM_REAL32:
  277. hr = VariantChangeType( &vValue, &rvValue, 0, VT_R4 );
  278. if ( FAILED(hr) ) return WBEM_E_TYPE_MISMATCH;
  279. m_eType = CCimValue::e_Float;
  280. m_fVal = V_R4(&vValue);
  281. break;
  282. case CIM_REAL64:
  283. hr = VariantChangeType( &vValue, &rvValue, 0, VT_R8 );
  284. if ( FAILED(hr) ) return WBEM_E_TYPE_MISMATCH;
  285. m_eType = CCimValue::e_Double;
  286. m_dbVal = V_R8(&vValue);
  287. break;
  288. case CIM_DATETIME:
  289. case CIM_INTERVAL:
  290. if ( V_VT(&rvValue) == VT_BSTR )
  291. {
  292. BOOL bRes = DMTFToSeconds( V_BSTR(&rvValue), m_ldbVal );
  293. if ( !bRes )
  294. {
  295. return WBEM_E_TYPE_MISMATCH;
  296. }
  297. }
  298. else
  299. {
  300. return WBEM_E_TYPE_MISMATCH;
  301. }
  302. m_eType = e_LongDouble;
  303. break;
  304. default:
  305. return WBEM_E_TYPE_MISMATCH;
  306. };
  307. return WBEM_S_NO_ERROR;
  308. }
  309. void CCimValue::CoerceToLongDouble()
  310. {
  311. switch( m_eType )
  312. {
  313. case e_Int:
  314. m_ldbVal = (long double)m_iVal;
  315. break;
  316. case e_UnsignedInt:
  317. m_ldbVal = (long double)m_uiVal;
  318. break;
  319. case e_Float:
  320. m_ldbVal = (long double)m_fVal;
  321. break;
  322. case e_Double:
  323. m_ldbVal = (long double)m_dbVal;
  324. break;
  325. case e_Long:
  326. m_ldbVal = (long double)m_lVal;
  327. break;
  328. case e_UnsignedLong:
  329. m_ldbVal = (long double)(__int64)m_ulVal;
  330. break;
  331. };
  332. m_eType = e_LongDouble;
  333. }
  334. void CCimValue::CoerceToDouble()
  335. {
  336. switch( m_eType )
  337. {
  338. case e_Int:
  339. m_dbVal = (double)m_iVal;
  340. break;
  341. case e_UnsignedInt:
  342. m_dbVal = (double)m_uiVal;
  343. break;
  344. case e_Float:
  345. m_dbVal = (double)m_fVal;
  346. break;
  347. case e_LongDouble:
  348. m_dbVal = (double)m_ldbVal;
  349. break;
  350. case e_Long:
  351. m_dbVal = (double)m_lVal;
  352. break;
  353. case e_UnsignedLong:
  354. m_dbVal = (double)(__int64)m_ulVal;
  355. break;
  356. };
  357. m_eType = e_Double;
  358. }
  359. void CCimValue::CoerceToFloat()
  360. {
  361. switch( m_eType )
  362. {
  363. case e_Int:
  364. m_fVal = (float)m_iVal;
  365. break;
  366. case e_UnsignedInt:
  367. m_fVal = (float)m_uiVal;
  368. break;
  369. case e_LongDouble:
  370. m_fVal = (float)m_ldbVal;
  371. break;
  372. case e_Double:
  373. m_fVal = (float)m_dbVal;
  374. break;
  375. case e_Long:
  376. m_fVal = (float)m_lVal;
  377. break;
  378. case e_UnsignedLong:
  379. m_fVal = (float)(__int64)m_ulVal;
  380. break;
  381. };
  382. m_eType = e_Float;
  383. }
  384. void CCimValue::CoerceToUnsignedLong()
  385. {
  386. switch( m_eType )
  387. {
  388. case e_Int:
  389. m_ulVal = (unsigned __int64)m_iVal;
  390. break;
  391. case e_UnsignedInt:
  392. m_ulVal = (unsigned __int64)m_uiVal;
  393. break;
  394. case e_Float:
  395. m_ulVal = (unsigned __int64)m_fVal;
  396. break;
  397. case e_Double:
  398. m_ulVal = (unsigned __int64)m_dbVal;
  399. break;
  400. case e_Long:
  401. m_ulVal = (unsigned __int64)m_lVal;
  402. break;
  403. case e_LongDouble:
  404. m_ulVal = (unsigned __int64)m_ldbVal;
  405. break;
  406. };
  407. m_eType = e_UnsignedLong;
  408. }
  409. void CCimValue::CoerceToLong()
  410. {
  411. switch( m_eType )
  412. {
  413. case e_Int:
  414. m_lVal = (__int64)m_iVal;
  415. break;
  416. case e_UnsignedInt:
  417. m_lVal = (__int64)m_uiVal;
  418. break;
  419. case e_Float:
  420. m_lVal = (__int64)m_fVal;
  421. break;
  422. case e_Double:
  423. m_lVal = (__int64)m_dbVal;
  424. break;
  425. case e_UnsignedLong:
  426. m_lVal = (__int64)m_ulVal;
  427. break;
  428. case e_LongDouble:
  429. m_lVal = (__int64)m_ldbVal;
  430. break;
  431. };
  432. m_eType = e_Long;
  433. }
  434. void CCimValue::CoerceToUnsignedInt()
  435. {
  436. switch( m_eType )
  437. {
  438. case e_Int:
  439. m_uiVal = (unsigned __int32)m_iVal;
  440. break;
  441. case e_Float:
  442. m_uiVal = (unsigned __int32)m_fVal;
  443. break;
  444. case e_Double:
  445. m_uiVal = (unsigned __int32)m_dbVal;
  446. break;
  447. case e_Long:
  448. m_uiVal = (unsigned __int32)m_lVal;
  449. break;
  450. case e_UnsignedLong:
  451. m_uiVal = (unsigned __int32)m_ulVal;
  452. break;
  453. case e_LongDouble:
  454. m_uiVal = (unsigned __int32)m_ldbVal;
  455. break;
  456. };
  457. m_eType = e_UnsignedInt;
  458. }
  459. void CCimValue::CoerceToInt()
  460. {
  461. switch( m_eType )
  462. {
  463. case e_Long:
  464. m_iVal = (__int32)m_lVal;
  465. break;
  466. case e_UnsignedInt:
  467. m_iVal = (__int32)m_uiVal;
  468. break;
  469. case e_Float:
  470. m_iVal = (__int32)m_fVal;
  471. break;
  472. case e_Double:
  473. m_iVal = (__int32)m_dbVal;
  474. break;
  475. case e_UnsignedLong:
  476. m_iVal = (__int32)m_ulVal;
  477. break;
  478. case e_LongDouble:
  479. m_iVal = (__int32)m_ldbVal;
  480. break;
  481. };
  482. m_eType = e_Int;
  483. }
  484. void HandleConversion( CCimValue& rValA, CCimValue& rValB )
  485. {
  486. if ( rValA.m_eType == rValB.m_eType )
  487. {
  488. return;
  489. }
  490. if ( rValA.m_eType == CCimValue::e_LongDouble )
  491. {
  492. rValB.CoerceToLongDouble();
  493. return;
  494. }
  495. if ( rValB.m_eType == CCimValue::e_LongDouble )
  496. {
  497. rValA.CoerceToLongDouble();
  498. return;
  499. }
  500. if ( rValA.m_eType == CCimValue::e_Double )
  501. {
  502. rValB.CoerceToDouble();
  503. return;
  504. }
  505. if ( rValB.m_eType == CCimValue::e_Double )
  506. {
  507. rValA.CoerceToDouble();
  508. return;
  509. }
  510. if ( rValA.m_eType == CCimValue::e_Float )
  511. {
  512. rValB.CoerceToFloat();
  513. return;
  514. }
  515. if ( rValB.m_eType == CCimValue::e_Float )
  516. {
  517. rValA.CoerceToFloat();
  518. return;
  519. }
  520. if ( rValA.m_eType == CCimValue::e_UnsignedLong )
  521. {
  522. rValB.CoerceToUnsignedLong();
  523. return;
  524. }
  525. if ( rValB.m_eType == CCimValue::e_UnsignedLong )
  526. {
  527. rValA.CoerceToUnsignedLong();
  528. return;
  529. }
  530. if ( rValA.m_eType == CCimValue::e_Long &&
  531. rValB.m_eType == CCimValue::e_UnsignedInt ||
  532. rValB.m_eType == CCimValue::e_Long &&
  533. rValA.m_eType == CCimValue::e_UnsignedInt )
  534. {
  535. rValA.CoerceToUnsignedLong();
  536. rValB.CoerceToUnsignedLong();
  537. return;
  538. }
  539. if ( rValA.m_eType == CCimValue::e_Long )
  540. {
  541. rValB.CoerceToLong();
  542. return;
  543. }
  544. if ( rValB.m_eType == CCimValue::e_Long )
  545. {
  546. rValA.CoerceToLong();
  547. return;
  548. }
  549. if ( rValA.m_eType == CCimValue::e_UnsignedInt )
  550. {
  551. rValB.CoerceToUnsignedInt();
  552. return;
  553. }
  554. if ( rValB.m_eType == CCimValue::e_UnsignedInt )
  555. {
  556. rValA.CoerceToUnsignedInt();
  557. return;
  558. }
  559. // this means both must be e_Int, but our check in the beginning
  560. // should have handled this...
  561. assert( 0 );
  562. }
  563. CCimValue operator+ ( CCimValue ValA, CCimValue ValB )
  564. {
  565. HandleConversion( ValA, ValB );
  566. assert( ValA.m_eType == ValB.m_eType );
  567. switch( ValA.m_eType )
  568. {
  569. case CCimValue::e_Int:
  570. ValA.m_iVal += ValB.m_iVal;
  571. break;
  572. case CCimValue::e_UnsignedInt:
  573. ValA.m_uiVal += ValB.m_uiVal;
  574. break;
  575. case CCimValue::e_Float:
  576. ValA.m_fVal += ValB.m_fVal;
  577. break;
  578. case CCimValue::e_Double:
  579. ValA.m_dbVal += ValB.m_dbVal;
  580. break;
  581. case CCimValue::e_LongDouble:
  582. ValA.m_ldbVal += ValB.m_ldbVal;
  583. break;
  584. case CCimValue::e_Long:
  585. ValA.m_lVal += ValB.m_lVal;
  586. break;
  587. case CCimValue::e_UnsignedLong:
  588. ValA.m_ulVal += ValB.m_ulVal;
  589. break;
  590. default:
  591. assert(0);
  592. };
  593. return ValA;
  594. }
  595. CCimValue operator- ( CCimValue ValA, CCimValue ValB )
  596. {
  597. HandleConversion( ValA, ValB );
  598. assert( ValA.m_eType == ValB.m_eType );
  599. switch( ValA.m_eType )
  600. {
  601. case CCimValue::e_Int:
  602. ValA.m_iVal -= ValB.m_iVal;
  603. break;
  604. case CCimValue::e_UnsignedInt:
  605. ValA.m_uiVal -= ValB.m_uiVal;
  606. break;
  607. case CCimValue::e_Float:
  608. ValA.m_fVal -= ValB.m_fVal;
  609. break;
  610. case CCimValue::e_Double:
  611. ValA.m_dbVal -= ValB.m_dbVal;
  612. break;
  613. case CCimValue::e_Long:
  614. ValA.m_lVal -= ValB.m_lVal;
  615. break;
  616. case CCimValue::e_UnsignedLong:
  617. ValA.m_ulVal -= ValB.m_ulVal;
  618. break;
  619. case CCimValue::e_LongDouble:
  620. ValA.m_ldbVal -= ValB.m_ldbVal;
  621. break;
  622. default:
  623. assert(0);
  624. };
  625. return ValA;
  626. }
  627. CCimValue operator* ( CCimValue ValA, CCimValue ValB )
  628. {
  629. HandleConversion( ValA, ValB );
  630. assert( ValA.m_eType == ValB.m_eType );
  631. switch( ValA.m_eType )
  632. {
  633. case CCimValue::e_Int:
  634. ValA.m_iVal *= ValB.m_iVal;
  635. break;
  636. case CCimValue::e_UnsignedInt:
  637. ValA.m_uiVal *= ValB.m_uiVal;
  638. break;
  639. case CCimValue::e_Float:
  640. ValA.m_fVal *= ValB.m_fVal;
  641. break;
  642. case CCimValue::e_Double:
  643. ValA.m_dbVal *= ValB.m_dbVal;
  644. break;
  645. case CCimValue::e_Long:
  646. ValA.m_lVal *= ValB.m_lVal;
  647. break;
  648. case CCimValue::e_UnsignedLong:
  649. ValA.m_ulVal *= ValB.m_ulVal;
  650. break;
  651. case CCimValue::e_LongDouble:
  652. ValA.m_ldbVal *= ValB.m_ldbVal;
  653. break;
  654. default:
  655. assert(0);
  656. };
  657. return ValA;
  658. }
  659. CCimValue operator/ ( CCimValue ValA, CCimValue ValB )
  660. {
  661. HandleConversion( ValA, ValB );
  662. assert( ValA.m_eType == ValB.m_eType );
  663. //
  664. // will raise a structured exception if div by 0.
  665. // caller is expected to handle this..
  666. //
  667. switch( ValA.m_eType )
  668. {
  669. case CCimValue::e_Int:
  670. if ( ValB.m_iVal == 0 ) throw CX_DivideByZeroException();
  671. ValA.m_iVal /= ValB.m_iVal;
  672. break;
  673. case CCimValue::e_UnsignedInt:
  674. if ( ValB.m_uiVal == 0 ) throw CX_DivideByZeroException();
  675. ValA.m_uiVal /= ValB.m_uiVal;
  676. break;
  677. case CCimValue::e_Float:
  678. if ( ValB.m_fVal == 0 ) throw CX_DivideByZeroException();
  679. ValA.m_fVal /= ValB.m_fVal;
  680. break;
  681. case CCimValue::e_Double:
  682. if ( ValB.m_dbVal == 0 ) throw CX_DivideByZeroException();
  683. ValA.m_dbVal /= ValB.m_dbVal;
  684. break;
  685. case CCimValue::e_Long:
  686. if ( ValB.m_lVal == 0 ) throw CX_DivideByZeroException();
  687. ValA.m_lVal /= ValB.m_lVal;
  688. break;
  689. case CCimValue::e_UnsignedLong:
  690. if ( ValB.m_ulVal == 0 ) throw CX_DivideByZeroException();
  691. ValA.m_ulVal /= ValB.m_ulVal;
  692. break;
  693. case CCimValue::e_LongDouble:
  694. if ( ValB.m_ldbVal == 0 ) throw CX_DivideByZeroException();
  695. ValA.m_ldbVal /= ValB.m_ldbVal;
  696. break;
  697. default:
  698. assert(0);
  699. };
  700. return ValA;
  701. }
  702. CCimValue operator% ( CCimValue ValA, CCimValue ValB )
  703. {
  704. HandleConversion( ValA, ValB );
  705. assert( ValA.m_eType == ValB.m_eType );
  706. //
  707. // will raise a structured exception if div by 0.
  708. // caller is expected to handle this..
  709. //
  710. switch( ValA.m_eType )
  711. {
  712. case CCimValue::e_Int:
  713. if ( ValB.m_iVal == 0 ) throw CX_DivideByZeroException();
  714. ValA.m_iVal %= ValB.m_iVal;
  715. break;
  716. case CCimValue::e_UnsignedInt:
  717. if ( ValB.m_uiVal == 0 ) throw CX_DivideByZeroException();
  718. ValA.m_uiVal %= ValB.m_uiVal;
  719. break;
  720. case CCimValue::e_Float:
  721. case CCimValue::e_Double:
  722. case CCimValue::e_LongDouble:
  723. throw CX_InvalidFloatingPointOperationException();
  724. case CCimValue::e_Long:
  725. if ( ValB.m_lVal == 0 ) throw CX_DivideByZeroException();
  726. ValA.m_lVal %= ValB.m_lVal;
  727. break;
  728. case CCimValue::e_UnsignedLong:
  729. if ( ValB.m_ulVal == 0 ) throw CX_DivideByZeroException();
  730. ValA.m_ulVal %= ValB.m_ulVal;
  731. break;
  732. default:
  733. assert(0);
  734. };
  735. return ValA;
  736. }