You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

234 lines
9.1 KiB

  1. /* Copyright 2010 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.DefaultSerializer {
  24. public static class EnumerableSerializerRegistration {
  25. #region public static methods
  26. public static void RegisterGenericSerializerDefinitions() {
  27. BsonSerializer.RegisterGenericSerializerDefinition(typeof(HashSet<>), typeof(EnumerableSerializer<>));
  28. BsonSerializer.RegisterGenericSerializerDefinition(typeof(ICollection<>), typeof(EnumerableSerializer<>));
  29. BsonSerializer.RegisterGenericSerializerDefinition(typeof(IEnumerable<>), typeof(EnumerableSerializer<>));
  30. BsonSerializer.RegisterGenericSerializerDefinition(typeof(IList<>), typeof(EnumerableSerializer<>));
  31. BsonSerializer.RegisterGenericSerializerDefinition(typeof(List<>), typeof(EnumerableSerializer<>));
  32. BsonSerializer.RegisterGenericSerializerDefinition(typeof(LinkedList<>), typeof(EnumerableSerializer<>));
  33. }
  34. #endregion
  35. }
  36. public class EnumerableSerializer<T> : BsonBaseSerializer {
  37. #region constructors
  38. public EnumerableSerializer() {
  39. }
  40. public EnumerableSerializer(
  41. object serializationOptions
  42. ) {
  43. }
  44. #endregion
  45. #region public methods
  46. public override object Deserialize(
  47. BsonReader bsonReader,
  48. Type nominalType
  49. ) {
  50. var bsonType = bsonReader.CurrentBsonType;
  51. if (bsonType == BsonType.Null) {
  52. bsonReader.ReadNull();
  53. return null;
  54. } else if (bsonType == BsonType.Array) {
  55. bsonReader.ReadStartArray();
  56. var list = (nominalType == typeof(List<T>) || nominalType.IsInterface) ? new List<T>() : (ICollection<T>) Activator.CreateInstance(nominalType);
  57. var discriminatorConvention = BsonDefaultSerializer.LookupDiscriminatorConvention(typeof(T));
  58. while (bsonReader.ReadBsonType() != BsonType.EndOfDocument) {
  59. bsonReader.SkipName();
  60. var elementType = discriminatorConvention.GetActualType(bsonReader, typeof(T));
  61. var serializer = BsonSerializer.LookupSerializer(elementType);
  62. var element = (T) serializer.Deserialize(bsonReader, typeof(T));
  63. list.Add(element);
  64. }
  65. bsonReader.ReadEndArray();
  66. return list;
  67. } else {
  68. var message = string.Format("Can't deserialize a {0} from BsonType {1}", nominalType.FullName, bsonType);
  69. throw new FileFormatException(message);
  70. }
  71. }
  72. public override void Serialize(
  73. BsonWriter bsonWriter,
  74. Type nominalType,
  75. object value,
  76. bool serializeIdFirst
  77. ) {
  78. if (value == null) {
  79. bsonWriter.WriteNull();
  80. } else {
  81. bsonWriter.WriteStartArray();
  82. int index = 0;
  83. foreach (var element in (IEnumerable<T>) value) {
  84. bsonWriter.WriteName(index.ToString());
  85. BsonSerializer.Serialize(bsonWriter, typeof(T), element);
  86. index++;
  87. }
  88. bsonWriter.WriteEndArray();
  89. }
  90. }
  91. #endregion
  92. }
  93. public static class QueueSerializerRegistration {
  94. #region public static methods
  95. public static void RegisterGenericSerializerDefinitions() {
  96. BsonSerializer.RegisterGenericSerializerDefinition(typeof(Queue<>), typeof(QueueSerializer<>));
  97. }
  98. #endregion
  99. }
  100. public class QueueSerializer<T> : BsonBaseSerializer {
  101. #region constructors
  102. public QueueSerializer(
  103. object serializationOptions
  104. ) {
  105. }
  106. #endregion
  107. #region public methods
  108. public override object Deserialize(
  109. BsonReader bsonReader,
  110. Type nominalType
  111. ) {
  112. var bsonType = bsonReader.CurrentBsonType;
  113. if (bsonType == BsonType.Null) {
  114. bsonReader.ReadNull();
  115. return null;
  116. } else if (bsonType == BsonType.Array) {
  117. bsonReader.ReadStartArray();
  118. var queue = new Queue<T>();
  119. var discriminatorConvention = BsonDefaultSerializer.LookupDiscriminatorConvention(typeof(T));
  120. while (bsonReader.ReadBsonType() != BsonType.EndOfDocument) {
  121. bsonReader.SkipName();
  122. var elementType = discriminatorConvention.GetActualType(bsonReader, typeof(T));
  123. var serializer = BsonSerializer.LookupSerializer(elementType);
  124. var element = (T) serializer.Deserialize(bsonReader, typeof(T));
  125. queue.Enqueue(element);
  126. }
  127. bsonReader.ReadEndArray();
  128. return queue;
  129. } else {
  130. var message = string.Format("Can't deserialize a {0} from BsonType {1}", nominalType.FullName, bsonType);
  131. throw new FileFormatException(message);
  132. }
  133. }
  134. public override void Serialize(
  135. BsonWriter bsonWriter,
  136. Type nominalType,
  137. object value,
  138. bool serializeIdFirst
  139. ) {
  140. if (value == null) {
  141. bsonWriter.WriteNull();
  142. } else {
  143. bsonWriter.WriteStartArray();
  144. int index = 0;
  145. foreach (var element in (Queue<T>) value) {
  146. bsonWriter.WriteName(index.ToString());
  147. BsonSerializer.Serialize(bsonWriter, typeof(T), element);
  148. index++;
  149. }
  150. bsonWriter.WriteEndArray();
  151. }
  152. }
  153. #endregion
  154. }
  155. public static class StackSerializerRegistration {
  156. #region public static methods
  157. public static void RegisterGenericSerializerDefinitions() {
  158. BsonSerializer.RegisterGenericSerializerDefinition(typeof(Stack<>), typeof(StackSerializer<>));
  159. }
  160. #endregion
  161. }
  162. public class StackSerializer<T> : BsonBaseSerializer {
  163. #region constructors
  164. public StackSerializer(
  165. object serializationOptions
  166. ) {
  167. }
  168. #endregion
  169. #region public methods
  170. public override object Deserialize(
  171. BsonReader bsonReader,
  172. Type nominalType
  173. ) {
  174. var bsonType = bsonReader.CurrentBsonType;
  175. if (bsonType == BsonType.Null) {
  176. bsonReader.ReadNull();
  177. return null;
  178. } else if (bsonType == BsonType.Array) {
  179. bsonReader.ReadStartArray();
  180. var stack = new Stack<T>();
  181. var discriminatorConvention = BsonDefaultSerializer.LookupDiscriminatorConvention(typeof(T));
  182. while (bsonReader.ReadBsonType() != BsonType.EndOfDocument) {
  183. bsonReader.SkipName();
  184. var elementType = discriminatorConvention.GetActualType(bsonReader, typeof(T));
  185. var serializer = BsonSerializer.LookupSerializer(elementType);
  186. var element = (T) serializer.Deserialize(bsonReader, typeof(T));
  187. stack.Push(element);
  188. }
  189. bsonReader.ReadEndArray();
  190. return stack;
  191. } else {
  192. var message = string.Format("Can't deserialize a {0} from BsonType {1}", nominalType.FullName, bsonType);
  193. throw new FileFormatException(message);
  194. }
  195. }
  196. public override void Serialize(
  197. BsonWriter bsonWriter,
  198. Type nominalType,
  199. object value,
  200. bool serializeIdFirst
  201. ) {
  202. if (value == null) {
  203. bsonWriter.WriteNull();
  204. } else {
  205. bsonWriter.WriteStartArray();
  206. var outputOrder = new List<T>((Stack<T>) value); // serialize first pushed item first (reverse of enumerator order)
  207. outputOrder.Reverse();
  208. int index = 0;
  209. foreach (var element in outputOrder) {
  210. bsonWriter.WriteName(index.ToString());
  211. BsonSerializer.Serialize(bsonWriter, typeof(T), element);
  212. index++;
  213. }
  214. bsonWriter.WriteEndArray();
  215. }
  216. }
  217. #endregion
  218. }
  219. }