GuidSerializer.cs 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  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.IO;
  17. using MongoDB.Bson.IO;
  18. using MongoDB.Bson.Serialization.Attributes;
  19. using MongoDB.Bson.Serialization.Options;
  20. namespace MongoDB.Bson.Serialization.Serializers
  21. {
  22. /// <summary>
  23. /// Represents a serializer for Guids.
  24. /// </summary>
  25. public class GuidSerializer : StructSerializerBase<Guid>, IRepresentationConfigurable<GuidSerializer>
  26. {
  27. // private fields
  28. private readonly BsonType _representation;
  29. // constructors
  30. /// <summary>
  31. /// Initializes a new instance of the <see cref="GuidSerializer"/> class.
  32. /// </summary>
  33. public GuidSerializer()
  34. : this(BsonType.Binary)
  35. {
  36. }
  37. /// <summary>
  38. /// Initializes a new instance of the <see cref="GuidSerializer"/> class.
  39. /// </summary>
  40. /// <param name="representation">The representation.</param>
  41. public GuidSerializer(BsonType representation)
  42. {
  43. switch (representation)
  44. {
  45. case BsonType.Binary:
  46. case BsonType.String:
  47. break;
  48. default:
  49. var message = string.Format("{0} is not a valid representation for a GuidSerializer.", representation);
  50. throw new ArgumentException(message);
  51. }
  52. _representation = representation;
  53. }
  54. // public properties
  55. /// <summary>
  56. /// Gets the representation.
  57. /// </summary>
  58. /// <value>
  59. /// The representation.
  60. /// </value>
  61. public BsonType Representation
  62. {
  63. get { return _representation; }
  64. }
  65. // public methods
  66. /// <summary>
  67. /// Deserializes a value.
  68. /// </summary>
  69. /// <param name="context">The deserialization context.</param>
  70. /// <param name="args">The deserialization args.</param>
  71. /// <returns>A deserialized value.</returns>
  72. public override Guid Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args)
  73. {
  74. var bsonReader = context.Reader;
  75. string message;
  76. var bsonType = bsonReader.GetCurrentBsonType();
  77. switch (bsonType)
  78. {
  79. case BsonType.Binary:
  80. var binaryData = bsonReader.ReadBinaryData();
  81. var bytes = binaryData.Bytes;
  82. var subType = binaryData.SubType;
  83. var guidRepresentation = binaryData.GuidRepresentation;
  84. if (bytes.Length != 16)
  85. {
  86. message = string.Format("Expected length to be 16, not {0}.", bytes.Length);
  87. throw new FormatException(message);
  88. }
  89. if (subType != BsonBinarySubType.UuidStandard && subType != BsonBinarySubType.UuidLegacy)
  90. {
  91. message = string.Format("Expected binary sub type to be UuidStandard or UuidLegacy, not {0}.", subType);
  92. throw new FormatException(message);
  93. }
  94. if (guidRepresentation == GuidRepresentation.Unspecified)
  95. {
  96. throw new BsonSerializationException("GuidSerializer cannot deserialize a Guid when GuidRepresentation is Unspecified.");
  97. }
  98. return GuidConverter.FromBytes(bytes, guidRepresentation);
  99. case BsonType.String:
  100. return new Guid(bsonReader.ReadString());
  101. default:
  102. throw CreateCannotDeserializeFromBsonTypeException(bsonType);
  103. }
  104. }
  105. /// <summary>
  106. /// Serializes a value.
  107. /// </summary>
  108. /// <param name="context">The serialization context.</param>
  109. /// <param name="args">The serialization args.</param>
  110. /// <param name="value">The object.</param>
  111. public override void Serialize(BsonSerializationContext context, BsonSerializationArgs args, Guid value)
  112. {
  113. var bsonWriter = context.Writer;
  114. switch (_representation)
  115. {
  116. case BsonType.Binary:
  117. var writerGuidRepresentation = bsonWriter.Settings.GuidRepresentation;
  118. if (writerGuidRepresentation == GuidRepresentation.Unspecified)
  119. {
  120. throw new BsonSerializationException("GuidSerializer cannot serialize a Guid when GuidRepresentation is Unspecified.");
  121. }
  122. var bytes = GuidConverter.ToBytes(value, writerGuidRepresentation);
  123. var subType = (writerGuidRepresentation == GuidRepresentation.Standard) ? BsonBinarySubType.UuidStandard : BsonBinarySubType.UuidLegacy;
  124. bsonWriter.WriteBinaryData(new BsonBinaryData(bytes, subType, writerGuidRepresentation));
  125. break;
  126. case BsonType.String:
  127. bsonWriter.WriteString(value.ToString());
  128. break;
  129. default:
  130. var message = string.Format("'{0}' is not a valid Guid representation.", _representation);
  131. throw new BsonSerializationException(message);
  132. }
  133. }
  134. /// <summary>
  135. /// Returns a serializer that has been reconfigured with the specified representation.
  136. /// </summary>
  137. /// <param name="representation">The representation.</param>
  138. /// <returns>The reconfigured serializer.</returns>
  139. public GuidSerializer WithRepresentation(BsonType representation)
  140. {
  141. if (representation == _representation)
  142. {
  143. return this;
  144. }
  145. else
  146. {
  147. return new GuidSerializer(representation);
  148. }
  149. }
  150. // explicit interface implementations
  151. IBsonSerializer IRepresentationConfigurable.WithRepresentation(BsonType representation)
  152. {
  153. return WithRepresentation(representation);
  154. }
  155. }
  156. }