/Bson/Serialization/Serializers/CollectionSerializers.cs

https://github.com/tadmarshall/mongo-csharp-driver · C# · 292 lines · 189 code · 17 blank · 86 comment · 33 complexity · 5b57ab17c3b6d00a3feed2eb85245c26 MD5 · raw file

  1. /* Copyright 2010-2011 10gen 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;
  17. using System.Collections.Generic;
  18. using System.Linq;
  19. using System.Text;
  20. using System.IO;
  21. using MongoDB.Bson.IO;
  22. using MongoDB.Bson.Serialization;
  23. namespace MongoDB.Bson.Serialization.Serializers {
  24. /// <summary>
  25. /// Represents a serializer for enumerable values.
  26. /// </summary>
  27. public class EnumerableSerializer : BsonBaseSerializer {
  28. #region private static fields
  29. private static EnumerableSerializer instance = new EnumerableSerializer();
  30. #endregion
  31. #region constructors
  32. /// <summary>
  33. /// Initializes a new instance of the EnumerableSerializer class.
  34. /// </summary>
  35. public EnumerableSerializer() {
  36. }
  37. #endregion
  38. #region public static properties
  39. /// <summary>
  40. /// Gets an instance of the EnumerableSerializer class.
  41. /// </summary>
  42. public static EnumerableSerializer Instance {
  43. get { return instance; }
  44. }
  45. #endregion
  46. #region public methods
  47. /// <summary>
  48. /// Deserializes an object from a BsonReader.
  49. /// </summary>
  50. /// <param name="bsonReader">The BsonReader.</param>
  51. /// <param name="nominalType">The nominal type of the object.</param>
  52. /// <param name="actualType">The actual type of the object.</param>
  53. /// <param name="options">The serialization options.</param>
  54. /// <returns>An object.</returns>
  55. public override object Deserialize(
  56. BsonReader bsonReader,
  57. Type nominalType,
  58. Type actualType, // ignored
  59. IBsonSerializationOptions options
  60. ) {
  61. var bsonType = bsonReader.CurrentBsonType;
  62. if (bsonType == BsonType.Null) {
  63. bsonReader.ReadNull();
  64. return null;
  65. } else if (bsonType == BsonType.Array) {
  66. bsonReader.ReadStartArray();
  67. var list = new ArrayList();
  68. var discriminatorConvention = BsonDefaultSerializer.LookupDiscriminatorConvention(typeof(object));
  69. while (bsonReader.ReadBsonType() != BsonType.EndOfDocument) {
  70. var elementType = discriminatorConvention.GetActualType(bsonReader, typeof(object));
  71. var serializer = BsonSerializer.LookupSerializer(elementType);
  72. var element = serializer.Deserialize(bsonReader, typeof(object), elementType, null);
  73. list.Add(element);
  74. }
  75. bsonReader.ReadEndArray();
  76. return list;
  77. } else {
  78. var message = string.Format("Can't deserialize a {0} from BsonType {1}.", nominalType.FullName, bsonType);
  79. throw new FileFormatException(message);
  80. }
  81. }
  82. /// <summary>
  83. /// Serializes an object to a BsonWriter.
  84. /// </summary>
  85. /// <param name="bsonWriter">The BsonWriter.</param>
  86. /// <param name="nominalType">The nominal type.</param>
  87. /// <param name="value">The object.</param>
  88. /// <param name="options">The serialization options.</param>
  89. public override void Serialize(
  90. BsonWriter bsonWriter,
  91. Type nominalType,
  92. object value,
  93. IBsonSerializationOptions options
  94. ) {
  95. if (value == null) {
  96. bsonWriter.WriteNull();
  97. } else {
  98. bsonWriter.WriteStartArray();
  99. foreach (var element in (IEnumerable) value) {
  100. BsonSerializer.Serialize(bsonWriter, typeof(object), element);
  101. }
  102. bsonWriter.WriteEndArray();
  103. }
  104. }
  105. #endregion
  106. }
  107. /// <summary>
  108. /// Represents a serializer for Queues.
  109. /// </summary>
  110. public class QueueSerializer : BsonBaseSerializer {
  111. #region private static fields
  112. private static QueueSerializer instance = new QueueSerializer();
  113. #endregion
  114. #region constructors
  115. /// <summary>
  116. /// Initializes a new instance of the QueueSerializer class.
  117. /// </summary>
  118. public QueueSerializer() {
  119. }
  120. #endregion
  121. #region public static properties
  122. /// <summary>
  123. /// Gets an instance of the QueueSerializer class.
  124. /// </summary>
  125. public static QueueSerializer Instance {
  126. get { return instance; }
  127. }
  128. #endregion
  129. #region public methods
  130. /// <summary>
  131. /// Deserializes an object from a BsonReader.
  132. /// </summary>
  133. /// <param name="bsonReader">The BsonReader.</param>
  134. /// <param name="nominalType">The nominal type of the object.</param>
  135. /// <param name="actualType">The actual type of the object.</param>
  136. /// <param name="options">The serialization options.</param>
  137. /// <returns>An object.</returns>
  138. public override object Deserialize(
  139. BsonReader bsonReader,
  140. Type nominalType,
  141. Type actualType, // ignored
  142. IBsonSerializationOptions options
  143. ) {
  144. var bsonType = bsonReader.CurrentBsonType;
  145. if (bsonType == BsonType.Null) {
  146. bsonReader.ReadNull();
  147. return null;
  148. } else if (bsonType == BsonType.Array) {
  149. bsonReader.ReadStartArray();
  150. var queue = new Queue();
  151. var discriminatorConvention = BsonDefaultSerializer.LookupDiscriminatorConvention(typeof(object));
  152. while (bsonReader.ReadBsonType() != BsonType.EndOfDocument) {
  153. var elementType = discriminatorConvention.GetActualType(bsonReader, typeof(object));
  154. var serializer = BsonSerializer.LookupSerializer(elementType);
  155. var element = serializer.Deserialize(bsonReader, typeof(object), elementType, null);
  156. queue.Enqueue(element);
  157. }
  158. bsonReader.ReadEndArray();
  159. return queue;
  160. } else {
  161. var message = string.Format("Can't deserialize a {0} from BsonType {1}.", nominalType.FullName, bsonType);
  162. throw new FileFormatException(message);
  163. }
  164. }
  165. /// <summary>
  166. /// Serializes an object to a BsonWriter.
  167. /// </summary>
  168. /// <param name="bsonWriter">The BsonWriter.</param>
  169. /// <param name="nominalType">The nominal type.</param>
  170. /// <param name="value">The object.</param>
  171. /// <param name="options">The serialization options.</param>
  172. public override void Serialize(
  173. BsonWriter bsonWriter,
  174. Type nominalType,
  175. object value,
  176. IBsonSerializationOptions options
  177. ) {
  178. if (value == null) {
  179. bsonWriter.WriteNull();
  180. } else {
  181. bsonWriter.WriteStartArray();
  182. foreach (var element in (Queue) value) {
  183. BsonSerializer.Serialize(bsonWriter, typeof(object), element);
  184. }
  185. bsonWriter.WriteEndArray();
  186. }
  187. }
  188. #endregion
  189. }
  190. /// <summary>
  191. /// Represents a serializer for Stacks.
  192. /// </summary>
  193. public class StackSerializer : BsonBaseSerializer {
  194. #region private static fields
  195. private static StackSerializer instance = new StackSerializer();
  196. #endregion
  197. #region constructors
  198. /// <summary>
  199. /// Initializes a new instance of the StackSerializer class.
  200. /// </summary>
  201. public StackSerializer() {
  202. }
  203. #endregion
  204. #region public static properties
  205. /// <summary>
  206. /// Gets an instance of the StackSerializer class.
  207. /// </summary>
  208. public static StackSerializer Instance {
  209. get { return instance; }
  210. }
  211. #endregion
  212. #region public methods
  213. /// <summary>
  214. /// Deserializes an object from a BsonReader.
  215. /// </summary>
  216. /// <param name="bsonReader">The BsonReader.</param>
  217. /// <param name="nominalType">The nominal type of the object.</param>
  218. /// <param name="actualType">The actual type of the object.</param>
  219. /// <param name="options">The serialization options.</param>
  220. /// <returns>An object.</returns>
  221. public override object Deserialize(
  222. BsonReader bsonReader,
  223. Type nominalType,
  224. Type actualType, // ignored
  225. IBsonSerializationOptions options
  226. ) {
  227. var bsonType = bsonReader.CurrentBsonType;
  228. if (bsonType == BsonType.Null) {
  229. bsonReader.ReadNull();
  230. return null;
  231. } else if (bsonType == BsonType.Array) {
  232. bsonReader.ReadStartArray();
  233. var stack = new Stack();
  234. var discriminatorConvention = BsonDefaultSerializer.LookupDiscriminatorConvention(typeof(object));
  235. while (bsonReader.ReadBsonType() != BsonType.EndOfDocument) {
  236. var elementType = discriminatorConvention.GetActualType(bsonReader, typeof(object));
  237. var serializer = BsonSerializer.LookupSerializer(elementType);
  238. var element = serializer.Deserialize(bsonReader, typeof(object), elementType, null);
  239. stack.Push(element);
  240. }
  241. bsonReader.ReadEndArray();
  242. return stack;
  243. } else {
  244. var message = string.Format("Can't deserialize a {0} from BsonType {1}.", nominalType.FullName, bsonType);
  245. throw new FileFormatException(message);
  246. }
  247. }
  248. /// <summary>
  249. /// Serializes an object to a BsonWriter.
  250. /// </summary>
  251. /// <param name="bsonWriter">The BsonWriter.</param>
  252. /// <param name="nominalType">The nominal type.</param>
  253. /// <param name="value">The object.</param>
  254. /// <param name="options">The serialization options.</param>
  255. public override void Serialize(
  256. BsonWriter bsonWriter,
  257. Type nominalType,
  258. object value,
  259. IBsonSerializationOptions options
  260. ) {
  261. if (value == null) {
  262. bsonWriter.WriteNull();
  263. } else {
  264. bsonWriter.WriteStartArray();
  265. var outputOrder = new ArrayList((Stack) value); // serialize first pushed item first (reverse of enumerator order)
  266. outputOrder.Reverse();
  267. foreach (var element in outputOrder) {
  268. BsonSerializer.Serialize(bsonWriter, typeof(object), element);
  269. }
  270. bsonWriter.WriteEndArray();
  271. }
  272. }
  273. #endregion
  274. }
  275. }