RepresentationConverter.cs 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152
  1. /* Copyright 2010-present MongoDB Inc.
  2. *
  3. * Licensed under the Apache License, Version 2.0 (the "License");
  4. * you may not use this file except in compliance with the License.
  5. * You may obtain a copy of the License at
  6. *
  7. * http://www.apache.org/licenses/LICENSE-2.0
  8. *
  9. * Unless required by applicable law or agreed to in writing, software
  10. * distributed under the License is distributed on an "AS IS" BASIS,
  11. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. * See the License for the specific language governing permissions and
  13. * limitations under the License.
  14. */
  15. using System;
  16. using MongoDB.Bson.Serialization.Attributes;
  17. namespace MongoDB.Bson.Serialization.Options
  18. {
  19. /// <summary>
  20. /// Represents the external representation of a field or property.
  21. /// </summary>
  22. public class RepresentationConverter
  23. {
  24. // private fields
  25. private bool _allowOverflow;
  26. private bool _allowTruncation;
  27. // constructors
  28. /// <summary>
  29. /// Initializes a new instance of the RepresentationConverter class.
  30. /// </summary>
  31. /// <param name="allowOverflow">Whether to allow overflow.</param>
  32. /// <param name="allowTruncation">Whether to allow truncation.</param>
  33. public RepresentationConverter(bool allowOverflow, bool allowTruncation)
  34. {
  35. _allowOverflow = allowOverflow;
  36. _allowTruncation = allowTruncation;
  37. }
  38. // public properties
  39. /// <summary>
  40. /// Gets whether to allow overflow.
  41. /// </summary>
  42. public bool AllowOverflow
  43. {
  44. get { return _allowOverflow; }
  45. }
  46. /// <summary>
  47. /// Gets whether to allow truncation.
  48. /// </summary>
  49. public bool AllowTruncation
  50. {
  51. get { return _allowTruncation; }
  52. }
  53. // public methods
  54. /// <summary>
  55. /// Converts a Decimal128 to a Decimal.
  56. /// </summary>
  57. /// <param name="value">A Decimal128.</param>
  58. /// <returns>A Decimal.</returns>
  59. public decimal ToDecimal(Decimal128 value)
  60. {
  61. if (value == Decimal128.MaxValue)
  62. {
  63. return decimal.MaxValue;
  64. }
  65. else if (value == Decimal128.MinValue)
  66. {
  67. return decimal.MinValue;
  68. }
  69. else if (Decimal128.IsInfinity(value) || Decimal128.IsNaN(value))
  70. {
  71. throw new OverflowException();
  72. }
  73. decimal decimalValue;
  74. if (_allowOverflow)
  75. {
  76. try { decimalValue = (decimal)value; } catch (OverflowException) { decimalValue = Decimal128.IsNegative(value) ? decimal.MinValue : decimal.MaxValue; }
  77. }
  78. else
  79. {
  80. decimalValue = (decimal)value;
  81. }
  82. if (!_allowTruncation && value != (Decimal128)decimalValue)
  83. {
  84. throw new TruncationException();
  85. }
  86. return decimalValue;
  87. }
  88. /// <summary>
  89. /// Converts a Double to a Decimal.
  90. /// </summary>
  91. /// <param name="value">A Double.</param>
  92. /// <returns>A Decimal.</returns>
  93. public decimal ToDecimal(double value)
  94. {
  95. if (value == double.MinValue)
  96. {
  97. return decimal.MinValue;
  98. }
  99. else if (value == double.MaxValue)
  100. {
  101. return decimal.MaxValue;
  102. }
  103. var decimalValue = (decimal)value;
  104. if (value < (double)decimal.MinValue || value > (double)decimal.MaxValue)
  105. {
  106. if (!_allowOverflow) { throw new OverflowException(); }
  107. }
  108. else if (value != (double)decimalValue)
  109. {
  110. if (!_allowTruncation) { throw new TruncationException(); }
  111. }
  112. return decimalValue;
  113. }
  114. /// <summary>
  115. /// Converts an Int32 to a Decimal.
  116. /// </summary>
  117. /// <param name="value">An Int32.</param>
  118. /// <returns>A Decimal.</returns>
  119. public decimal ToDecimal(int value)
  120. {
  121. return (decimal)value;
  122. }
  123. /// <summary>
  124. /// Converts an Int64 to a Decimal.
  125. /// </summary>
  126. /// <param name="value">An Int64.</param>
  127. /// <returns>A Decimal.</returns>
  128. public decimal ToDecimal(long value)
  129. {
  130. return (decimal)value;
  131. }
  132. /// <summary>
  133. /// Converts a decimal to a Decimal128.
  134. /// </summary>
  135. /// <param name="value">A decimal.</param>
  136. /// <returns>A Decimal128.</returns>
  137. public Decimal128 ToDecimal128(decimal value)
  138. {
  139. if (value == decimal.MaxValue)
  140. {
  141. return Decimal128.MaxValue;
  142. }
  143. else if (value == decimal.MinValue)
  144. {
  145. return Decimal128.MinValue;
  146. }
  147. // conversion from decimal to Decimal128 is lossless so need to check for overflow or truncation
  148. return (Decimal128)value;
  149. }
  150. /// <summary>
  151. /// Converts a Double to a Decimal128.
  152. /// </summary>
  153. /// <param name="value">A Double.</param>
  154. /// <returns>A Decimal128.</returns>
  155. public Decimal128 ToDecimal128(double value)
  156. {
  157. if (value == double.MaxValue)
  158. {
  159. return Decimal128.MaxValue;
  160. }
  161. else if (value == double.MinValue)
  162. {
  163. return Decimal128.MinValue;
  164. }
  165. else if (double.IsPositiveInfinity(value))
  166. {
  167. return Decimal128.PositiveInfinity;
  168. }
  169. else if (double.IsNegativeInfinity(value))
  170. {
  171. return Decimal128.NegativeInfinity;
  172. }
  173. else if (double.IsNaN(value))
  174. {
  175. return Decimal128.QNaN;
  176. }
  177. var decimal128Value = (Decimal128)value;
  178. if (!_allowTruncation && value != (double)decimal128Value)
  179. {
  180. throw new TruncationException();
  181. }
  182. return decimal128Value;
  183. }
  184. /// <summary>
  185. /// Converts an Int32 to a Decimal128.
  186. /// </summary>
  187. /// <param name="value">An Int32.</param>
  188. /// <returns>A Decimal128.</returns>
  189. public Decimal128 ToDecimal128(int value)
  190. {
  191. return (Decimal128)value;
  192. }
  193. /// <summary>
  194. /// Converts an Int64 to a Decimal128.
  195. /// </summary>
  196. /// <param name="value">An Int64.</param>
  197. /// <returns>A Decimal128.</returns>
  198. public Decimal128 ToDecimal128(long value)
  199. {
  200. return (Decimal128)value;
  201. }
  202. /// <summary>
  203. /// Converts a UInt64 to a Decimal128.
  204. /// </summary>
  205. /// <param name="value">A UInt64.</param>
  206. /// <returns>A Decimal128.</returns>
  207. [CLSCompliant(false)]
  208. public Decimal128 ToDecimal128(ulong value)
  209. {
  210. return (Decimal128)value;
  211. }
  212. /// <summary>
  213. /// Converts a Decimal to a Double.
  214. /// </summary>
  215. /// <param name="value">A Decimal.</param>
  216. /// <returns>A Double.</returns>
  217. public double ToDouble(decimal value)
  218. {
  219. if (value == decimal.MinValue)
  220. {
  221. return double.MinValue;
  222. }
  223. else if (value == decimal.MaxValue)
  224. {
  225. return double.MaxValue;
  226. }
  227. var doubleValue = (double)value;
  228. if (value != (decimal)doubleValue)
  229. {
  230. if (!_allowTruncation) { throw new TruncationException(); }
  231. }
  232. return doubleValue;
  233. }
  234. /// <summary>
  235. /// Converts a Decimal128 to a Double.
  236. /// </summary>
  237. /// <param name="value">A Decimal.</param>
  238. /// <returns>A Double.</returns>
  239. public double ToDouble(Decimal128 value)
  240. {
  241. if (value == Decimal128.MaxValue)
  242. {
  243. return double.MaxValue;
  244. }
  245. else if (value == Decimal128.MinValue)
  246. {
  247. return double.MinValue;
  248. }
  249. else if (Decimal128.IsPositiveInfinity(value))
  250. {
  251. return double.PositiveInfinity;
  252. }
  253. else if (Decimal128.IsNegativeInfinity(value))
  254. {
  255. return double.NegativeInfinity;
  256. }
  257. else if (Decimal128.IsNaN(value))
  258. {
  259. return double.NaN;
  260. }
  261. double doubleValue;
  262. if (_allowOverflow)
  263. {
  264. try { doubleValue = (double)value; } catch (OverflowException) { doubleValue = Decimal128.IsNegative(value) ? double.MinValue : double.MaxValue; }
  265. }
  266. else
  267. {
  268. doubleValue = (double)value;
  269. }
  270. if (!_allowTruncation && value != (Decimal128)doubleValue)
  271. {
  272. throw new TruncationException();
  273. }
  274. return doubleValue;
  275. }
  276. /// <summary>
  277. /// Converts a Double to a Double.
  278. /// </summary>
  279. /// <param name="value">A Double.</param>
  280. /// <returns>A Double.</returns>
  281. public double ToDouble(double value)
  282. {
  283. return value;
  284. }
  285. /// <summary>
  286. /// Converts a Single to a Double.
  287. /// </summary>
  288. /// <param name="value">A Single.</param>
  289. /// <returns>A Double.</returns>
  290. public double ToDouble(float value)
  291. {
  292. if (value == float.MinValue)
  293. {
  294. return double.MinValue;
  295. }
  296. else if (value == float.MaxValue)
  297. {
  298. return double.MaxValue;
  299. }
  300. else if (float.IsNegativeInfinity(value))
  301. {
  302. return double.NegativeInfinity;
  303. }
  304. else if (float.IsPositiveInfinity(value))
  305. {
  306. return double.PositiveInfinity;
  307. }
  308. else if (float.IsNaN(value))
  309. {
  310. return double.NaN;
  311. }
  312. return value;
  313. }
  314. /// <summary>
  315. /// Converts an Int32 to a Double.
  316. /// </summary>
  317. /// <param name="value">An Int32.</param>
  318. /// <returns>A Double.</returns>
  319. public double ToDouble(int value)
  320. {
  321. return value;
  322. }
  323. /// <summary>
  324. /// Converts an Int64 to a Double.
  325. /// </summary>
  326. /// <param name="value">An Int64.</param>
  327. /// <returns>A Double.</returns>
  328. public double ToDouble(long value)
  329. {
  330. var doubleValue = (double)value;
  331. if (value != (long)doubleValue)
  332. {
  333. if (!_allowTruncation) { throw new TruncationException(); }
  334. }
  335. return doubleValue;
  336. }
  337. /// <summary>
  338. /// Converts an Int16 to a Double.
  339. /// </summary>
  340. /// <param name="value">An Int16.</param>
  341. /// <returns>A Double.</returns>
  342. public double ToDouble(short value)
  343. {
  344. return value;
  345. }
  346. /// <summary>
  347. /// Converts a UInt32 to a Double.
  348. /// </summary>
  349. /// <param name="value">A UInt32.</param>
  350. /// <returns>A Double.</returns>
  351. [CLSCompliant(false)]
  352. public double ToDouble(uint value)
  353. {
  354. return value;
  355. }
  356. /// <summary>
  357. /// Converts a UInt64 to a Double.
  358. /// </summary>
  359. /// <param name="value">A UInt64.</param>
  360. /// <returns>A Double.</returns>
  361. [CLSCompliant(false)]
  362. public double ToDouble(ulong value)
  363. {
  364. var doubleValue = (double)value;
  365. if (value != (ulong)doubleValue)
  366. {
  367. if (!_allowTruncation) { throw new TruncationException(); }
  368. }
  369. return doubleValue;
  370. }
  371. /// <summary>
  372. /// Converts a UInt16 to a Double.
  373. /// </summary>
  374. /// <param name="value">A UInt16.</param>
  375. /// <returns>A Double.</returns>
  376. [CLSCompliant(false)]
  377. public double ToDouble(ushort value)
  378. {
  379. return value;
  380. }
  381. /// <summary>
  382. /// Converts a Decimal128 to an Int16.
  383. /// </summary>
  384. /// <param name="value">A Decimal128.</param>
  385. /// <returns>An Int16.</returns>
  386. public short ToInt16(Decimal128 value)
  387. {
  388. short shortValue;
  389. if (_allowOverflow)
  390. {
  391. try { shortValue = (short)value; } catch (OverflowException) { shortValue = Decimal128.IsNegative(value) ? short.MinValue : short.MaxValue; }
  392. }
  393. else
  394. {
  395. shortValue = (short)value;
  396. }
  397. if (!_allowTruncation && value != (Decimal128)shortValue)
  398. {
  399. throw new TruncationException();
  400. }
  401. return shortValue;
  402. }
  403. /// <summary>
  404. /// Converts a Double to an Int16.
  405. /// </summary>
  406. /// <param name="value">A Double.</param>
  407. /// <returns>An Int16.</returns>
  408. public short ToInt16(double value)
  409. {
  410. var int16Value = (short)value;
  411. if (value < short.MinValue || value > short.MaxValue)
  412. {
  413. if (!_allowOverflow) { throw new OverflowException(); }
  414. }
  415. else if (value != (double)int16Value)
  416. {
  417. if (!_allowTruncation) { throw new TruncationException(); }
  418. }
  419. return int16Value;
  420. }
  421. /// <summary>
  422. /// Converts an Int32 to an Int16.
  423. /// </summary>
  424. /// <param name="value">An Int32.</param>
  425. /// <returns>An Int16.</returns>
  426. public short ToInt16(int value)
  427. {
  428. if (value < short.MinValue || value > short.MaxValue)
  429. {
  430. if (!_allowOverflow) { throw new OverflowException(); }
  431. }
  432. return (short)value;
  433. }
  434. /// <summary>
  435. /// Converts an Int64 to an Int16.
  436. /// </summary>
  437. /// <param name="value">An Int64.</param>
  438. /// <returns>An Int16.</returns>
  439. public short ToInt16(long value)
  440. {
  441. if (value < short.MinValue || value > short.MaxValue)
  442. {
  443. if (!_allowOverflow) { throw new OverflowException(); }
  444. }
  445. return (short)value;
  446. }
  447. /// <summary>
  448. /// Converts a Decimal to an Int32.
  449. /// </summary>
  450. /// <param name="value">A Decimal.</param>
  451. /// <returns>An Int32.</returns>
  452. public int ToInt32(decimal value)
  453. {
  454. if (value == decimal.MinValue)
  455. {
  456. return int.MinValue;
  457. }
  458. else if (value == decimal.MaxValue)
  459. {
  460. return int.MaxValue;
  461. }
  462. var int32Value = (int)value;
  463. if (value < int.MinValue || value > int.MaxValue)
  464. {
  465. if (!_allowOverflow) { throw new OverflowException(); }
  466. }
  467. else if (value != (decimal)int32Value)
  468. {
  469. if (!_allowTruncation) { throw new TruncationException(); }
  470. }
  471. return int32Value;
  472. }
  473. /// <summary>
  474. /// Converts a Decimal128 to an Int32.
  475. /// </summary>
  476. /// <param name="value">A Decimal128.</param>
  477. /// <returns>An Int32.</returns>
  478. public int ToInt32(Decimal128 value)
  479. {
  480. int intValue;
  481. if (_allowOverflow)
  482. {
  483. try { intValue = (int)value; } catch (OverflowException) { intValue = Decimal128.IsNegative(value) ? int.MinValue : int.MaxValue; }
  484. }
  485. else
  486. {
  487. intValue = (int)value;
  488. }
  489. if (!_allowTruncation && value != (Decimal128)intValue)
  490. {
  491. throw new TruncationException();
  492. }
  493. return intValue;
  494. }
  495. /// <summary>
  496. /// Converts a Double to an Int32.
  497. /// </summary>
  498. /// <param name="value">A Double.</param>
  499. /// <returns>An Int32.</returns>
  500. public int ToInt32(double value)
  501. {
  502. var int32Value = (int)value;
  503. if (value < int.MinValue || value > int.MaxValue)
  504. {
  505. if (!_allowOverflow) { throw new OverflowException(); }
  506. }
  507. else if (value != (double)int32Value)
  508. {
  509. if (!_allowTruncation) { throw new TruncationException(); }
  510. }
  511. return int32Value;
  512. }
  513. /// <summary>
  514. /// Converts a Single to an Int32.
  515. /// </summary>
  516. /// <param name="value">A Single.</param>
  517. /// <returns>An Int32.</returns>
  518. public int ToInt32(float value)
  519. {
  520. var int32Value = (int)value;
  521. if (value < int.MinValue || value > int.MaxValue)
  522. {
  523. if (!_allowOverflow) { throw new OverflowException(); }
  524. }
  525. else if (value != (float)int32Value)
  526. {
  527. if (!_allowTruncation) { throw new TruncationException(); }
  528. }
  529. return int32Value;
  530. }
  531. /// <summary>
  532. /// Converts an Int32 to an Int32.
  533. /// </summary>
  534. /// <param name="value">An Int32.</param>
  535. /// <returns>An Int32.</returns>
  536. public int ToInt32(int value)
  537. {
  538. return value;
  539. }
  540. /// <summary>
  541. /// Converts an Int64 to an Int32.
  542. /// </summary>
  543. /// <param name="value">An Int64.</param>
  544. /// <returns>An Int32.</returns>
  545. public int ToInt32(long value)
  546. {
  547. if (value < int.MinValue || value > int.MaxValue)
  548. {
  549. if (!_allowOverflow) { throw new OverflowException(); }
  550. }
  551. return (int)value;
  552. }
  553. /// <summary>
  554. /// Converts an Int16 to an Int32.
  555. /// </summary>
  556. /// <param name="value">An Int16.</param>
  557. /// <returns>An Int32.</returns>
  558. public int ToInt32(short value)
  559. {
  560. return value;
  561. }
  562. /// <summary>
  563. /// Converts a UInt32 to an Int32.
  564. /// </summary>
  565. /// <param name="value">A UInt32.</param>
  566. /// <returns>An Int32.</returns>
  567. [CLSCompliant(false)]
  568. public int ToInt32(uint value)
  569. {
  570. if (value > (uint)int.MaxValue)
  571. {
  572. if (!_allowOverflow) { throw new OverflowException(); }
  573. }
  574. return (int)value;
  575. }
  576. /// <summary>
  577. /// Converts a UInt64 to an Int32.
  578. /// </summary>
  579. /// <param name="value">A UInt64.</param>
  580. /// <returns>An Int32.</returns>
  581. [CLSCompliant(false)]
  582. public int ToInt32(ulong value)
  583. {
  584. if (value > (ulong)int.MaxValue)
  585. {
  586. if (!_allowOverflow) { throw new OverflowException(); }
  587. }
  588. return (int)value;
  589. }
  590. /// <summary>
  591. /// Converts a UInt16 to an Int32.
  592. /// </summary>
  593. /// <param name="value">A UInt16.</param>
  594. /// <returns>An Int32.</returns>
  595. [CLSCompliant(false)]
  596. public int ToInt32(ushort value)
  597. {
  598. return value;
  599. }
  600. /// <summary>
  601. /// Converts a Decimal to an Int64.
  602. /// </summary>
  603. /// <param name="value">A Decimal.</param>
  604. /// <returns>An Int64.</returns>
  605. public long ToInt64(decimal value)
  606. {
  607. if (value == decimal.MinValue)
  608. {
  609. return long.MinValue;
  610. }
  611. else if (value == decimal.MaxValue)
  612. {
  613. return long.MaxValue;
  614. }
  615. var int64Value = (long)value;
  616. if (value < long.MinValue || value > long.MaxValue)
  617. {
  618. if (!_allowOverflow) { throw new OverflowException(); }
  619. }
  620. else if (value != (decimal)int64Value)
  621. {
  622. if (!_allowTruncation) { throw new TruncationException(); }
  623. }
  624. return int64Value;
  625. }
  626. /// <summary>
  627. /// Converts a Decimal128 to an Int64.
  628. /// </summary>
  629. /// <param name="value">A Decimal128.</param>
  630. /// <returns>An Int64.</returns>
  631. public long ToInt64(Decimal128 value)
  632. {
  633. long longValue;
  634. if (_allowOverflow)
  635. {
  636. try { longValue = (long)value; } catch (OverflowException) { longValue = Decimal128.IsNegative(value) ? long.MinValue : long.MaxValue; }
  637. }
  638. else
  639. {
  640. longValue = (long)value;
  641. }
  642. if (!_allowTruncation && value != (Decimal128)longValue)
  643. {
  644. throw new TruncationException();
  645. }
  646. return longValue;
  647. }
  648. /// <summary>
  649. /// Converts a Double to an Int64.
  650. /// </summary>
  651. /// <param name="value">A Double.</param>
  652. /// <returns>An Int64.</returns>
  653. public long ToInt64(double value)
  654. {
  655. var int64Value = (long)value;
  656. if (value < long.MinValue || value > long.MaxValue)
  657. {
  658. if (!_allowOverflow) { throw new OverflowException(); }
  659. }
  660. else if (value != (double)int64Value)
  661. {
  662. if (!_allowTruncation) { throw new TruncationException(); }
  663. }
  664. return int64Value;
  665. }
  666. /// <summary>
  667. /// Converts a Single to an Int64.
  668. /// </summary>
  669. /// <param name="value">A Single.</param>
  670. /// <returns>An Int64.</returns>
  671. public long ToInt64(float value)
  672. {
  673. var int64Value = (long)value;
  674. if (value < long.MinValue || value > long.MaxValue)
  675. {
  676. if (!_allowOverflow) { throw new OverflowException(); }
  677. }
  678. else if (value != (float)int64Value)
  679. {
  680. if (!_allowTruncation) { throw new TruncationException(); }
  681. }
  682. return int64Value;
  683. }
  684. /// <summary>
  685. /// Converts an Int32 to an Int64.
  686. /// </summary>
  687. /// <param name="value">An Int32.</param>
  688. /// <returns>An Int64.</returns>
  689. public long ToInt64(int value)
  690. {
  691. return value;
  692. }
  693. /// <summary>
  694. /// Converts an Int64 to an Int64.
  695. /// </summary>
  696. /// <param name="value">An Int64.</param>
  697. /// <returns>An Int64.</returns>
  698. public long ToInt64(long value)
  699. {
  700. return value;
  701. }
  702. /// <summary>
  703. /// Converts an Int16 to an Int64.
  704. /// </summary>
  705. /// <param name="value">An Int16.</param>
  706. /// <returns>An Int64.</returns>
  707. public long ToInt64(short value)
  708. {
  709. return value;
  710. }
  711. /// <summary>
  712. /// Converts a UInt32 to an Int64.
  713. /// </summary>
  714. /// <param name="value">A UInt32.</param>
  715. /// <returns>An Int64.</returns>
  716. [CLSCompliant(false)]
  717. public long ToInt64(uint value)
  718. {
  719. return (long)value;
  720. }
  721. /// <summary>
  722. /// Converts a UInt64 to an Int64.
  723. /// </summary>
  724. /// <param name="value">A UInt64.</param>
  725. /// <returns>An Int64.</returns>
  726. [CLSCompliant(false)]
  727. public long ToInt64(ulong value)
  728. {
  729. if (value > (ulong)long.MaxValue)
  730. {
  731. if (!_allowOverflow) { throw new OverflowException(); }
  732. }
  733. return (long)value;
  734. }
  735. /// <summary>
  736. /// Converts a UInt16 to an Int64.
  737. /// </summary>
  738. /// <param name="value">A UInt16.</param>
  739. /// <returns>An Int64.</returns>
  740. [CLSCompliant(false)]
  741. public long ToInt64(ushort value)
  742. {
  743. return value;
  744. }
  745. /// <summary>
  746. /// Converts a Decimal128 to a Single.
  747. /// </summary>
  748. /// <param name="value">A Decimal128.</param>
  749. /// <returns>A Single.</returns>
  750. public float ToSingle(Decimal128 value)
  751. {
  752. if (value == Decimal128.MaxValue)
  753. {
  754. return float.MaxValue;
  755. }
  756. else if (value == Decimal128.MinValue)
  757. {
  758. return float.MinValue;
  759. }
  760. else if (Decimal128.IsPositiveInfinity(value))
  761. {
  762. return float.PositiveInfinity;
  763. }
  764. else if (Decimal128.IsNegativeInfinity(value))
  765. {
  766. return float.NegativeInfinity;
  767. }
  768. else if (Decimal128.IsNaN(value))
  769. {
  770. return float.NaN;
  771. }
  772. float floatValue;
  773. if (_allowOverflow)
  774. {
  775. try { floatValue = (float)value; } catch (OverflowException) { floatValue = Decimal128.IsNegative(value) ? float.MinValue : float.MaxValue; }
  776. }
  777. else
  778. {
  779. floatValue = (float)value;
  780. }
  781. if (!_allowTruncation && value != (Decimal128)floatValue)
  782. {
  783. throw new TruncationException();
  784. }
  785. return floatValue;
  786. }
  787. /// <summary>
  788. /// Converts a Double to a Single.
  789. /// </summary>
  790. /// <param name="value">A Double.</param>
  791. /// <returns>A Single.</returns>
  792. public float ToSingle(double value)
  793. {
  794. if (value == double.MinValue)
  795. {
  796. return float.MinValue;
  797. }
  798. else if (value == double.MaxValue)
  799. {
  800. return float.MaxValue;
  801. }
  802. else if (double.IsNegativeInfinity(value))
  803. {
  804. return float.NegativeInfinity;
  805. }
  806. else if (double.IsPositiveInfinity(value))
  807. {
  808. return float.PositiveInfinity;
  809. }
  810. else if (double.IsNaN(value))
  811. {
  812. return float.NaN;
  813. }
  814. var floatValue = (float)value;
  815. if (value < float.MinValue || value > float.MaxValue)
  816. {
  817. if (!_allowOverflow) { throw new OverflowException(); }
  818. }
  819. else if (value != (double)floatValue)
  820. {
  821. if (!_allowTruncation) { throw new TruncationException(); }
  822. }
  823. return floatValue;
  824. }
  825. /// <summary>
  826. /// Converts an Int32 to a Single.
  827. /// </summary>
  828. /// <param name="value">An Int32.</param>
  829. /// <returns>A Single.</returns>
  830. public float ToSingle(int value)
  831. {
  832. var floatValue = (float)value;
  833. if (value != (int)floatValue)
  834. {
  835. if (!_allowTruncation) { throw new TruncationException(); }
  836. }
  837. return floatValue;
  838. }
  839. /// <summary>
  840. /// Converts an Int64 to a Single.
  841. /// </summary>
  842. /// <param name="value">An Int64.</param>
  843. /// <returns>A Single.</returns>
  844. public float ToSingle(long value)
  845. {
  846. var floatValue = (float)value;
  847. if (value != (long)floatValue)
  848. {
  849. if (!_allowTruncation) { throw new TruncationException(); }
  850. }
  851. return floatValue;
  852. }
  853. /// <summary>
  854. /// Converts a Decimal128 to a UInt16.
  855. /// </summary>
  856. /// <param name="value">A Decimal128.</param>
  857. /// <returns>A UInt16.</returns>
  858. [CLSCompliant(false)]
  859. public ushort ToUInt16(Decimal128 value)
  860. {
  861. ushort ushortValue;
  862. if (_allowOverflow)
  863. {
  864. try { ushortValue = (ushort)value; } catch (OverflowException) { ushortValue = Decimal128.IsNegative(value) ? ushort.MinValue : ushort.MaxValue; }
  865. }
  866. else
  867. {
  868. ushortValue = (ushort)value;
  869. }
  870. if (!_allowTruncation && value != (Decimal128)ushortValue)
  871. {
  872. throw new TruncationException();
  873. }
  874. return ushortValue;
  875. }
  876. /// <summary>
  877. /// Converts a Double to a UInt16.
  878. /// </summary>
  879. /// <param name="value">A Double.</param>
  880. /// <returns>A UInt16.</returns>
  881. [CLSCompliant(false)]
  882. public ushort ToUInt16(double value)
  883. {
  884. var uint16Value = (ushort)value;
  885. if (value < ushort.MinValue || value > ushort.MaxValue)
  886. {
  887. if (!_allowOverflow) { throw new OverflowException(); }
  888. }
  889. else if (value != (double)uint16Value)
  890. {
  891. if (!_allowTruncation) { throw new TruncationException(); }
  892. }
  893. return uint16Value;
  894. }
  895. /// <summary>
  896. /// Converts an Int32 to a UInt16.
  897. /// </summary>
  898. /// <param name="value">An Int32.</param>
  899. /// <returns>A UInt16.</returns>
  900. [CLSCompliant(false)]
  901. public ushort ToUInt16(int value)
  902. {
  903. if (value < ushort.MinValue || value > ushort.MaxValue)
  904. {
  905. if (!_allowOverflow) { throw new OverflowException(); }
  906. }
  907. return (ushort)value;
  908. }
  909. /// <summary>
  910. /// Converts an Int64 to a UInt16.
  911. /// </summary>
  912. /// <param name="value">An Int64.</param>
  913. /// <returns>A UInt16.</returns>
  914. [CLSCompliant(false)]
  915. public ushort ToUInt16(long value)
  916. {
  917. if (value < ushort.MinValue || value > ushort.MaxValue)
  918. {
  919. if (!_allowOverflow) { throw new OverflowException(); }
  920. }
  921. return (ushort)value;
  922. }
  923. /// <summary>
  924. /// Converts a Decimal128 to a UInt32.
  925. /// </summary>
  926. /// <param name="value">A Decimal128.</param>
  927. /// <returns>A UInt32.</returns>
  928. [CLSCompliant(false)]
  929. public uint ToUInt32(Decimal128 value)
  930. {
  931. uint uintValue;
  932. if (_allowOverflow)
  933. {
  934. try { uintValue = (uint)value; } catch (OverflowException) { uintValue = Decimal128.IsNegative(value) ? uint.MinValue : uint.MaxValue; }
  935. }
  936. else
  937. {
  938. uintValue = (uint)value;
  939. }
  940. if (!_allowTruncation && value != (Decimal128)uintValue)
  941. {
  942. throw new TruncationException();
  943. }
  944. return uintValue;
  945. }
  946. /// <summary>
  947. /// Converts a Double to a UInt32.
  948. /// </summary>
  949. /// <param name="value">A Double.</param>
  950. /// <returns>A UInt32.</returns>
  951. [CLSCompliant(false)]
  952. public uint ToUInt32(double value)
  953. {
  954. var uint32Value = (uint)value;
  955. if (value < uint.MinValue || value > uint.MaxValue)
  956. {
  957. if (!_allowOverflow) { throw new OverflowException(); }
  958. }
  959. else if (value != (double)uint32Value)
  960. {
  961. if (!_allowTruncation) { throw new TruncationException(); }
  962. }
  963. return uint32Value;
  964. }
  965. /// <summary>
  966. /// Converts an Int32 to a UInt32.
  967. /// </summary>
  968. /// <param name="value">An Int32.</param>
  969. /// <returns>A UInt32.</returns>
  970. [CLSCompliant(false)]
  971. public uint ToUInt32(int value)
  972. {
  973. if (value < uint.MinValue)
  974. {
  975. if (!_allowOverflow) { throw new OverflowException(); }
  976. }
  977. return (uint)value;
  978. }
  979. /// <summary>
  980. /// Converts an Int64 to a UInt32.
  981. /// </summary>
  982. /// <param name="value">An Int64.</param>
  983. /// <returns>A UInt32.</returns>
  984. [CLSCompliant(false)]
  985. public uint ToUInt32(long value)
  986. {
  987. if (value < uint.MinValue || value > uint.MaxValue)
  988. {
  989. if (!_allowOverflow) { throw new OverflowException(); }
  990. }
  991. return (uint)value;
  992. }
  993. /// <summary>
  994. /// Converts a Decimal128 to a UInt64.
  995. /// </summary>
  996. /// <param name="value">A Decimal128.</param>
  997. /// <returns>A UInt64.</returns>
  998. [CLSCompliant(false)]
  999. public ulong ToUInt64(Decimal128 value)
  1000. {
  1001. ulong ulongValue;
  1002. if (_allowOverflow)
  1003. {
  1004. try { ulongValue = (ulong)value; } catch (OverflowException) { ulongValue = Decimal128.IsNegative(value) ? ulong.MinValue : ulong.MaxValue; }
  1005. }
  1006. else
  1007. {
  1008. ulongValue = (ulong)value;
  1009. }
  1010. if (!_allowTruncation && value != (Decimal128)ulongValue)
  1011. {
  1012. throw new TruncationException();
  1013. }
  1014. return ulongValue;
  1015. }
  1016. /// <summary>
  1017. /// Converts a Double to a UInt64.
  1018. /// </summary>
  1019. /// <param name="value">A Double.</param>
  1020. /// <returns>A UInt64.</returns>
  1021. [CLSCompliant(false)]
  1022. public ulong ToUInt64(double value)
  1023. {
  1024. var uint64Value = (ulong)value;
  1025. if (value < ulong.MinValue || value > ulong.MaxValue)
  1026. {
  1027. if (!_allowOverflow) { throw new OverflowException(); }
  1028. }
  1029. else if (value != (double)uint64Value)
  1030. {
  1031. if (!_allowTruncation) { throw new TruncationException(); }
  1032. }
  1033. return uint64Value;
  1034. }
  1035. /// <summary>
  1036. /// Converts an Int32 to a UInt64.
  1037. /// </summary>
  1038. /// <param name="value">An Int32.</param>
  1039. /// <returns>A UInt64.</returns>
  1040. [CLSCompliant(false)]
  1041. public ulong ToUInt64(int value)
  1042. {
  1043. if (value < (int)ulong.MinValue)
  1044. {
  1045. if (!_allowOverflow) { throw new OverflowException(); }
  1046. }
  1047. return (ulong)value;
  1048. }
  1049. /// <summary>
  1050. /// Converts an Int64 to a UInt64.
  1051. /// </summary>
  1052. /// <param name="value">An Int64.</param>
  1053. /// <returns>A UInt64.</returns>
  1054. [CLSCompliant(false)]
  1055. public ulong ToUInt64(long value)
  1056. {
  1057. if (value < (int)ulong.MinValue)
  1058. {
  1059. if (!_allowOverflow) { throw new OverflowException(); }
  1060. }
  1061. return (ulong)value;
  1062. }
  1063. }
  1064. }