BsonDecimal128.cs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348
  1. /* Copyright 2016-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.IO;
  17. namespace MongoDB.Bson
  18. {
  19. /// <summary>
  20. /// Represents a BSON Decimal128 value.
  21. /// </summary>
  22. /// <seealso cref="MongoDB.Bson.BsonValue" />
  23. [Serializable]
  24. public class BsonDecimal128 : BsonValue, IComparable<BsonDecimal128>, IEquatable<BsonDecimal128>
  25. {
  26. // private fields
  27. private readonly Decimal128 _value;
  28. /// <summary>
  29. /// Initializes a new instance of the <see cref="BsonDecimal128" /> class.
  30. /// </summary>
  31. /// <param name="value">The value.</param>
  32. public BsonDecimal128(Decimal128 value)
  33. {
  34. _value = value;
  35. }
  36. // public properties
  37. /// <inheritdoc />
  38. public override BsonType BsonType
  39. {
  40. get { return BsonType.Decimal128; }
  41. }
  42. /// <inheritdoc />
  43. [Obsolete("Use Value instead.")]
  44. public override object RawValue
  45. {
  46. get { return _value; }
  47. }
  48. /// <summary>
  49. /// Gets the value.
  50. /// </summary>
  51. public Decimal128 Value
  52. {
  53. get { return _value; }
  54. }
  55. // public operators
  56. /// <summary>
  57. /// Converts a Decimal128 to a BsonDecimal128.
  58. /// </summary>
  59. /// <param name="value">A Decimal128.</param>
  60. /// <returns>A BsonDecimal128.</returns>
  61. public static implicit operator BsonDecimal128(Decimal128 value)
  62. {
  63. return new BsonDecimal128(value);
  64. }
  65. /// <summary>
  66. /// Compares two BsonDecimal128 values.
  67. /// </summary>
  68. /// <param name="lhs">The first BsonDecimal128.</param>
  69. /// <param name="rhs">The other BsonDecimal128.</param>
  70. /// <returns>True if the two BsonDecimal128 values are not equal according to ==.</returns>
  71. public static bool operator !=(BsonDecimal128 lhs, BsonDecimal128 rhs)
  72. {
  73. return !(lhs == rhs);
  74. }
  75. /// <summary>
  76. /// Compares two BsonDecimal128 values.
  77. /// </summary>
  78. /// <param name="lhs">The first BsonDecimal128.</param>
  79. /// <param name="rhs">The other BsonDecimal128.</param>
  80. /// <returns>True if the two BsonDecimal128 values are equal according to ==.</returns>
  81. public static bool operator ==(BsonDecimal128 lhs, BsonDecimal128 rhs)
  82. {
  83. if (object.ReferenceEquals(lhs, null)) { return object.ReferenceEquals(rhs, null); }
  84. return lhs.OperatorEqualsImplementation(rhs);
  85. }
  86. // public static methods
  87. /// <summary>
  88. /// Creates a new instance of the BsonDecimal128 class.
  89. /// </summary>
  90. /// <param name="value">An object to be mapped to a BsonDecimal128.</param>
  91. /// <returns>A BsonDecimal128.</returns>
  92. public new static BsonDecimal128 Create(object value)
  93. {
  94. if (value == null)
  95. {
  96. throw new ArgumentNullException("value");
  97. }
  98. return (BsonDecimal128)BsonTypeMapper.MapToBsonValue(value, BsonType.Decimal128);
  99. }
  100. // public methods
  101. /// <summary>
  102. /// Compares this BsonDecimal128 to another BsonDecimal128.
  103. /// </summary>
  104. /// <param name="other">The other BsonDecimal128.</param>
  105. /// <returns>A 32-bit signed integer that indicates whether this BsonDecimal128 is less than, equal to, or greather than the other.</returns>
  106. public int CompareTo(BsonDecimal128 other)
  107. {
  108. if (other == null) { return 1; }
  109. return _value.CompareTo(other._value);
  110. }
  111. /// <inheritdoc />
  112. public override int CompareTo(BsonValue other)
  113. {
  114. if (other == null) { return 1; }
  115. var otherDecimal128 = other as BsonDecimal128;
  116. if (otherDecimal128 != null)
  117. {
  118. return _value.CompareTo(otherDecimal128.Value);
  119. }
  120. var otherInt32 = other as BsonInt32;
  121. if (otherInt32 != null)
  122. {
  123. return _value.CompareTo((Decimal128)otherInt32.Value);
  124. }
  125. var otherInt64 = other as BsonInt64;
  126. if (otherInt64 != null)
  127. {
  128. return _value.CompareTo((Decimal128)otherInt64.Value);
  129. }
  130. var otherDouble = other as BsonDouble;
  131. if (otherDouble != null)
  132. {
  133. return _value.CompareTo((Decimal128)otherDouble.Value);
  134. }
  135. return CompareTypeTo(other);
  136. }
  137. /// <summary>
  138. /// Compares this BsonDecimal128 to another BsonDecimal128.
  139. /// </summary>
  140. /// <param name="rhs">The other BsonDecimal128.</param>
  141. /// <returns>True if the two BsonDecimal128 values are equal.</returns>
  142. public bool Equals(BsonDecimal128 rhs)
  143. {
  144. if (object.ReferenceEquals(rhs, null) || GetType() != rhs.GetType()) { return false; }
  145. return _value.Equals(rhs._value); // use Equals instead of == so NaN is handled correctly
  146. }
  147. /// <inheritdoc />
  148. public override bool Equals(object obj)
  149. {
  150. return Equals(obj as BsonDecimal128); // works even if obj is null or of a different type
  151. }
  152. /// <inheritdoc />
  153. public override int GetHashCode()
  154. {
  155. // see Effective Java by Joshua Bloch
  156. int hash = 17;
  157. hash = 37 * hash + BsonType.GetHashCode();
  158. hash = 37 * hash + _value.GetHashCode();
  159. return hash;
  160. }
  161. /// <inheritdoc />
  162. public override bool ToBoolean()
  163. {
  164. return !(Decimal128.IsNaN(_value) || _value.Equals(Decimal128.Zero));
  165. }
  166. /// <inheritdoc />
  167. public override decimal ToDecimal()
  168. {
  169. return Decimal128.ToDecimal(_value);
  170. }
  171. /// <inheritdoc />
  172. public override Decimal128 ToDecimal128()
  173. {
  174. return _value;
  175. }
  176. /// <inheritdoc />
  177. public override double ToDouble()
  178. {
  179. return Decimal128.ToDouble(_value);
  180. }
  181. /// <inheritdoc />
  182. public override int ToInt32()
  183. {
  184. return Decimal128.ToInt32(_value);
  185. }
  186. /// <inheritdoc />
  187. public override long ToInt64()
  188. {
  189. return Decimal128.ToInt64(_value);
  190. }
  191. /// <inheritdoc />
  192. public override string ToString()
  193. {
  194. return JsonConvert.ToString(_value);
  195. }
  196. // protected methods
  197. /// <inheritdoc/>
  198. protected override TypeCode IConvertibleGetTypeCodeImplementation()
  199. {
  200. return TypeCode.Object;
  201. }
  202. /// <inheritdoc/>
  203. protected override bool IConvertibleToBooleanImplementation(IFormatProvider provider)
  204. {
  205. return ((IConvertible)_value).ToBoolean(provider);
  206. }
  207. /// <inheritdoc/>
  208. protected override byte IConvertibleToByteImplementation(IFormatProvider provider)
  209. {
  210. return ((IConvertible)_value).ToByte(provider);
  211. }
  212. /// <inheritdoc/>
  213. protected override decimal IConvertibleToDecimalImplementation(IFormatProvider provider)
  214. {
  215. return ((IConvertible)_value).ToDecimal(provider);
  216. }
  217. /// <inheritdoc/>
  218. protected override double IConvertibleToDoubleImplementation(IFormatProvider provider)
  219. {
  220. return ((IConvertible)_value).ToDouble(provider);
  221. }
  222. /// <inheritdoc/>
  223. protected override short IConvertibleToInt16Implementation(IFormatProvider provider)
  224. {
  225. return ((IConvertible)_value).ToInt16(provider);
  226. }
  227. /// <inheritdoc/>
  228. protected override int IConvertibleToInt32Implementation(IFormatProvider provider)
  229. {
  230. return ((IConvertible)_value).ToInt32(provider);
  231. }
  232. /// <inheritdoc/>
  233. protected override long IConvertibleToInt64Implementation(IFormatProvider provider)
  234. {
  235. return ((IConvertible)_value).ToInt64(provider);
  236. }
  237. /// <inheritdoc/>
  238. #pragma warning disable 3002
  239. protected override sbyte IConvertibleToSByteImplementation(IFormatProvider provider)
  240. {
  241. return ((IConvertible)_value).ToSByte(provider);
  242. }
  243. #pragma warning restore
  244. /// <inheritdoc/>
  245. protected override float IConvertibleToSingleImplementation(IFormatProvider provider)
  246. {
  247. return ((IConvertible)_value).ToSingle(provider);
  248. }
  249. /// <inheritdoc/>
  250. protected override string IConvertibleToStringImplementation(IFormatProvider provider)
  251. {
  252. return ((IConvertible)_value).ToString(provider);
  253. }
  254. /// <inheritdoc/>
  255. #pragma warning disable 3002
  256. protected override ushort IConvertibleToUInt16Implementation(IFormatProvider provider)
  257. {
  258. return ((IConvertible)_value).ToUInt16(provider);
  259. }
  260. #pragma warning restore
  261. /// <inheritdoc/>
  262. #pragma warning disable 3002
  263. protected override uint IConvertibleToUInt32Implementation(IFormatProvider provider)
  264. {
  265. return ((IConvertible)_value).ToUInt32(provider);
  266. }
  267. #pragma warning restore
  268. /// <inheritdoc/>
  269. #pragma warning disable 3002
  270. protected override ulong IConvertibleToUInt64Implementation(IFormatProvider provider)
  271. {
  272. return ((IConvertible)_value).ToUInt64(provider);
  273. }
  274. #pragma warning restore
  275. /// <inheritdoc/>
  276. protected override bool OperatorEqualsImplementation(BsonValue rhs)
  277. {
  278. var rhsDecimal128 = rhs as BsonDecimal128;
  279. if (rhsDecimal128 != null)
  280. {
  281. return _value == rhsDecimal128._value; // use == instead of Equals so NaN is handled correctly
  282. }
  283. var rhsInt32 = rhs as BsonInt32;
  284. if (rhsInt32 != null)
  285. {
  286. return _value == (Decimal128)rhsInt32.Value;
  287. }
  288. var rhsInt64 = rhs as BsonInt64;
  289. if (rhsInt64 != null)
  290. {
  291. return _value == (Decimal128)rhsInt64.Value;
  292. }
  293. var rhsDouble = rhs as BsonDouble;
  294. if (rhsDouble != null)
  295. {
  296. return _value == (Decimal128)rhsDouble.Value; // use == instead of Equals so NaN is handled correctly
  297. }
  298. return this.Equals(rhs);
  299. }
  300. }
  301. }