/// <summary> /// Positions the reader to a string element by name. /// </summary> /// <param name="reader">The reader.</param> /// <param name="name">The name of the element.</param> /// <returns>True if the element was found.</returns> public static string FindStringElement(this IBsonReader reader, string name) { BsonType bsonType; while ((bsonType = reader.ReadBsonType()) != BsonType.EndOfDocument) { if (bsonType == BsonType.String) { var elementName = reader.ReadName(); if (elementName == name) { return(reader.ReadString()); } else { reader.SkipValue(); } } else { reader.SkipName(); reader.SkipValue(); } } return(null); }
public Type GetActualType(IBsonReader bsonReader, Type nominalType) { var bookmark = bsonReader.GetBookmark(); bsonReader.ReadStartDocument(); var actualType = nominalType; while (bsonReader.ReadBsonType() != BsonType.EndOfDocument) { var name = bsonReader.ReadName(); if (name == "OnlyInB") { actualType = typeof(B); break; } else if (name == "OnlyInC") { actualType = typeof(C); break; } bsonReader.SkipValue(); } bsonReader.ReturnToBookmark(bookmark); return(actualType); }
/// <inheritdoc/> public Type GetActualType(IBsonReader bsonReader, Type nominalType) { ThrowIfNominalTypeIsIncorrect(nominalType); var bookmark = bsonReader.GetBookmark(); bsonReader.ReadStartDocument(); ObjectId id = default; while (bsonReader.ReadBsonType() != BsonType.EndOfDocument) { var fieldName = bsonReader.ReadName(); if (fieldName == ElementName) { var partitioned = bsonReader.ReadBoolean(); bsonReader.ReturnToBookmark(bookmark); return(partitioned ? typeof(Partitioned.PartitionedStreamProcessorState) : typeof(StreamProcessorState)); } else if (fieldName == "_id") { id = bsonReader.ReadObjectId(); } else { bsonReader.SkipValue(); } } bsonReader.ReturnToBookmark(bookmark); throw new StreamProcessorStateDocumentIsMissingPartitionedField(id); }
/// <summary> /// Positions the reader to an element by name. /// </summary> /// <param name="reader">The reader.</param> /// <param name="name">The name of the element.</param> /// <returns>True if the element was found.</returns> public static bool FindElement(this IBsonReader reader, string name) { while (reader.ReadBsonType() != BsonType.EndOfDocument) { var elementName = reader.ReadName(); if (elementName == name) { return(true); } reader.SkipValue(); } return(false); }
public Type GetActualType(IBsonReader bsonReader, Type nominalType) { var bookmark = bsonReader.GetBookmark(); bsonReader.ReadStartDocument(); var actualType = nominalType; while (bsonReader.ReadBsonType() != BsonType.EndOfDocument) { var name = bsonReader.ReadName(); if (name == "OnlyInB") { actualType = typeof(B); break; } else if (name == "OnlyInC") { actualType = typeof(C); break; } bsonReader.SkipValue(); } bsonReader.ReturnToBookmark(bookmark); return actualType; }
/***************************************************/ private object DeserializeDiscriminatedValue(BsonDeserializationContext context, BsonDeserializationArgs args) { // First try to recover the object type IBsonReader reader = context.Reader; BsonReaderBookmark bookmark = reader.GetBookmark(); Type actualType = typeof(CustomObject); try { actualType = _discriminatorConvention.GetActualType(reader, typeof(object)); } catch { // This is were we can call the Version_Engine to return the new type string from the old one if exists string recordedType = GetCurrentTypeValue(reader); // If failed, return Custom object context.Reader.ReturnToBookmark(bookmark); Engine.Reflection.Compute.RecordWarning("The type " + recordedType + " is unknown -> data returned as custom objects."); IBsonSerializer customSerializer = BsonSerializer.LookupSerializer(typeof(CustomObject)); return(customSerializer.Deserialize(context, args)); } // Handle the special case where the type is object if (actualType == typeof(object)) { BsonType currentBsonType = reader.GetCurrentBsonType(); if (currentBsonType == BsonType.Document && context.DynamicDocumentSerializer != null) { return(context.DynamicDocumentSerializer.Deserialize(context, args)); } reader.ReadStartDocument(); reader.ReadEndDocument(); return(new object()); } // Handle the genral case of finding the correct deserialiser and calling it IBsonSerializer bsonSerializer = BsonSerializer.LookupSerializer(actualType); IBsonPolymorphicSerializer bsonPolymorphicSerializer = bsonSerializer as IBsonPolymorphicSerializer; if (bsonPolymorphicSerializer != null && bsonPolymorphicSerializer.IsDiscriminatorCompatibleWithObjectSerializer) { bookmark = context.Reader.GetBookmark(); try { return(bsonSerializer.Deserialize(context, args)); } catch { context.Reader.ReturnToBookmark(bookmark); Engine.Reflection.Compute.RecordWarning("Cannot find a definition of type " + actualType.FullName + " that matches the object to deserialise -> data returned as custom objects."); IBsonSerializer customSerializer = BsonSerializer.LookupSerializer(typeof(CustomObject)); CustomObject fallback = customSerializer.Deserialize(context, args) as CustomObject; //This is where we will try to get the correct object type from the custom object using the versionning engine // If failed, just return the custom object return(fallback); } } object result = null; bool flag = false; reader.ReadStartDocument(); while (reader.ReadBsonType() != 0) { string text = reader.ReadName(); if (text == _discriminatorConvention.ElementName) { reader.SkipValue(); } else { if (!(text == "_v")) { throw new FormatException($"Unexpected element name: '{text}'."); } result = bsonSerializer.Deserialize(context); flag = true; } } reader.ReadEndDocument(); if (!flag) { throw new FormatException("_v element missing."); } return(result); }