BsonValue.cs 53 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509
  1. /* Copyright 2010-2014 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 System.Collections.Generic;
  17. using System.Text.RegularExpressions;
  18. using MongoDB.Bson.IO;
  19. using MongoDB.Bson.Serialization;
  20. namespace MongoDB.Bson
  21. {
  22. /// <summary>
  23. /// Represents a BSON value (this is an abstract class, see the various subclasses).
  24. /// </summary>
  25. [Serializable]
  26. public abstract class BsonValue : IComparable<BsonValue>, IConvertible, IEquatable<BsonValue>
  27. {
  28. // private static fields
  29. private static Dictionary<BsonType, int> __bsonTypeSortOrder = new Dictionary<BsonType, int>
  30. {
  31. { BsonType.MinKey, 1 },
  32. { BsonType.Undefined, 2 },
  33. { BsonType.Null, 3 },
  34. { BsonType.Double, 4 },
  35. { BsonType.Int32, 4 },
  36. { BsonType.Int64, 4 },
  37. { BsonType.String, 5 },
  38. { BsonType.Symbol, 5 },
  39. { BsonType.Document, 6 },
  40. { BsonType.Array, 7 },
  41. { BsonType.Binary, 8 },
  42. { BsonType.ObjectId, 9 },
  43. { BsonType.Boolean, 10 },
  44. { BsonType.DateTime, 11 },
  45. { BsonType.Timestamp, 11 },
  46. { BsonType.RegularExpression, 12 },
  47. { BsonType.JavaScript, 13 }, // TODO: confirm where JavaScript and JavaScriptWithScope are in the sort order
  48. { BsonType.JavaScriptWithScope, 14 },
  49. { BsonType.MaxKey, 15 }
  50. };
  51. // private fields
  52. private BsonType _bsonType;
  53. // constructors
  54. /// <summary>
  55. /// Initializes a new instance of the BsonValue class.
  56. /// </summary>
  57. /// <param name="bsonType">The BsonType of this BsonValue.</param>
  58. protected BsonValue(BsonType bsonType)
  59. {
  60. _bsonType = bsonType;
  61. }
  62. // public properties
  63. /// <summary>
  64. /// Casts the BsonValue to a Boolean (throws an InvalidCastException if the cast is not valid).
  65. /// </summary>
  66. public bool AsBoolean
  67. {
  68. get { return ((BsonBoolean)this).Value; }
  69. }
  70. /// <summary>
  71. /// Casts the BsonValue to a BsonArray (throws an InvalidCastException if the cast is not valid).
  72. /// </summary>
  73. public BsonArray AsBsonArray
  74. {
  75. get { return (BsonArray)this; }
  76. }
  77. /// <summary>
  78. /// Casts the BsonValue to a BsonBinaryData (throws an InvalidCastException if the cast is not valid).
  79. /// </summary>
  80. public BsonBinaryData AsBsonBinaryData
  81. {
  82. get { return (BsonBinaryData)this; }
  83. }
  84. /// <summary>
  85. /// Casts the BsonValue to a BsonDateTime (throws an InvalidCastException if the cast is not valid).
  86. /// </summary>
  87. public BsonDateTime AsBsonDateTime
  88. {
  89. get { return (BsonDateTime)this; }
  90. }
  91. /// <summary>
  92. /// Casts the BsonValue to a BsonDocument (throws an InvalidCastException if the cast is not valid).
  93. /// </summary>
  94. public BsonDocument AsBsonDocument
  95. {
  96. get { return (BsonDocument)this; }
  97. }
  98. /// <summary>
  99. /// Casts the BsonValue to a BsonJavaScript (throws an InvalidCastException if the cast is not valid).
  100. /// </summary>
  101. public BsonJavaScript AsBsonJavaScript
  102. {
  103. get { return (BsonJavaScript)this; }
  104. }
  105. /// <summary>
  106. /// Casts the BsonValue to a BsonJavaScriptWithScope (throws an InvalidCastException if the cast is not valid).
  107. /// </summary>
  108. public BsonJavaScriptWithScope AsBsonJavaScriptWithScope
  109. {
  110. get { return (BsonJavaScriptWithScope)this; }
  111. }
  112. /// <summary>
  113. /// Casts the BsonValue to a BsonMaxKey (throws an InvalidCastException if the cast is not valid).
  114. /// </summary>
  115. public BsonMaxKey AsBsonMaxKey
  116. {
  117. get { return (BsonMaxKey)this; }
  118. }
  119. /// <summary>
  120. /// Casts the BsonValue to a BsonMinKey (throws an InvalidCastException if the cast is not valid).
  121. /// </summary>
  122. public BsonMinKey AsBsonMinKey
  123. {
  124. get { return (BsonMinKey)this; }
  125. }
  126. /// <summary>
  127. /// Casts the BsonValue to a BsonNull (throws an InvalidCastException if the cast is not valid).
  128. /// </summary>
  129. public BsonNull AsBsonNull
  130. {
  131. get { return (BsonNull)this; }
  132. }
  133. /// <summary>
  134. /// Casts the BsonValue to a BsonRegularExpression (throws an InvalidCastException if the cast is not valid).
  135. /// </summary>
  136. public BsonRegularExpression AsBsonRegularExpression
  137. {
  138. get { return (BsonRegularExpression)this; }
  139. }
  140. /// <summary>
  141. /// Casts the BsonValue to a BsonSymbol (throws an InvalidCastException if the cast is not valid).
  142. /// </summary>
  143. public BsonSymbol AsBsonSymbol
  144. {
  145. get { return (BsonSymbol)this; }
  146. }
  147. /// <summary>
  148. /// Casts the BsonValue to a BsonTimestamp (throws an InvalidCastException if the cast is not valid).
  149. /// </summary>
  150. public BsonTimestamp AsBsonTimestamp
  151. {
  152. get { return (BsonTimestamp)this; }
  153. }
  154. /// <summary>
  155. /// Casts the BsonValue to a BsonUndefined (throws an InvalidCastException if the cast is not valid).
  156. /// </summary>
  157. public BsonUndefined AsBsonUndefined
  158. {
  159. get { return (BsonUndefined)this; }
  160. }
  161. /// <summary>
  162. /// Casts the BsonValue to a BsonValue (a way of upcasting subclasses of BsonValue to BsonValue at compile time).
  163. /// </summary>
  164. public BsonValue AsBsonValue
  165. {
  166. get { return this; }
  167. }
  168. /// <summary>
  169. /// Casts the BsonValue to a Byte[] (throws an InvalidCastException if the cast is not valid).
  170. /// </summary>
  171. public byte[] AsByteArray
  172. {
  173. get { return ((BsonBinaryData)this).Bytes; }
  174. }
  175. /// <summary>
  176. /// Casts the BsonValue to a DateTime in UTC (throws an InvalidCastException if the cast is not valid).
  177. /// </summary>
  178. [Obsolete("Use ToUniversalTime instead.")]
  179. public DateTime AsDateTime
  180. {
  181. get { return AsUniversalTime; }
  182. }
  183. /// <summary>
  184. /// Casts the BsonValue to a Double (throws an InvalidCastException if the cast is not valid).
  185. /// </summary>
  186. public double AsDouble
  187. {
  188. get { return ((BsonDouble)this).Value; }
  189. }
  190. /// <summary>
  191. /// Casts the BsonValue to a Guid (throws an InvalidCastException if the cast is not valid).
  192. /// </summary>
  193. public Guid AsGuid
  194. {
  195. get { return ((BsonBinaryData)this).ToGuid(); }
  196. }
  197. /// <summary>
  198. /// Casts the BsonValue to an Int32 (throws an InvalidCastException if the cast is not valid).
  199. /// </summary>
  200. public int AsInt32
  201. {
  202. get { return ((BsonInt32)this).Value; }
  203. }
  204. /// <summary>
  205. /// Casts the BsonValue to a DateTime in the local timezone (throws an InvalidCastException if the cast is not valid).
  206. /// </summary>
  207. [Obsolete("Use ToLocalTime instead.")]
  208. public DateTime AsLocalTime
  209. {
  210. get { return ((BsonDateTime)this).ToLocalTime(); }
  211. }
  212. /// <summary>
  213. /// Casts the BsonValue to a Int64 (throws an InvalidCastException if the cast is not valid).
  214. /// </summary>
  215. public long AsInt64
  216. {
  217. get { return ((BsonInt64)this).Value; }
  218. }
  219. /// <summary>
  220. /// Casts the BsonValue to a Nullable{Boolean} (throws an InvalidCastException if the cast is not valid).
  221. /// </summary>
  222. public bool? AsNullableBoolean
  223. {
  224. get { return (_bsonType == BsonType.Null) ? null : (bool?)AsBoolean; }
  225. }
  226. /// <summary>
  227. /// Casts the BsonValue to a Nullable{DateTime} (throws an InvalidCastException if the cast is not valid).
  228. /// </summary>
  229. [Obsolete("Use ToNullableUniversalTime instead.")]
  230. public DateTime? AsNullableDateTime
  231. {
  232. get { return (_bsonType == BsonType.Null) ? null : (DateTime?)AsDateTime; }
  233. }
  234. /// <summary>
  235. /// Casts the BsonValue to a Nullable{Double} (throws an InvalidCastException if the cast is not valid).
  236. /// </summary>
  237. public double? AsNullableDouble
  238. {
  239. get { return (_bsonType == BsonType.Null) ? null : (double?)AsDouble; }
  240. }
  241. /// <summary>
  242. /// Casts the BsonValue to a Nullable{Guid} (throws an InvalidCastException if the cast is not valid).
  243. /// </summary>
  244. public Guid? AsNullableGuid
  245. {
  246. get { return (_bsonType == BsonType.Null) ? null : (Guid?)AsGuid; }
  247. }
  248. /// <summary>
  249. /// Casts the BsonValue to a Nullable{Int32} (throws an InvalidCastException if the cast is not valid).
  250. /// </summary>
  251. public int? AsNullableInt32
  252. {
  253. get { return (_bsonType == BsonType.Null) ? null : (int?)AsInt32; }
  254. }
  255. /// <summary>
  256. /// Casts the BsonValue to a Nullable{Int64} (throws an InvalidCastException if the cast is not valid).
  257. /// </summary>
  258. public long? AsNullableInt64
  259. {
  260. get { return (_bsonType == BsonType.Null) ? null : (long?)AsInt64; }
  261. }
  262. /// <summary>
  263. /// Casts the BsonValue to a Nullable{ObjectId} (throws an InvalidCastException if the cast is not valid).
  264. /// </summary>
  265. public ObjectId? AsNullableObjectId
  266. {
  267. get { return (_bsonType == BsonType.Null) ? null : (ObjectId?)AsObjectId; }
  268. }
  269. /// <summary>
  270. /// Casts the BsonValue to an ObjectId (throws an InvalidCastException if the cast is not valid).
  271. /// </summary>
  272. public ObjectId AsObjectId
  273. {
  274. get { return ((BsonObjectId)this).Value; }
  275. }
  276. /// <summary>
  277. /// Casts the BsonValue to a Regex (throws an InvalidCastException if the cast is not valid).
  278. /// </summary>
  279. public Regex AsRegex
  280. {
  281. get { return ((BsonRegularExpression)this).ToRegex(); }
  282. }
  283. /// <summary>
  284. /// Casts the BsonValue to a String (throws an InvalidCastException if the cast is not valid).
  285. /// </summary>
  286. public string AsString
  287. {
  288. get { return ((BsonString)this).Value; }
  289. }
  290. /// <summary>
  291. /// Casts the BsonValue to a DateTime in UTC (throws an InvalidCastException if the cast is not valid).
  292. /// </summary>
  293. [Obsolete("Use ToUniversalTime instead.")]
  294. public DateTime AsUniversalTime
  295. {
  296. get { return ((BsonDateTime)this).ToUniversalTime(); }
  297. }
  298. /// <summary>
  299. /// Gets the BsonType of this BsonValue.
  300. /// </summary>
  301. public BsonType BsonType
  302. {
  303. get { return _bsonType; }
  304. }
  305. /// <summary>
  306. /// Tests whether this BsonValue is a Boolean.
  307. /// </summary>
  308. public bool IsBoolean
  309. {
  310. get { return _bsonType == BsonType.Boolean; }
  311. }
  312. /// <summary>
  313. /// Tests whether this BsonValue is a BsonArray.
  314. /// </summary>
  315. public bool IsBsonArray
  316. {
  317. get { return _bsonType == BsonType.Array; }
  318. }
  319. /// <summary>
  320. /// Tests whether this BsonValue is a BsonBinaryData.
  321. /// </summary>
  322. public bool IsBsonBinaryData
  323. {
  324. get { return _bsonType == BsonType.Binary; }
  325. }
  326. /// <summary>
  327. /// Tests whether this BsonValue is a BsonDateTime.
  328. /// </summary>
  329. public bool IsBsonDateTime
  330. {
  331. get { return _bsonType == BsonType.DateTime; }
  332. }
  333. /// <summary>
  334. /// Tests whether this BsonValue is a BsonDocument.
  335. /// </summary>
  336. public bool IsBsonDocument
  337. {
  338. get { return _bsonType == BsonType.Document; }
  339. }
  340. /// <summary>
  341. /// Tests whether this BsonValue is a BsonJavaScript.
  342. /// </summary>
  343. public bool IsBsonJavaScript
  344. {
  345. get { return _bsonType == BsonType.JavaScript || _bsonType == BsonType.JavaScriptWithScope; }
  346. }
  347. /// <summary>
  348. /// Tests whether this BsonValue is a BsonJavaScriptWithScope.
  349. /// </summary>
  350. public bool IsBsonJavaScriptWithScope
  351. {
  352. get { return _bsonType == BsonType.JavaScriptWithScope; }
  353. }
  354. /// <summary>
  355. /// Tests whether this BsonValue is a BsonMaxKey.
  356. /// </summary>
  357. public bool IsBsonMaxKey
  358. {
  359. get { return _bsonType == BsonType.MaxKey; }
  360. }
  361. /// <summary>
  362. /// Tests whether this BsonValue is a BsonMinKey.
  363. /// </summary>
  364. public bool IsBsonMinKey
  365. {
  366. get { return _bsonType == BsonType.MinKey; }
  367. }
  368. /// <summary>
  369. /// Tests whether this BsonValue is a BsonNull.
  370. /// </summary>
  371. public bool IsBsonNull
  372. {
  373. get { return _bsonType == BsonType.Null; }
  374. }
  375. /// <summary>
  376. /// Tests whether this BsonValue is a BsonRegularExpression.
  377. /// </summary>
  378. public bool IsBsonRegularExpression
  379. {
  380. get { return _bsonType == BsonType.RegularExpression; }
  381. }
  382. /// <summary>
  383. /// Tests whether this BsonValue is a BsonSymbol .
  384. /// </summary>
  385. public bool IsBsonSymbol
  386. {
  387. get { return _bsonType == BsonType.Symbol; }
  388. }
  389. /// <summary>
  390. /// Tests whether this BsonValue is a BsonTimestamp.
  391. /// </summary>
  392. public bool IsBsonTimestamp
  393. {
  394. get { return _bsonType == BsonType.Timestamp; }
  395. }
  396. /// <summary>
  397. /// Tests whether this BsonValue is a BsonUndefined.
  398. /// </summary>
  399. public bool IsBsonUndefined
  400. {
  401. get { return _bsonType == BsonType.Undefined; }
  402. }
  403. /// <summary>
  404. /// Tests whether this BsonValue is a DateTime.
  405. /// </summary>
  406. [Obsolete("Use IsValidDateTime instead.")]
  407. public bool IsDateTime
  408. {
  409. get { return IsValidDateTime; }
  410. }
  411. /// <summary>
  412. /// Tests whether this BsonValue is a Double.
  413. /// </summary>
  414. public bool IsDouble
  415. {
  416. get { return _bsonType == BsonType.Double; }
  417. }
  418. /// <summary>
  419. /// Tests whether this BsonValue is a Guid.
  420. /// </summary>
  421. public bool IsGuid
  422. {
  423. get
  424. {
  425. if (_bsonType == BsonType.Binary)
  426. {
  427. var subType = ((BsonBinaryData)this).SubType;
  428. return subType == BsonBinarySubType.UuidStandard || subType == BsonBinarySubType.UuidLegacy;
  429. }
  430. else
  431. {
  432. return false;
  433. }
  434. }
  435. }
  436. /// <summary>
  437. /// Tests whether this BsonValue is an Int32.
  438. /// </summary>
  439. public bool IsInt32
  440. {
  441. get { return _bsonType == BsonType.Int32; }
  442. }
  443. /// <summary>
  444. /// Tests whether this BsonValue is an Int64.
  445. /// </summary>
  446. public bool IsInt64
  447. {
  448. get { return _bsonType == BsonType.Int64; }
  449. }
  450. /// <summary>
  451. /// Tests whether this BsonValue is a numeric value.
  452. /// </summary>
  453. public bool IsNumeric
  454. {
  455. get
  456. {
  457. return
  458. _bsonType == BsonType.Double ||
  459. _bsonType == BsonType.Int32 ||
  460. _bsonType == BsonType.Int64;
  461. }
  462. }
  463. /// <summary>
  464. /// Tests whether this BsonValue is an ObjectId .
  465. /// </summary>
  466. public bool IsObjectId
  467. {
  468. get { return _bsonType == BsonType.ObjectId; }
  469. }
  470. /// <summary>
  471. /// Tests whether this BsonValue is a String.
  472. /// </summary>
  473. public bool IsString
  474. {
  475. get { return _bsonType == BsonType.String; }
  476. }
  477. /// <summary>
  478. /// Tests whether this BsonValue is a valid DateTime.
  479. /// </summary>
  480. public virtual bool IsValidDateTime
  481. {
  482. get { return false; }
  483. }
  484. /// <summary>
  485. /// Gets the raw value of this BsonValue (or null if this BsonValue doesn't have a single scalar value).
  486. /// </summary>
  487. // note: don't change return value to "this" or lots of things will break
  488. [Obsolete("Use Value property of subclasses or BsonTypeMapper.MapToDotNetValue instead.")]
  489. public virtual object RawValue
  490. {
  491. get { return null; } // subclasses that have a single value (e.g. Int32) override this
  492. }
  493. // public operators
  494. /// <summary>
  495. /// Casts a BsonValue to a bool.
  496. /// </summary>
  497. /// <param name="value">The BsonValue.</param>
  498. /// <returns>A bool.</returns>
  499. public static explicit operator bool(BsonValue value)
  500. {
  501. if (value == null)
  502. {
  503. throw new ArgumentNullException("value");
  504. }
  505. return value.AsBoolean;
  506. }
  507. /// <summary>
  508. /// Casts a BsonValue to a bool?.
  509. /// </summary>
  510. /// <param name="value">The BsonValue.</param>
  511. /// <returns>A bool?.</returns>
  512. public static explicit operator bool?(BsonValue value)
  513. {
  514. return (value == null) ? null : value.AsNullableBoolean;
  515. }
  516. /// <summary>
  517. /// Converts a bool to a BsonValue.
  518. /// </summary>
  519. /// <param name="value">A bool.</param>
  520. /// <returns>A BsonValue.</returns>
  521. public static implicit operator BsonValue(bool value)
  522. {
  523. return value ? BsonBoolean.True : BsonBoolean.False;
  524. }
  525. /// <summary>
  526. /// Converts a bool? to a BsonValue.
  527. /// </summary>
  528. /// <param name="value">A bool?.</param>
  529. /// <returns>A BsonValue.</returns>
  530. public static implicit operator BsonValue(bool? value)
  531. {
  532. return value.HasValue ? (BsonValue)(value.Value ? BsonBoolean.True : BsonBoolean.False) : BsonNull.Value;
  533. }
  534. /// <summary>
  535. /// Converts a byte[] to a BsonValue.
  536. /// </summary>
  537. /// <param name="value">A byte[].</param>
  538. /// <returns>A BsonValue.</returns>
  539. public static implicit operator BsonValue(byte[] value)
  540. {
  541. return (value != null) ? (BsonValue)new BsonBinaryData(value) : null;
  542. }
  543. /// <summary>
  544. /// Converts a DateTime to a BsonValue.
  545. /// </summary>
  546. /// <param name="value">A DateTime.</param>
  547. /// <returns>A BsonValue.</returns>
  548. public static implicit operator BsonValue(DateTime value)
  549. {
  550. return new BsonDateTime(value);
  551. }
  552. /// <summary>
  553. /// Converts a DateTime? to a BsonValue.
  554. /// </summary>
  555. /// <param name="value">A DateTime?.</param>
  556. /// <returns>A BsonValue.</returns>
  557. public static implicit operator BsonValue(DateTime? value)
  558. {
  559. return value.HasValue ? (BsonValue)new BsonDateTime(value.Value) : BsonNull.Value;
  560. }
  561. /// <summary>
  562. /// Converts a double to a BsonValue.
  563. /// </summary>
  564. /// <param name="value">A double.</param>
  565. /// <returns>A BsonValue.</returns>
  566. public static implicit operator BsonValue(double value)
  567. {
  568. return new BsonDouble(value);
  569. }
  570. /// <summary>
  571. /// Converts a double? to a BsonValue.
  572. /// </summary>
  573. /// <param name="value">A double?.</param>
  574. /// <returns>A BsonValue.</returns>
  575. public static implicit operator BsonValue(double? value)
  576. {
  577. return value.HasValue ? (BsonValue)new BsonDouble(value.Value) : BsonNull.Value;
  578. }
  579. /// <summary>
  580. /// Converts an Enum to a BsonValue.
  581. /// </summary>
  582. /// <param name="value">An Enum.</param>
  583. /// <returns>A BsonValue.</returns>
  584. public static implicit operator BsonValue(Enum value)
  585. {
  586. return BsonTypeMapper.MapToBsonValue(value);
  587. }
  588. /// <summary>
  589. /// Converts a Guid to a BsonValue.
  590. /// </summary>
  591. /// <param name="value">A Guid.</param>
  592. /// <returns>A BsonValue.</returns>
  593. public static implicit operator BsonValue(Guid value)
  594. {
  595. return new BsonBinaryData(value);
  596. }
  597. /// <summary>
  598. /// Converts a Guid? to a BsonValue.
  599. /// </summary>
  600. /// <param name="value">A Guid?.</param>
  601. /// <returns>A BsonValue.</returns>
  602. public static implicit operator BsonValue(Guid? value)
  603. {
  604. return value.HasValue ? (BsonValue)new BsonBinaryData(value.Value) : BsonNull.Value;
  605. }
  606. /// <summary>
  607. /// Converts an int to a BsonValue.
  608. /// </summary>
  609. /// <param name="value">An int.</param>
  610. /// <returns>A BsonValue.</returns>
  611. public static implicit operator BsonValue(int value)
  612. {
  613. return new BsonInt32(value);
  614. }
  615. /// <summary>
  616. /// Converts an int? to a BsonValue.
  617. /// </summary>
  618. /// <param name="value">An int?.</param>
  619. /// <returns>A BsonValue.</returns>
  620. public static implicit operator BsonValue(int? value)
  621. {
  622. return value.HasValue ? (BsonValue)new BsonInt32(value.Value) : BsonNull.Value;
  623. }
  624. /// <summary>
  625. /// Converts a long to a BsonValue.
  626. /// </summary>
  627. /// <param name="value">A long.</param>
  628. /// <returns>A BsonValue.</returns>
  629. public static implicit operator BsonValue(long value)
  630. {
  631. return new BsonInt64(value);
  632. }
  633. /// <summary>
  634. /// Converts a long? to a BsonValue.
  635. /// </summary>
  636. /// <param name="value">A long?.</param>
  637. /// <returns>A BsonValue.</returns>
  638. public static implicit operator BsonValue(long? value)
  639. {
  640. return value.HasValue ? (BsonValue)new BsonInt64(value.Value) : BsonNull.Value;
  641. }
  642. /// <summary>
  643. /// Converts an ObjectId to a BsonValue.
  644. /// </summary>
  645. /// <param name="value">An ObjectId.</param>
  646. /// <returns>A BsonValue.</returns>
  647. public static implicit operator BsonValue(ObjectId value)
  648. {
  649. return new BsonObjectId(value);
  650. }
  651. /// <summary>
  652. /// Converts an ObjectId? to a BsonValue.
  653. /// </summary>
  654. /// <param name="value">An ObjectId?.</param>
  655. /// <returns>A BsonValue.</returns>
  656. public static implicit operator BsonValue(ObjectId? value)
  657. {
  658. return value.HasValue ? (BsonValue)new BsonObjectId(value.Value) : BsonNull.Value;
  659. }
  660. /// <summary>
  661. /// Converts a Regex to a BsonValue.
  662. /// </summary>
  663. /// <param name="value">A Regex.</param>
  664. /// <returns>A BsonValue.</returns>
  665. public static implicit operator BsonValue(Regex value)
  666. {
  667. return (value != null) ? (BsonValue)new BsonRegularExpression(value) : null;
  668. }
  669. /// <summary>
  670. /// Converts a string to a BsonValue.
  671. /// </summary>
  672. /// <param name="value">A string.</param>
  673. /// <returns>A BsonValue.</returns>
  674. public static implicit operator BsonValue(string value)
  675. {
  676. return (value != null) ? (BsonValue)new BsonString(value) : null;
  677. }
  678. /// <summary>
  679. /// Casts a BsonValue to a byte[].
  680. /// </summary>
  681. /// <param name="value">The BsonValue.</param>
  682. /// <returns>A byte[].</returns>
  683. public static explicit operator byte[](BsonValue value)
  684. {
  685. return (value == null) ? null : value.AsByteArray;
  686. }
  687. /// <summary>
  688. /// Casts a BsonValue to a DateTime.
  689. /// </summary>
  690. /// <param name="value">The BsonValue.</param>
  691. /// <returns>A DateTime.</returns>
  692. public static explicit operator DateTime(BsonValue value)
  693. {
  694. if (value == null)
  695. {
  696. throw new ArgumentNullException("value");
  697. }
  698. if (!(value is BsonDateTime))
  699. {
  700. throw new InvalidCastException();
  701. }
  702. return value.ToUniversalTime();
  703. }
  704. /// <summary>
  705. /// Casts a BsonValue to a DateTime?.
  706. /// </summary>
  707. /// <param name="value">The BsonValue.</param>
  708. /// <returns>A DateTime?.</returns>
  709. public static explicit operator DateTime?(BsonValue value)
  710. {
  711. if (value != null && !((value is BsonDateTime) || (value is BsonNull)))
  712. {
  713. throw new InvalidCastException();
  714. }
  715. return (value == null) ? null : value.ToNullableUniversalTime();
  716. }
  717. /// <summary>
  718. /// Casts a BsonValue to a double.
  719. /// </summary>
  720. /// <param name="value">The BsonValue.</param>
  721. /// <returns>A double.</returns>
  722. public static explicit operator double(BsonValue value)
  723. {
  724. if (value == null)
  725. {
  726. throw new ArgumentNullException("value");
  727. }
  728. return value.AsDouble;
  729. }
  730. /// <summary>
  731. /// Casts a BsonValue to a double?.
  732. /// </summary>
  733. /// <param name="value">The BsonValue.</param>
  734. /// <returns>A double?.</returns>
  735. public static explicit operator double?(BsonValue value)
  736. {
  737. return (value == null) ? null : value.AsNullableDouble;
  738. }
  739. /// <summary>
  740. /// Casts a BsonValue to a Guid.
  741. /// </summary>
  742. /// <param name="value">The BsonValue.</param>
  743. /// <returns>A Guid.</returns>
  744. public static explicit operator Guid(BsonValue value)
  745. {
  746. if (value == null)
  747. {
  748. throw new ArgumentNullException("value");
  749. }
  750. return value.AsGuid;
  751. }
  752. /// <summary>
  753. /// Casts a BsonValue to a Guid?.
  754. /// </summary>
  755. /// <param name="value">The BsonValue.</param>
  756. /// <returns>A Guid?.</returns>
  757. public static explicit operator Guid?(BsonValue value)
  758. {
  759. return (value == null) ? null : value.AsNullableGuid;
  760. }
  761. /// <summary>
  762. /// Casts a BsonValue to an int.
  763. /// </summary>
  764. /// <param name="value">The BsonValue.</param>
  765. /// <returns>An int.</returns>
  766. public static explicit operator int(BsonValue value)
  767. {
  768. if (value == null)
  769. {
  770. throw new ArgumentNullException("value");
  771. }
  772. return value.AsInt32;
  773. }
  774. /// <summary>
  775. /// Casts a BsonValue to an int?.
  776. /// </summary>
  777. /// <param name="value">The BsonValue.</param>
  778. /// <returns>An int?.</returns>
  779. public static explicit operator int?(BsonValue value)
  780. {
  781. return value == null ? null : value.AsNullableInt32;
  782. }
  783. /// <summary>
  784. /// Casts a BsonValue to a long.
  785. /// </summary>
  786. /// <param name="value">The BsonValue.</param>
  787. /// <returns>A long.</returns>
  788. public static explicit operator long(BsonValue value)
  789. {
  790. if (value == null)
  791. {
  792. throw new ArgumentNullException("value");
  793. }
  794. return value.AsInt64;
  795. }
  796. /// <summary>
  797. /// Casts a BsonValue to a long?.
  798. /// </summary>
  799. /// <param name="value">The BsonValue.</param>
  800. /// <returns>A long?.</returns>
  801. public static explicit operator long?(BsonValue value)
  802. {
  803. return (value == null) ? null : value.AsNullableInt64;
  804. }
  805. /// <summary>
  806. /// Casts a BsonValue to an ObjectId.
  807. /// </summary>
  808. /// <param name="value">The BsonValue.</param>
  809. /// <returns>An ObjectId.</returns>
  810. public static explicit operator ObjectId(BsonValue value)
  811. {
  812. if (value == null)
  813. {
  814. throw new ArgumentNullException("value");
  815. }
  816. return value.AsObjectId;
  817. }
  818. /// <summary>
  819. /// Casts a BsonValue to an ObjectId?.
  820. /// </summary>
  821. /// <param name="value">The BsonValue.</param>
  822. /// <returns>An ObjectId?.</returns>
  823. public static explicit operator ObjectId?(BsonValue value)
  824. {
  825. return (value == null) ? null : value.AsNullableObjectId;
  826. }
  827. /// <summary>
  828. /// Casts a BsonValue to a Regex.
  829. /// </summary>
  830. /// <param name="value">The BsonValue.</param>
  831. /// <returns>A Regex.</returns>
  832. public static explicit operator Regex(BsonValue value)
  833. {
  834. return (value == null) ? null : value.AsRegex;
  835. }
  836. /// <summary>
  837. /// Casts a BsonValue to a string.
  838. /// </summary>
  839. /// <param name="value">The BsonValue.</param>
  840. /// <returns>A string.</returns>
  841. public static explicit operator string(BsonValue value)
  842. {
  843. return (value == null) ? null : value.AsString;
  844. }
  845. /// <summary>
  846. /// Compares two BsonValues.
  847. /// </summary>
  848. /// <param name="lhs">The first BsonValue.</param>
  849. /// <param name="rhs">The other BsonValue.</param>
  850. /// <returns>True if the first BsonValue is less than the other one.</returns>
  851. public static bool operator <(BsonValue lhs, BsonValue rhs)
  852. {
  853. if (object.ReferenceEquals(lhs, null) && object.ReferenceEquals(rhs, null)) { return false; }
  854. if (object.ReferenceEquals(lhs, null)) { return true; }
  855. if (object.ReferenceEquals(rhs, null)) { return false; }
  856. return lhs.CompareTo(rhs) < 0;
  857. }
  858. /// <summary>
  859. /// Compares two BsonValues.
  860. /// </summary>
  861. /// <param name="lhs">The first BsonValue.</param>
  862. /// <param name="rhs">The other BsonValue.</param>
  863. /// <returns>True if the first BsonValue is less than or equal to the other one.</returns>
  864. public static bool operator <=(BsonValue lhs, BsonValue rhs)
  865. {
  866. if (object.ReferenceEquals(lhs, null) && object.ReferenceEquals(rhs, null)) { return true; }
  867. if (object.ReferenceEquals(lhs, null)) { return true; }
  868. if (object.ReferenceEquals(rhs, null)) { return false; }
  869. return lhs.CompareTo(rhs) <= 0;
  870. }
  871. /// <summary>
  872. /// Compares two BsonValues.
  873. /// </summary>
  874. /// <param name="lhs">The first BsonValue.</param>
  875. /// <param name="rhs">The other BsonValue.</param>
  876. /// <returns>True if the two BsonValues are not equal according to ==.</returns>
  877. public static bool operator !=(BsonValue lhs, BsonValue rhs)
  878. {
  879. return !(lhs == rhs);
  880. }
  881. /// <summary>
  882. /// Compares two BsonValues.
  883. /// </summary>
  884. /// <param name="lhs">The first BsonValue.</param>
  885. /// <param name="rhs">The other BsonValue.</param>
  886. /// <returns>True if the two BsonValues are equal according to ==.</returns>
  887. public static bool operator ==(BsonValue lhs, BsonValue rhs)
  888. {
  889. if (object.ReferenceEquals(lhs, null)) { return object.ReferenceEquals(rhs, null); }
  890. if (object.ReferenceEquals(rhs, null)) { return false; } // don't check type because sometimes different types can be ==
  891. return lhs.OperatorEqualsImplementation(rhs); // some subclasses override OperatorEqualsImplementation
  892. }
  893. /// <summary>
  894. /// Compares two BsonValues.
  895. /// </summary>
  896. /// <param name="lhs">The first BsonValue.</param>
  897. /// <param name="rhs">The other BsonValue.</param>
  898. /// <returns>True if the first BsonValue is greater than the other one.</returns>
  899. public static bool operator >(BsonValue lhs, BsonValue rhs)
  900. {
  901. return !(lhs <= rhs);
  902. }
  903. /// <summary>
  904. /// Compares two BsonValues.
  905. /// </summary>
  906. /// <param name="lhs">The first BsonValue.</param>
  907. /// <param name="rhs">The other BsonValue.</param>
  908. /// <returns>True if the first BsonValue is greater than or equal to the other one.</returns>
  909. public static bool operator >=(BsonValue lhs, BsonValue rhs)
  910. {
  911. return !(lhs < rhs);
  912. }
  913. // public indexers
  914. /// <summary>
  915. /// Gets or sets a value by position (only applies to BsonDocument and BsonArray).
  916. /// </summary>
  917. /// <param name="index">The position.</param>
  918. /// <returns>The value.</returns>
  919. public virtual BsonValue this[int index]
  920. {
  921. get
  922. {
  923. var message = string.Format("{0} does not support indexing by position (only BsonDocument and BsonArray do).", this.GetType().Name);
  924. throw new NotSupportedException(message);
  925. }
  926. set
  927. {
  928. var message = string.Format("{0} does not support indexing by position (only BsonDocument and BsonArray do).", this.GetType().Name);
  929. throw new NotSupportedException(message);
  930. }
  931. }
  932. /// <summary>
  933. /// Gets or sets a value by name (only applies to BsonDocument).
  934. /// </summary>
  935. /// <param name="name">The name.</param>
  936. /// <returns>The value.</returns>
  937. public virtual BsonValue this[string name]
  938. {
  939. get
  940. {
  941. var message = string.Format("{0} does not support indexing by name (only BsonDocument does).", this.GetType().Name);
  942. throw new NotSupportedException(message);
  943. }
  944. set
  945. {
  946. var message = string.Format("{0} does not support indexing by name (only BsonDocument does).", this.GetType().Name);
  947. throw new NotSupportedException(message);
  948. }
  949. }
  950. // public static methods
  951. // TODO: implement more Create methods for .NET types (int, string, etc...)? Not sure... already have implicit conversions
  952. /// <summary>
  953. /// Creates a new instance of the BsonValue class.
  954. /// </summary>
  955. /// <param name="value">A value to be mapped to a BsonValue.</param>
  956. /// <returns>A BsonValue.</returns>
  957. public static BsonValue Create(object value)
  958. {
  959. // optimize away the call to MapToBsonValue for the most common cases
  960. if (value == null)
  961. {
  962. return null; // not BsonNull.Value to be consistent with other Create methods
  963. }
  964. else if (value is BsonValue)
  965. {
  966. return (BsonValue)value;
  967. }
  968. else if (value is int)
  969. {
  970. return new BsonInt32((int)value);
  971. }
  972. else if (value is string)
  973. {
  974. return new BsonString((string)value);
  975. }
  976. else if (value is bool)
  977. {
  978. return (BsonBoolean)((bool)value);
  979. }
  980. else if (value is DateTime)
  981. {
  982. return new BsonDateTime((DateTime)value);
  983. }
  984. else if (value is long)
  985. {
  986. return new BsonInt64((long)value);
  987. }
  988. else if (value is double)
  989. {
  990. return new BsonDouble((double)value);
  991. }
  992. else
  993. {
  994. return BsonTypeMapper.MapToBsonValue(value);
  995. }
  996. }
  997. /// <summary>
  998. /// Reads one BsonValue from a BsonReader.
  999. /// </summary>
  1000. /// <param name="bsonReader">The reader.</param>
  1001. /// <returns>A BsonValue.</returns>
  1002. [Obsolete("Use BsonSerializer.Deserialize<BsonValue> instead.")]
  1003. public static BsonValue ReadFrom(BsonReader bsonReader)
  1004. {
  1005. return BsonSerializer.Deserialize<BsonValue>(bsonReader);
  1006. }
  1007. // public methods
  1008. /// <summary>
  1009. /// Creates a shallow clone of the BsonValue (see also DeepClone).
  1010. /// </summary>
  1011. /// <returns>A shallow clone of the BsonValue.</returns>
  1012. public virtual BsonValue Clone()
  1013. {
  1014. return this; // subclasses override Clone if necessary
  1015. }
  1016. /// <summary>
  1017. /// Compares this BsonValue to another BsonValue.
  1018. /// </summary>
  1019. /// <param name="other">The other BsonValue.</param>
  1020. /// <returns>A 32-bit signed integer that indicates whether this BsonValue is less than, equal to, or greather than the other BsonValue.</returns>
  1021. public abstract int CompareTo(BsonValue other);
  1022. /// <summary>
  1023. /// Compares the type of this BsonValue to the type of another BsonValue.
  1024. /// </summary>
  1025. /// <param name="other">The other BsonValue.</param>
  1026. /// <returns>A 32-bit signed integer that indicates whether the type of this BsonValue is less than, equal to, or greather than the type of the other BsonValue.</returns>
  1027. public int CompareTypeTo(BsonValue other)
  1028. {
  1029. if (object.ReferenceEquals(other, null)) { return 1; }
  1030. return __bsonTypeSortOrder[_bsonType].CompareTo(__bsonTypeSortOrder[other._bsonType]);
  1031. }
  1032. /// <summary>
  1033. /// Creates a deep clone of the BsonValue (see also Clone).
  1034. /// </summary>
  1035. /// <returns>A deep clone of the BsonValue.</returns>
  1036. public virtual BsonValue DeepClone()
  1037. {
  1038. return this; // subclasses override DeepClone if necessary
  1039. }
  1040. /// <summary>
  1041. /// Compares this BsonValue to another BsonValue.
  1042. /// </summary>
  1043. /// <param name="rhs">The other BsonValue.</param>
  1044. /// <returns>True if the two BsonValue values are equal.</returns>
  1045. public bool Equals(BsonValue rhs)
  1046. {
  1047. return Equals((object)rhs);
  1048. }
  1049. /// <summary>
  1050. /// Compares this BsonValue to another object.
  1051. /// </summary>
  1052. /// <param name="obj">The other object.</param>
  1053. /// <returns>True if the other object is a BsonValue and equal to this one.</returns>
  1054. public override bool Equals(object obj)
  1055. {
  1056. throw new BsonInternalException("A subclass of BsonValue did not override Equals.");
  1057. }
  1058. /// <summary>
  1059. /// Gets the hash code.
  1060. /// </summary>
  1061. /// <returns>The hash code.</returns>
  1062. public override int GetHashCode()
  1063. {
  1064. throw new BsonInternalException("A subclass of BsonValue did not override GetHashCode.");
  1065. }
  1066. /// <summary>
  1067. /// Converts this BsonValue to a Boolean (using the JavaScript definition of truthiness).
  1068. /// </summary>
  1069. /// <returns>A Boolean.</returns>
  1070. public virtual bool ToBoolean()
  1071. {
  1072. // some subclasses override as appropriate
  1073. return true; // everything else is true
  1074. }
  1075. /// <summary>
  1076. /// Converts this BsonValue to a Double.
  1077. /// </summary>
  1078. /// <returns>A Double.</returns>
  1079. public virtual double ToDouble()
  1080. {
  1081. var message = string.Format("{0} does not support ToDouble.", this.GetType().Name);
  1082. throw new NotSupportedException(message);
  1083. }
  1084. /// <summary>
  1085. /// Converts this BsonValue to an Int32.
  1086. /// </summary>
  1087. /// <returns>An Int32.</returns>
  1088. public virtual int ToInt32()
  1089. {
  1090. var message = string.Format("{0} does not support ToInt32.", this.GetType().Name);
  1091. throw new NotSupportedException(message);
  1092. }
  1093. /// <summary>
  1094. /// Converts this BsonValue to an Int64.
  1095. /// </summary>
  1096. /// <returns>An Int64.</returns>
  1097. public virtual long ToInt64()
  1098. {
  1099. var message = string.Format("{0} does not support ToInt64.", this.GetType().Name);
  1100. throw new NotSupportedException(message);
  1101. }
  1102. /// <summary>
  1103. /// Converts this BsonValue to a DateTime in local time.
  1104. /// </summary>
  1105. /// <returns>A DateTime.</returns>
  1106. public virtual DateTime ToLocalTime()
  1107. {
  1108. var message = string.Format("{0} does not support ToLocalTime.", this.GetType().Name);
  1109. throw new NotSupportedException(message);
  1110. }
  1111. /// <summary>
  1112. /// Converts this BsonValue to a DateTime? in local time.
  1113. /// </summary>
  1114. /// <returns>A DateTime?.</returns>
  1115. public virtual DateTime? ToNullableLocalTime()
  1116. {
  1117. var message = string.Format("{0} does not support ToNullableLocalTime.", this.GetType().Name);
  1118. throw new NotSupportedException(message);
  1119. }
  1120. /// <summary>
  1121. /// Converts this BsonValue to a DateTime? in UTC.
  1122. /// </summary>
  1123. /// <returns>A DateTime?.</returns>
  1124. public virtual DateTime? ToNullableUniversalTime()
  1125. {
  1126. var message = string.Format("{0} does not support ToNullableUniversalTime.", this.GetType().Name);
  1127. throw new NotSupportedException(message);
  1128. }
  1129. /// <summary>
  1130. /// Converts this BsonValue to a DateTime in UTC.
  1131. /// </summary>
  1132. /// <returns>A DateTime.</returns>
  1133. public virtual DateTime ToUniversalTime()
  1134. {
  1135. var message = string.Format("{0} does not support ToUniversalTime.", this.GetType().Name);
  1136. throw new NotSupportedException(message);
  1137. }
  1138. /// <summary>
  1139. /// Writes the BsonValue to a BsonWriter.
  1140. /// </summary>
  1141. /// <param name="bsonWriter">The writer.</param>
  1142. [Obsolete("Use BsonSerializer.Serialize<BsonValue> instead.")]
  1143. public void WriteTo(BsonWriter bsonWriter)
  1144. {
  1145. BsonSerializer.Serialize(bsonWriter, this);
  1146. }
  1147. // protected methods
  1148. /// <summary>
  1149. /// Implementation of operator ==.
  1150. /// </summary>
  1151. /// <param name="rhs">The other BsonValue.</param>
  1152. /// <returns>True if the two BsonValues are equal according to ==.</returns>
  1153. protected virtual bool OperatorEqualsImplementation(BsonValue rhs)
  1154. {
  1155. return Equals(rhs); // default implementation of == is to call Equals
  1156. }
  1157. // explicit IConvertible implementation
  1158. TypeCode IConvertible.GetTypeCode()
  1159. {
  1160. switch (_bsonType)
  1161. {
  1162. case BsonType.Boolean: return TypeCode.Boolean;
  1163. case BsonType.DateTime: return TypeCode.DateTime;
  1164. case BsonType.Double: return TypeCode.Double;
  1165. case BsonType.Int32: return TypeCode.Int32;
  1166. case BsonType.Int64: return TypeCode.Int64;
  1167. case BsonType.String: return TypeCode.String;
  1168. default: return TypeCode.Object;
  1169. }
  1170. }
  1171. bool IConvertible.ToBoolean(IFormatProvider provider)
  1172. {
  1173. switch (_bsonType)
  1174. {
  1175. case BsonType.Boolean: return this.AsBoolean;
  1176. case BsonType.Double: return Convert.ToBoolean(this.AsDouble, provider);
  1177. case BsonType.Int32: return Convert.ToBoolean(this.AsInt32, provider);
  1178. case BsonType.Int64: return Convert.ToBoolean(this.AsInt64, provider);
  1179. case BsonType.String: return Convert.ToBoolean(this.AsString, provider);
  1180. default: throw new InvalidCastException();
  1181. }
  1182. }
  1183. byte IConvertible.ToByte(IFormatProvider provider)
  1184. {
  1185. switch (_bsonType)
  1186. {
  1187. case BsonType.Boolean: return Convert.ToByte(this.AsBoolean, provider);
  1188. case BsonType.Double: return Convert.ToByte(this.AsDouble, provider);
  1189. case BsonType.Int32: return Convert.ToByte(this.AsInt32, provider);
  1190. case BsonType.Int64: return Convert.ToByte(this.AsInt64, provider);
  1191. case BsonType.String: return Convert.ToByte(this.AsString, provider);
  1192. default: throw new InvalidCastException();
  1193. }
  1194. }
  1195. char IConvertible.ToChar(IFormatProvider provider)
  1196. {
  1197. switch (_bsonType)
  1198. {
  1199. case BsonType.Int32: return Convert.ToChar(this.AsInt32, provider);
  1200. case BsonType.Int64: return Convert.ToChar(this.AsInt64, provider);
  1201. case BsonType.String: return Convert.ToChar(this.AsString, provider);
  1202. default: throw new InvalidCastException();
  1203. }
  1204. }
  1205. DateTime IConvertible.ToDateTime(IFormatProvider provider)
  1206. {
  1207. switch (_bsonType)
  1208. {
  1209. case BsonType.DateTime: return this.ToUniversalTime();
  1210. case BsonType.String: return Convert.ToDateTime(this.AsString, provider);
  1211. default: throw new InvalidCastException();
  1212. }
  1213. }
  1214. decimal IConvertible.ToDecimal(IFormatProvider provider)
  1215. {
  1216. switch (_bsonType)
  1217. {
  1218. case BsonType.Boolean: return Convert.ToDecimal(this.AsBoolean, provider);
  1219. case BsonType.Double: return Convert.ToDecimal(this.AsDouble, provider);
  1220. case BsonType.Int32: return Convert.ToDecimal(this.AsInt32, provider);
  1221. case BsonType.Int64: return Convert.ToDecimal(this.AsInt64, provider);
  1222. case BsonType.String: return Convert.ToDecimal(this.AsString, provider);
  1223. default: throw new InvalidCastException();
  1224. }
  1225. }
  1226. double IConvertible.ToDouble(IFormatProvider provider)
  1227. {
  1228. switch (_bsonType)
  1229. {
  1230. case BsonType.Boolean: return Convert.ToDouble(this.AsBoolean, provider);
  1231. case BsonType.Double: return this.AsDouble;
  1232. case BsonType.Int32: return Convert.ToDouble(this.AsInt32, provider);
  1233. case BsonType.Int64: return Convert.ToDouble(this.AsInt64, provider);
  1234. case BsonType.String: return Convert.ToDouble(this.AsString, provider);
  1235. default: throw new InvalidCastException();
  1236. }
  1237. }
  1238. short IConvertible.ToInt16(IFormatProvider provider)
  1239. {
  1240. switch (_bsonType)
  1241. {
  1242. case BsonType.Boolean: return Convert.ToInt16(this.AsBoolean, provider);
  1243. case BsonType.Double: return Convert.ToInt16(this.AsDouble, provider);
  1244. case BsonType.Int32: return Convert.ToInt16(this.AsInt32, provider);
  1245. case BsonType.Int64: return Convert.ToInt16(this.AsInt64, provider);
  1246. case BsonType.String: return Convert.ToInt16(this.AsString, provider);
  1247. default: throw new InvalidCastException();
  1248. }
  1249. }
  1250. int IConvertible.ToInt32(IFormatProvider provider)
  1251. {
  1252. switch (_bsonType)
  1253. {
  1254. case BsonType.Boolean: return Convert.ToInt32(this.AsBoolean, provider);
  1255. case BsonType.Double: return Convert.ToInt32(this.AsDouble, provider);
  1256. case BsonType.Int32: return this.AsInt32;
  1257. case BsonType.Int64: return Convert.ToInt32(this.AsInt64, provider);
  1258. case BsonType.String: return Convert.ToInt32(this.AsString, provider);
  1259. default: throw new InvalidCastException();
  1260. }
  1261. }
  1262. long IConvertible.ToInt64(IFormatProvider provider)
  1263. {
  1264. switch (_bsonType)
  1265. {
  1266. case BsonType.Boolean: return Convert.ToInt64(this.AsBoolean, provider);
  1267. case BsonType.Double: return Convert.ToInt64(this.AsDouble, provider);
  1268. case BsonType.Int32: return Convert.ToInt64(this.AsInt32, provider);
  1269. case BsonType.Int64: return this.AsInt64;
  1270. case BsonType.String: return Convert.ToInt64(this.AsString, provider);
  1271. default: throw new InvalidCastException();
  1272. }
  1273. }
  1274. sbyte IConvertible.ToSByte(IFormatProvider provider)
  1275. {
  1276. switch (_bsonType)
  1277. {
  1278. case BsonType.Boolean: return Convert.ToSByte(this.AsBoolean, provider);
  1279. case BsonType.Double: return Convert.ToSByte(this.AsDouble, provider);
  1280. case BsonType.Int32: return Convert.ToSByte(this.AsInt32, provider);
  1281. case BsonType.Int64: return Convert.ToSByte(this.AsInt64, provider);
  1282. case BsonType.String: return Convert.ToSByte(this.AsString, provider);
  1283. default: throw new InvalidCastException();
  1284. }
  1285. }
  1286. float IConvertible.ToSingle(IFormatProvider provider)
  1287. {
  1288. switch (_bsonType)
  1289. {
  1290. case BsonType.Boolean: return Convert.ToSingle(this.AsBoolean, provider);
  1291. case BsonType.Double: return Convert.ToSingle(this.AsDouble, provider);
  1292. case BsonType.Int32: return Convert.ToSingle(this.AsInt32, provider);
  1293. case BsonType.Int64: return Convert.ToSingle(this.AsInt64, provider);
  1294. case BsonType.String: return Convert.ToSingle(this.AsString, provider);
  1295. default: throw new InvalidCastException();
  1296. }
  1297. }
  1298. string IConvertible.ToString(IFormatProvider provider)
  1299. {
  1300. switch (_bsonType)
  1301. {
  1302. case BsonType.Boolean: return Convert.ToString(this.AsBoolean, provider);
  1303. case BsonType.Double: return Convert.ToString(this.AsDouble, provider);
  1304. case BsonType.Int32: return Convert.ToString(this.AsInt32, provider);
  1305. case BsonType.Int64: return Convert.ToString(this.AsInt64, provider);
  1306. case BsonType.ObjectId: return this.AsObjectId.ToString();
  1307. case BsonType.String: return this.AsString;
  1308. default: throw new InvalidCastException();
  1309. }
  1310. }
  1311. object IConvertible.ToType(Type conversionType, IFormatProvider provider)
  1312. {
  1313. if (conversionType == typeof(object))
  1314. {
  1315. return this;
  1316. }
  1317. switch (_bsonType)
  1318. {
  1319. case BsonType.Boolean: return Convert.ChangeType(this.AsBoolean, conversionType, provider);
  1320. case BsonType.DateTime: return Convert.ChangeType(this.ToUniversalTime(), conversionType, provider);
  1321. case BsonType.Double: return Convert.ChangeType(this.AsDouble, conversionType, provider);
  1322. case BsonType.Int32: return Convert.ChangeType(this.AsInt32, conversionType, provider);
  1323. case BsonType.Int64: return Convert.ChangeType(this.AsInt64, conversionType, provider);
  1324. case BsonType.ObjectId: return Convert.ChangeType(this.AsObjectId, conversionType, provider);
  1325. case BsonType.String: return Convert.ChangeType(this.AsString, conversionType, provider);
  1326. default: throw new InvalidCastException();
  1327. }
  1328. }
  1329. ushort IConvertible.ToUInt16(IFormatProvider provider)
  1330. {
  1331. switch (_bsonType)
  1332. {
  1333. case BsonType.Boolean: return Convert.ToUInt16(this.AsBoolean, provider);
  1334. case BsonType.Double: return Convert.ToUInt16(this.AsDouble, provider);
  1335. case BsonType.Int32: return Convert.ToUInt16(this.AsInt32, provider);
  1336. case BsonType.Int64: return Convert.ToUInt16(this.AsInt64, provider);
  1337. case BsonType.String: return Convert.ToUInt16(this.AsString, provider);
  1338. default: throw new InvalidCastException();
  1339. }
  1340. }
  1341. uint IConvertible.ToUInt32(IFormatProvider provider)
  1342. {
  1343. switch (_bsonType)
  1344. {
  1345. case BsonType.Boolean: return Convert.ToUInt32(this.AsBoolean, provider);
  1346. case BsonType.Double: return Convert.ToUInt32(this.AsDouble, provider);
  1347. case BsonType.Int32: return Convert.ToUInt16(this.AsInt32, provider);
  1348. case BsonType.Int64: return Convert.ToUInt32(this.AsInt64, provider);
  1349. case BsonType.String: return Convert.ToUInt32(this.AsString, provider);
  1350. default: throw new InvalidCastException();
  1351. }
  1352. }
  1353. ulong IConvertible.ToUInt64(IFormatProvider provider)
  1354. {
  1355. switch (_bsonType)
  1356. {
  1357. case BsonType.Boolean: return Convert.ToUInt64(this.AsBoolean, provider);
  1358. case BsonType.Double: return Convert.ToUInt64(this.AsDouble, provider);
  1359. case BsonType.Int32: return Convert.ToUInt64(this.AsInt32, provider);
  1360. case BsonType.Int64: return Convert.ToUInt16(this.AsInt64, provider);
  1361. case BsonType.String: return Convert.ToUInt64(this.AsString, provider);
  1362. default: throw new InvalidCastException();
  1363. }
  1364. }
  1365. }
  1366. }