PageRenderTime 55ms CodeModel.GetById 28ms RepoModel.GetById 1ms app.codeStats 0ms

/src/MongoDB.Driver/DBObjectArray.cs

https://github.com/automatonic/mongodb-net
C# | 607 lines | 279 code | 50 blank | 278 comment | 17 complexity | 81ce02edd368507d104ca3d396b970b7 MD5 | raw file
Possible License(s): Apache-2.0
  1. //DEVFUEL COPYRIGHT
  2. using System;
  3. using System.Collections;
  4. using System.Collections.Generic;
  5. using MongoDB.Driver.Conditions;
  6. namespace MongoDB.Driver
  7. {
  8. /// <summary>
  9. /// Utility class to support an array of <see cref="IDBObject"/> instances
  10. /// </summary>
  11. /// <remarks>
  12. /// <example caption="Expanding to indexes">
  13. /// <code><![CDATA[
  14. /// DBObjectArray obj = new DBObjectArray();
  15. /// obj["0"] = value1;
  16. /// obj["4"] = value2;
  17. /// obj[2] = value3;
  18. /// ]]></code>
  19. /// </example>
  20. /// <example caption="Invalid indexes">
  21. /// <code><![CDATA[
  22. /// BasicDBList list = new BasicDBList();
  23. /// list["1"] ="bar"; // ok
  24. /// list["1E1"] ="bar"; // throws exception
  25. /// ]]></code>
  26. /// </remarks>
  27. /// </example>
  28. public class DBObjectArray : IList, IList<object>, IDBObject
  29. {
  30. List<object> _list = null;
  31. /// <summary>
  32. /// Initializes a new instance of the <see cref="DBObjectArray"/> class.
  33. /// </summary>
  34. public DBObjectArray()
  35. {
  36. _list = new List<object>();
  37. }
  38. /// <summary>
  39. /// Initializes a new instance of the <see cref="DBObjectArray"/> class.
  40. /// </summary>
  41. /// <param name="capacity">The capacity.</param>
  42. public DBObjectArray(int capacity)
  43. {
  44. _list = new List<object>(capacity);
  45. }
  46. /// <summary>
  47. /// Initializes a new instance of the <see cref="DBObjectArray"/> class.
  48. /// </summary>
  49. /// <param name="map">The map.</param>
  50. public DBObjectArray(IDictionary<string, object> map)
  51. {
  52. Condition.Requires(map, "map").IsNotNull();
  53. _list = new List<object>(map.Count);
  54. PutAll(map);
  55. }
  56. /// <summary>
  57. /// Initializes a new instance of the <see cref="DBObjectArray"/> class.
  58. /// </summary>
  59. /// <param name="list">The list.</param>
  60. public DBObjectArray(params DBObject[] list)
  61. {
  62. Condition.Requires(list, "list").IsNotNull();
  63. _list = new List<object>(list.Length);
  64. foreach (object o in list)
  65. {
  66. (_list as IList).Add(o);
  67. }
  68. }
  69. /// <summary>
  70. /// Initializes a new instance of the <see cref="DBObjectArray"/> class.
  71. /// </summary>
  72. /// <param name="list">The list.</param>
  73. public DBObjectArray(IList list)
  74. {
  75. Condition.Requires(list, "list").IsNotNull();
  76. _list = new List<object>(list.Count);
  77. foreach (object o in list)
  78. {
  79. (_list as IList).Add(o);
  80. }
  81. }
  82. /// <summary>
  83. /// Initializes a new instance of the <see cref="DBObjectArray"/> class.
  84. /// </summary>
  85. /// <param name="list">The list.</param>
  86. public DBObjectArray(IList<object> list)
  87. {
  88. _list = new List<object>(list);
  89. }
  90. /// <summary>
  91. /// Puts all the pairs in the dictionary into this array
  92. /// </summary>
  93. /// <param name="map">The map.</param>
  94. public void PutAll(IDictionary<string, object> map)
  95. {
  96. foreach (KeyValuePair<string,object> pair in map)
  97. {
  98. this[pair.Key] = pair.Value;
  99. }
  100. }
  101. /// <summary>
  102. /// Gets or sets the capacity.
  103. /// </summary>
  104. /// <value>The capacity.</value>
  105. public int Capacity { get { return _list.Capacity; } set { _list.Capacity = value; } }
  106. /// <summary>
  107. /// Adds the specified pair.
  108. /// </summary>
  109. /// <param name="key">The key.</param>
  110. /// <param name="value">The value.</param>
  111. public void Add(string key, object value)
  112. {
  113. this[key] = value;
  114. }
  115. /// <summary>
  116. /// Determines whether this array contains the specified key.
  117. /// </summary>
  118. /// <param name="key">The key.</param>
  119. /// <returns>
  120. /// <c>true</c> if this array contains the specified key; otherwise, <c>false</c>.
  121. /// </returns>
  122. public bool ContainsKey(string key)
  123. {
  124. int index = int.Parse(key);
  125. return index < _list.Count && index >= 0;
  126. }
  127. /// <summary>
  128. /// Gets the keys for this collection (which should be integers as strings).
  129. /// </summary>
  130. /// <value>The keys.</value>
  131. public ICollection<string> Keys
  132. {
  133. get
  134. {
  135. int i = 0;
  136. return _list.ConvertAll(o => (i++).ToString());
  137. }
  138. }
  139. /// <summary>
  140. /// Removes the pair identified by the specified key.
  141. /// </summary>
  142. /// <param name="key">The key.</param>
  143. /// <returns></returns>
  144. public bool Remove(string key)
  145. {
  146. _list.RemoveAt(int.Parse(key));
  147. return true;
  148. }
  149. /// <summary>
  150. /// Tries to get the value associated with the specified key
  151. /// </summary>
  152. /// <param name="key">The key.</param>
  153. /// <param name="value">The value.</param>
  154. /// <returns><c>true</c> if the value was found; <c>false</c> otherwise.</returns>
  155. public bool TryGetValue(string key, out object value)
  156. {
  157. value = null;
  158. int index = 0;
  159. if (!int.TryParse(key, out index) || index < 0 || index >= Count)
  160. return false;
  161. value = _list[index];
  162. return true;
  163. }
  164. /// <summary>
  165. /// Gets all the values in the collection
  166. /// </summary>
  167. /// <value>The values.</value>
  168. public ICollection<object> Values
  169. {
  170. get
  171. {
  172. return _list;
  173. }
  174. }
  175. /// <summary>
  176. /// Gets or sets the value associated with the specified key.
  177. /// </summary>
  178. /// <remarks>
  179. /// Setting with an index greater than the capacity will cause an error. Otherwise the list will resize (filling with null entries) to accommodate.</remarks>
  180. /// <value>The associated value</value>
  181. /// <exception cref="System.ArgumentException"/>
  182. public object this[string key]
  183. {
  184. get
  185. {
  186. int index = -1;
  187. if (!int.TryParse(key, out index))
  188. throw new ArgumentException("Cannot parse integer index", "key");
  189. return this[index];
  190. }
  191. set
  192. {
  193. int index = -1;
  194. if (!int.TryParse(key, out index))
  195. throw new ArgumentException("Cannot parse integer index", "key");
  196. this[index] = value;
  197. }
  198. }
  199. /// <summary>
  200. /// Gets or sets the value associated with the specified index.
  201. /// </summary>
  202. /// <remarks>
  203. /// Setting with an index greater than the capacity will cause an error. Otherwise the list will resize (filling with null entries) to accommodate.</remarks>
  204. /// <value>The associated value</value>
  205. /// <exception cref="System.ArgumentException"/>
  206. public object this[int key]
  207. {
  208. get
  209. {
  210. if (key < 0 || key >= _list.Count)
  211. throw new ArgumentOutOfRangeException("key");
  212. return _list[key];
  213. }
  214. set
  215. {
  216. if (key < 0)
  217. throw new ArgumentOutOfRangeException("key");
  218. while (key >= _list.Count)//allow a set that extends the list length (inside the capacity)
  219. {
  220. _list.Add(null);
  221. }
  222. _list[key] = value;
  223. }
  224. }
  225. /// <summary>
  226. /// Adds the specified pair.
  227. /// </summary>
  228. /// <param name="pair">The item.</param>
  229. public void Add(KeyValuePair<string, object> pair)
  230. {
  231. this[pair.Key] = pair.Value;
  232. }
  233. /// <summary>
  234. /// Removes all items from this collection.
  235. /// </summary>
  236. /// <exception cref="T:System.NotSupportedException">The <see cref="T:System.Collections.IList"/> is read-only. </exception>
  237. public void Clear()
  238. {
  239. _list.Clear();
  240. }
  241. /// <summary>
  242. /// Determines whether this collection contains the specified pair
  243. /// </summary>
  244. /// <param name="pair">The pair.</param>
  245. /// <returns>
  246. /// <c>true</c> if this collection contains the pair; otherwise, <c>false</c>.
  247. /// </returns>
  248. public bool Contains(KeyValuePair<string, object> pair)
  249. {
  250. return ContainsKey(pair.Key) && this[pair.Key].Equals(pair.Value);
  251. }
  252. /// <summary>
  253. /// Copies this collection's pairs to the specified array at the specified index
  254. /// </summary>
  255. /// <param name="array">The array.</param>
  256. /// <param name="arrayIndex">Index of the array.</param>
  257. public void CopyTo(KeyValuePair<string, object>[] array, int arrayIndex)
  258. {
  259. if (array == null)
  260. throw new ArgumentNullException("array");
  261. if (arrayIndex >= array.Length)
  262. throw new ArgumentException("index must be within the array", "arrayIndex");
  263. int source = 0;
  264. for (int dest = arrayIndex; dest < array.Length; dest++)
  265. {
  266. array[dest] = new KeyValuePair<string, object>(source.ToString(), _list[source++]);
  267. }
  268. }
  269. /// <summary>
  270. /// Gets the number of elements contained in the <see cref="T:System.Collections.ICollection"/>.
  271. /// </summary>
  272. /// <value></value>
  273. /// <returns>The number of elements contained in the <see cref="T:System.Collections.ICollection"/>.</returns>
  274. public int Count
  275. {
  276. get { return _list.Count; }
  277. }
  278. /// <summary>
  279. /// Gets a value indicating whether the <see cref="T:System.Collections.IList"/> is read-only.
  280. /// </summary>
  281. /// <value></value>
  282. /// <returns>true if the <see cref="T:System.Collections.IList"/> is read-only; otherwise, false.</returns>
  283. bool ICollection<System.Collections.Generic.KeyValuePair<string, object>>.IsReadOnly
  284. {
  285. get { return false; }
  286. }
  287. /// <summary>
  288. /// Gets a value indicating whether the <see cref="T:System.Collections.IList"/> is read-only.
  289. /// </summary>
  290. /// <value></value>
  291. /// <returns>true if the <see cref="T:System.Collections.IList"/> is read-only; otherwise, false.</returns>
  292. bool ICollection<object>.IsReadOnly
  293. {
  294. get { return false; }
  295. }
  296. /// <summary>
  297. /// Removes the specified pair.
  298. /// </summary>
  299. /// <param name="pair">The pair to remove.</param>
  300. /// <returns></returns>
  301. public bool Remove(KeyValuePair<string, object> pair)
  302. {
  303. return Remove(pair.Key);
  304. }
  305. /// <summary>
  306. /// Gets a pair enumerator.
  307. /// </summary>
  308. /// <returns>the enumerator</returns>
  309. public IEnumerator<KeyValuePair<string, object>> GetEnumerator()
  310. {
  311. if (Count == 0)
  312. return new List<KeyValuePair<string, object>>().GetEnumerator();
  313. KeyValuePair<string, object>[] entryArray = new KeyValuePair<string, object>[Count];
  314. CopyTo(entryArray, 0);
  315. List<KeyValuePair<string, object>> entries = new List<KeyValuePair<string, object>>(entryArray);
  316. return entries.GetEnumerator();
  317. }
  318. /// <summary>
  319. /// Returns an enumerator that iterates through a collection.
  320. /// </summary>
  321. /// <returns>
  322. /// An <see cref="T:System.Collections.IEnumerator"/> object that can be used to iterate through the collection.
  323. /// </returns>
  324. IEnumerator IEnumerable.GetEnumerator()
  325. {
  326. return _list.GetEnumerator();
  327. }
  328. /// <summary>
  329. /// Finds the index of the specified value
  330. /// </summary>
  331. /// <param name="value">The value in the collection.</param>
  332. /// <returns></returns>
  333. public int IndexOf(object value)
  334. {
  335. return _list.IndexOf(value);
  336. }
  337. /// <summary>
  338. /// Inserts the specified item at the specified index.
  339. /// </summary>
  340. /// <param name="index">The index.</param>
  341. /// <param name="value">The value.</param>
  342. public void Insert(int index, object value)
  343. {
  344. _list.Insert(index, value);
  345. }
  346. /// <summary>
  347. /// Removes the <see cref="T:System.Collections.IList"/> item at the specified index.
  348. /// </summary>
  349. /// <param name="index">The zero-based index of the item to remove.</param>
  350. /// <exception cref="T:System.ArgumentOutOfRangeException">
  351. /// <paramref name="index"/> is not a valid index in the <see cref="T:System.Collections.IList"/>. </exception>
  352. /// <exception cref="T:System.NotSupportedException">The <see cref="T:System.Collections.IList"/> is read-only.-or- The <see cref="T:System.Collections.IList"/> has a fixed size. </exception>
  353. public void RemoveAt(int index)
  354. {
  355. _list.RemoveAt(index);
  356. }
  357. /// <summary>
  358. /// Adds the specified value to the end of the collection.
  359. /// </summary>
  360. /// <param name="value">The item.</param>
  361. public void Add(object value)
  362. {
  363. _list.Add(value);
  364. }
  365. /// <summary>
  366. /// Determines whether this collection contains the specified value.
  367. /// </summary>
  368. /// <param name="value">The value.</param>
  369. /// <returns>
  370. /// <c>true</c> if this collection contains the specified value; otherwise, <c>false</c>.
  371. /// </returns>
  372. public bool Contains(object value)
  373. {
  374. return _list.Contains(value);
  375. }
  376. /// <summary>
  377. /// Copies this collection's values to the array at the specified index
  378. /// </summary>
  379. /// <param name="array">the array.</param>
  380. /// <param name="arrayIndex">the index.</param>
  381. public void CopyTo(object[] array, int arrayIndex)
  382. {
  383. _list.CopyTo(array, arrayIndex);
  384. }
  385. /// <summary>
  386. /// Removes the specified value.
  387. /// </summary>
  388. /// <param name="value">The value.</param>
  389. /// <returns><c>true</c> if the value was found and removed; <c>false</c> otherwise.</returns>
  390. public bool Remove(object value)
  391. {
  392. return _list.Remove(value);
  393. }
  394. /// <summary>
  395. /// Gets the enumerator.
  396. /// </summary>
  397. /// <returns>the enumerator</returns>
  398. IEnumerator<object> IEnumerable<object>.GetEnumerator()
  399. {
  400. return _list.GetEnumerator();
  401. }
  402. private IList _ilist { get { return _list as IList; } }
  403. /// <summary>
  404. /// Adds an item to the <see cref="T:System.Collections.IList"/>.
  405. /// </summary>
  406. /// <param name="value">The object to add to the <see cref="T:System.Collections.IList"/>.</param>
  407. /// <returns>
  408. /// The position into which the new element was inserted, or -1 to indicate that the item was not inserted into the collection,
  409. /// </returns>
  410. /// <exception cref="T:System.NotSupportedException">The <see cref="T:System.Collections.IList"/> is read-only.-or- The <see cref="T:System.Collections.IList"/> has a fixed size. </exception>
  411. int IList.Add(object value)
  412. {
  413. return _ilist.Add(value);
  414. }
  415. /// <summary>
  416. /// Removes all items from the <see cref="T:System.Collections.IList"/>.
  417. /// </summary>
  418. /// <exception cref="T:System.NotSupportedException">The <see cref="T:System.Collections.IList"/> is read-only. </exception>
  419. void IList.Clear()
  420. {
  421. _ilist.Clear();
  422. }
  423. /// <summary>
  424. /// Determines whether the <see cref="T:System.Collections.IList"/> contains a specific value.
  425. /// </summary>
  426. /// <param name="value">The object to locate in the <see cref="T:System.Collections.IList"/>.</param>
  427. /// <returns>
  428. /// true if the <see cref="T:System.Object"/> is found in the <see cref="T:System.Collections.IList"/>; otherwise, false.
  429. /// </returns>
  430. bool IList.Contains(object value)
  431. {
  432. return _ilist.Contains(value);
  433. }
  434. /// <summary>
  435. /// Determines the index of a specific item in the <see cref="T:System.Collections.IList"/>.
  436. /// </summary>
  437. /// <param name="value">The object to locate in the <see cref="T:System.Collections.IList"/>.</param>
  438. /// <returns>
  439. /// The index of <paramref name="value"/> if found in the list; otherwise, -1.
  440. /// </returns>
  441. int IList.IndexOf(object value)
  442. {
  443. return _ilist.IndexOf(value);
  444. }
  445. /// <summary>
  446. /// Inserts an item to the <see cref="T:System.Collections.IList"/> at the specified index.
  447. /// </summary>
  448. /// <param name="index">The zero-based index at which <paramref name="value"/> should be inserted.</param>
  449. /// <param name="value">The object to insert into the <see cref="T:System.Collections.IList"/>.</param>
  450. /// <exception cref="T:System.ArgumentOutOfRangeException">
  451. /// <paramref name="index"/> is not a valid index in the <see cref="T:System.Collections.IList"/>. </exception>
  452. /// <exception cref="T:System.NotSupportedException">The <see cref="T:System.Collections.IList"/> is read-only.-or- The <see cref="T:System.Collections.IList"/> has a fixed size. </exception>
  453. /// <exception cref="T:System.NullReferenceException">
  454. /// <paramref name="value"/> is null reference in the <see cref="T:System.Collections.IList"/>.</exception>
  455. void IList.Insert(int index, object value)
  456. {
  457. _ilist.Insert(index, value);
  458. }
  459. /// <summary>
  460. /// Gets a value indicating whether the <see cref="T:System.Collections.IList"/> has a fixed size.
  461. /// </summary>
  462. /// <value></value>
  463. /// <returns>true if the <see cref="T:System.Collections.IList"/> has a fixed size; otherwise, false.</returns>
  464. bool IList.IsFixedSize
  465. {
  466. get { return _ilist.IsFixedSize; }
  467. }
  468. /// <summary>
  469. /// Gets a value indicating whether the <see cref="T:System.Collections.IList"/> is read-only.
  470. /// </summary>
  471. /// <value></value>
  472. /// <returns>true if the <see cref="T:System.Collections.IList"/> is read-only; otherwise, false.</returns>
  473. bool IList.IsReadOnly
  474. {
  475. get { return _ilist.IsReadOnly; }
  476. }
  477. /// <summary>
  478. /// Removes the first occurrence of a specific object from the <see cref="T:System.Collections.IList"/>.
  479. /// </summary>
  480. /// <param name="value">The object to remove from the <see cref="T:System.Collections.IList"/>.</param>
  481. /// <exception cref="T:System.NotSupportedException">The <see cref="T:System.Collections.IList"/> is read-only.-or- The <see cref="T:System.Collections.IList"/> has a fixed size. </exception>
  482. void IList.Remove(object value)
  483. {
  484. _ilist.Remove(value);
  485. }
  486. /// <summary>
  487. /// Removes the <see cref="T:System.Collections.IList"/> item at the specified index.
  488. /// </summary>
  489. /// <param name="index">The zero-based index of the item to remove.</param>
  490. /// <exception cref="T:System.ArgumentOutOfRangeException">
  491. /// <paramref name="index"/> is not a valid index in the <see cref="T:System.Collections.IList"/>. </exception>
  492. /// <exception cref="T:System.NotSupportedException">The <see cref="T:System.Collections.IList"/> is read-only.-or- The <see cref="T:System.Collections.IList"/> has a fixed size. </exception>
  493. void IList.RemoveAt(int index)
  494. {
  495. _ilist.RemoveAt(index);
  496. }
  497. /// <summary>
  498. /// Gets or sets the <see cref="System.Object"/> at the specified index.
  499. /// </summary>
  500. /// <value></value>
  501. object IList.this[int index]
  502. {
  503. get
  504. {
  505. return this[index];
  506. }
  507. set
  508. {
  509. this[index] = value;
  510. }
  511. }
  512. ICollection _icollection { get { return _list as ICollection; } }
  513. /// <summary>
  514. /// Copies the elements of the <see cref="T:System.Collections.ICollection"/> to an <see cref="T:System.Array"/>, starting at a particular <see cref="T:System.Array"/> index.
  515. /// </summary>
  516. /// <param name="array">The one-dimensional <see cref="T:System.Array"/> that is the destination of the elements copied from <see cref="T:System.Collections.ICollection"/>. The <see cref="T:System.Array"/> must have zero-based indexing.</param>
  517. /// <param name="index">The zero-based index in <paramref name="array"/> at which copying begins.</param>
  518. /// <exception cref="T:System.ArgumentNullException">
  519. /// <paramref name="array"/> is null. </exception>
  520. /// <exception cref="T:System.ArgumentOutOfRangeException">
  521. /// <paramref name="index"/> is less than zero. </exception>
  522. /// <exception cref="T:System.ArgumentException">
  523. /// <paramref name="array"/> is multidimensional.-or- The number of elements in the source <see cref="T:System.Collections.ICollection"/> is greater than the available space from <paramref name="index"/> to the end of the destination <paramref name="array"/>. </exception>
  524. /// <exception cref="T:System.ArgumentException">The type of the source <see cref="T:System.Collections.ICollection"/> cannot be cast automatically to the type of the destination <paramref name="array"/>. </exception>
  525. void ICollection.CopyTo(Array array, int index)
  526. {
  527. _icollection.CopyTo(array, index);
  528. }
  529. /// <summary>
  530. /// Gets the number of elements contained in the <see cref="T:System.Collections.ICollection"/>.
  531. /// </summary>
  532. /// <value></value>
  533. /// <returns>The number of elements contained in the <see cref="T:System.Collections.ICollection"/>.</returns>
  534. int ICollection.Count
  535. {
  536. get { return _icollection.Count; }
  537. }
  538. /// <summary>
  539. /// Gets a value indicating whether access to the <see cref="T:System.Collections.ICollection"/> is synchronized (thread safe).
  540. /// </summary>
  541. /// <value></value>
  542. /// <returns>true if access to the <see cref="T:System.Collections.ICollection"/> is synchronized (thread safe); otherwise, false.</returns>
  543. bool ICollection.IsSynchronized
  544. {
  545. get { return _icollection.IsSynchronized; }
  546. }
  547. /// <summary>
  548. /// Gets an object that can be used to synchronize access to the <see cref="T:System.Collections.ICollection"/>.
  549. /// </summary>
  550. /// <value></value>
  551. /// <returns>An object that can be used to synchronize access to the <see cref="T:System.Collections.ICollection"/>.</returns>
  552. object ICollection.SyncRoot
  553. {
  554. get { return _icollection.SyncRoot; }
  555. }
  556. }
  557. }