ThreeDimensionalArraySerializer.cs 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. /* Copyright 2010-present MongoDB Inc.
  2. *
  3. * Licensed under the Apache License, Version 2.0 (the "License");
  4. * you may not use this file except in compliance with the License.
  5. * You may obtain a copy of the License at
  6. *
  7. * http://www.apache.org/licenses/LICENSE-2.0
  8. *
  9. * Unless required by applicable law or agreed to in writing, software
  10. * distributed under the License is distributed on an "AS IS" BASIS,
  11. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. * See the License for the specific language governing permissions and
  13. * limitations under the License.
  14. */
  15. using System;
  16. using System.Collections.Generic;
  17. namespace MongoDB.Bson.Serialization.Serializers
  18. {
  19. /// <summary>
  20. /// Represents a serializer for three-dimensional arrays.
  21. /// </summary>
  22. /// <typeparam name="TItem">The type of the elements.</typeparam>
  23. public class ThreeDimensionalArraySerializer<TItem> :
  24. SealedClassSerializerBase<TItem[,,]>,
  25. IChildSerializerConfigurable
  26. {
  27. // private fields
  28. private readonly Lazy<IBsonSerializer<TItem>> _lazyItemSerializer;
  29. // constructors
  30. /// <summary>
  31. /// Initializes a new instance of the <see cref="ThreeDimensionalArraySerializer{TItem}"/> class.
  32. /// </summary>
  33. public ThreeDimensionalArraySerializer()
  34. : this(BsonSerializer.SerializerRegistry)
  35. {
  36. }
  37. /// <summary>
  38. /// Initializes a new instance of the <see cref="ThreeDimensionalArraySerializer{TItem}"/> class.
  39. /// </summary>
  40. /// <param name="itemSerializer">The item serializer.</param>
  41. public ThreeDimensionalArraySerializer(IBsonSerializer<TItem> itemSerializer)
  42. {
  43. if (itemSerializer == null)
  44. {
  45. throw new ArgumentNullException("itemSerializer");
  46. }
  47. _lazyItemSerializer = new Lazy<IBsonSerializer<TItem>>(() => itemSerializer);
  48. }
  49. /// <summary>
  50. /// Initializes a new instance of the <see cref="ThreeDimensionalArraySerializer{TItem}" /> class.
  51. /// </summary>
  52. /// <param name="serializerRegistry">The serializer registry.</param>
  53. public ThreeDimensionalArraySerializer(IBsonSerializerRegistry serializerRegistry)
  54. {
  55. if (serializerRegistry == null)
  56. {
  57. throw new ArgumentNullException("serializerRegistry");
  58. }
  59. _lazyItemSerializer = new Lazy<IBsonSerializer<TItem>>(() => serializerRegistry.GetSerializer<TItem>());
  60. }
  61. // public properties
  62. /// <summary>
  63. /// Gets the item serializer.
  64. /// </summary>
  65. /// <value>
  66. /// The item serializer.
  67. /// </value>
  68. public IBsonSerializer<TItem> ItemSerializer
  69. {
  70. get { return _lazyItemSerializer.Value; }
  71. }
  72. // public methods
  73. /// <summary>
  74. /// Deserializes a value.
  75. /// </summary>
  76. /// <param name="context">The deserialization context.</param>
  77. /// <param name="args">The deserialization args.</param>
  78. /// <returns>A deserialized value.</returns>
  79. protected override TItem[, ,] DeserializeValue(BsonDeserializationContext context, BsonDeserializationArgs args)
  80. {
  81. var bsonReader = context.Reader;
  82. EnsureBsonTypeEquals(bsonReader, BsonType.Array);
  83. bsonReader.ReadStartArray();
  84. var outerList = new List<List<List<TItem>>>();
  85. while (bsonReader.ReadBsonType() != BsonType.EndOfDocument)
  86. {
  87. bsonReader.ReadStartArray();
  88. var middleList = new List<List<TItem>>();
  89. while (bsonReader.ReadBsonType() != BsonType.EndOfDocument)
  90. {
  91. bsonReader.ReadStartArray();
  92. var innerList = new List<TItem>();
  93. while (bsonReader.ReadBsonType() != BsonType.EndOfDocument)
  94. {
  95. var item = _lazyItemSerializer.Value.Deserialize(context);
  96. innerList.Add(item);
  97. }
  98. bsonReader.ReadEndArray();
  99. middleList.Add(innerList);
  100. }
  101. bsonReader.ReadEndArray();
  102. outerList.Add(middleList);
  103. }
  104. bsonReader.ReadEndArray();
  105. var length1 = outerList.Count;
  106. var length2 = (length1 == 0) ? 0 : outerList[0].Count;
  107. var length3 = (length2 == 0) ? 0 : outerList[0][0].Count;
  108. var array = new TItem[length1, length2, length3];
  109. for (int i = 0; i < length1; i++)
  110. {
  111. var middleList = outerList[i];
  112. if (middleList.Count != length2)
  113. {
  114. var message = string.Format("Middle list {0} is of length {1} but should be of length {2}.", i, middleList.Count, length2);
  115. throw new FormatException(message);
  116. }
  117. for (int j = 0; j < length2; j++)
  118. {
  119. var innerList = middleList[j];
  120. if (innerList.Count != length3)
  121. {
  122. var message = string.Format("Inner list {0} is of length {1} but should be of length {2}.", j, innerList.Count, length3);
  123. throw new FormatException(message);
  124. }
  125. for (int k = 0; k < length3; k++)
  126. {
  127. array[i, j, k] = innerList[k];
  128. }
  129. }
  130. }
  131. return array;
  132. }
  133. /// <summary>
  134. /// Serializes a value.
  135. /// </summary>
  136. /// <param name="context">The serialization context.</param>
  137. /// <param name="args">The serialization args.</param>
  138. /// <param name="value">The object.</param>
  139. protected override void SerializeValue(BsonSerializationContext context, BsonSerializationArgs args, TItem[,,] value)
  140. {
  141. var bsonWriter = context.Writer;
  142. var length1 = value.GetLength(0);
  143. var length2 = value.GetLength(1);
  144. var length3 = value.GetLength(2);
  145. bsonWriter.WriteStartArray();
  146. for (int i = 0; i < length1; i++)
  147. {
  148. bsonWriter.WriteStartArray();
  149. for (int j = 0; j < length2; j++)
  150. {
  151. bsonWriter.WriteStartArray();
  152. for (int k = 0; k < length3; k++)
  153. {
  154. _lazyItemSerializer.Value.Serialize(context, value[i, j, k]);
  155. }
  156. bsonWriter.WriteEndArray();
  157. }
  158. bsonWriter.WriteEndArray();
  159. }
  160. bsonWriter.WriteEndArray();
  161. }
  162. /// <summary>
  163. /// Returns a serializer that has been reconfigured with the specified item serializer.
  164. /// </summary>
  165. /// <param name="itemSerializer">The item serializer.</param>
  166. /// <returns>The reconfigured serializer.</returns>
  167. public ThreeDimensionalArraySerializer<TItem> WithItemSerializer(IBsonSerializer<TItem> itemSerializer)
  168. {
  169. return new ThreeDimensionalArraySerializer<TItem>(itemSerializer);
  170. }
  171. // explicit interface implementations
  172. IBsonSerializer IChildSerializerConfigurable.ChildSerializer
  173. {
  174. get { return ItemSerializer; }
  175. }
  176. IBsonSerializer IChildSerializerConfigurable.WithChildSerializer(IBsonSerializer childSerializer)
  177. {
  178. return WithItemSerializer((IBsonSerializer<TItem>)childSerializer);
  179. }
  180. }
  181. }