// public methods /// <summary> /// Apply an attribute to these serialization options and modify the options accordingly. /// </summary> /// <param name="serializer">The serializer that these serialization options are for.</param> /// <param name="attribute">The serialization options attribute.</param> public override void ApplyAttribute(IBsonSerializer serializer, Attribute attribute) { EnsureNotFrozen(); var representationAttribute = attribute as BsonRepresentationAttribute; if (representationAttribute != null) { _representation = representationAttribute.Representation; return; } var optionsAttribute = attribute as BsonTimeSpanOptionsAttribute; if (optionsAttribute != null) { _representation = optionsAttribute.Representation; _units = optionsAttribute.Units; return; } var message = string.Format("A serialization options attribute of type {0} cannot be applied to serialization options of type {1}.", BsonUtils.GetFriendlyTypeName(attribute.GetType()), BsonUtils.GetFriendlyTypeName(GetType())); throw new NotSupportedException(message); }
public void TestLessThanMinToDateTimeConversion() { var actual = BsonUtils.ToDateTimeFromMillisecondsSinceEpoch( BsonConstants.DateTimeMinValueMillisecondsSinceEpoch - 1); }
/// <summary> /// Writes a BSON DateTime to the writer. /// </summary> /// <param name="value">The number of milliseconds since the Unix epoch.</param> public override void WriteDateTime(long value) { if (Disposed) { throw new ObjectDisposedException("JsonWriter"); } if (State != BsonWriterState.Value && State != BsonWriterState.Initial) { ThrowInvalidState("WriteDateTime", BsonWriterState.Value, BsonWriterState.Initial); } switch (_jsonWriterSettings.OutputMode) { case JsonOutputMode.Strict: WriteStartDocument(); WriteInt64("$date", value); WriteEndDocument(); break; case JsonOutputMode.JavaScript: case JsonOutputMode.TenGen: WriteNameHelper(Name); _textWriter.Write("new Date({0})", value); break; case JsonOutputMode.Shell: WriteNameHelper(Name); if (_jsonWriterSettings.ShellVersion >= new Version(1, 8, 0)) { // use ISODate for values that fall within .NET's DateTime range, and "new Date" for all others if (value >= BsonConstants.DateTimeMinValueMillisecondsSinceEpoch && value <= BsonConstants.DateTimeMaxValueMillisecondsSinceEpoch) { var utcDateTime = BsonUtils.ToDateTimeFromMillisecondsSinceEpoch(value); if (!_jsonWriterSettings.UseIso8601DateFormat) { _textWriter.Write("ISODate(\"{0}\")", utcDateTime.ToString("yyyy-MM-ddTHH:mm:ss.FFFZ")); } else { _textWriter.Write("\"{0}\"", utcDateTime.ToString("s", CultureInfo.InvariantCulture)); } } else { _textWriter.Write("new Date({0})", value); } } else { _textWriter.Write("new Date({0})", value); } break; default: throw new BsonInternalException("Unexpected JsonOutputMode."); } State = GetNextState(); }
public void TestToHexStringNull() { var actual = BsonUtils.ToHexString(null); }
public void TestParseHexStringInvalid2() { var actual = BsonUtils.ParseHexString("00 1"); }
/// <summary> /// To the hex string. /// </summary> /// <param name="bytes">The bytes.</param> /// <returns></returns> protected string ToHexString(byte[] bytes) { return(BsonUtils.ToHexString(bytes)); }
private void TranslateWithIndex(MethodCallExpression methodCallExpression) { if (methodCallExpression.Arguments.Count != 2) { throw new ArgumentOutOfRangeException("methodCallExpression"); } var method = methodCallExpression.Method; if (method.DeclaringType != typeof(LinqToMongo)) { var message = string.Format("WithIndex method of class {0} is not supported.", BsonUtils.GetFriendlyTypeName(method.DeclaringType)); throw new NotSupportedException(message); } if (_indexHint != null) { throw new NotSupportedException("Only one index can be used for each query"); } if (_distinct != null) { var message = "WithIndex cannot be used together with Distinct."; throw new NotSupportedException(message); } Expression expression = methodCallExpression.Arguments[1]; if (expression.Type != typeof(BsonString) && expression.Type != typeof(BsonDocument)) { throw new ArgumentOutOfRangeException("methodCallExpression", "Expected an Expression of Type BsonString or BsonDocument."); } var constantExpression = expression as ConstantExpression; if (constantExpression == null) { throw new ArgumentOutOfRangeException("methodCallExpression", "Expected a ConstantExpression."); } _indexHint = (BsonValue)constantExpression.Value; }
/// <summary> /// Gets the serializer. /// </summary> /// <param name="type">The type.</param> /// <returns></returns> public override IBsonSerializer GetSerializer(Type type) { if (type == null) { throw new ArgumentNullException("type"); } if (type.IsGenericType && type.ContainsGenericParameters) { var message = string.Format("Generic type {0} has unassigned type parameters.", BsonUtils.GetFriendlyTypeName(type)); throw new ArgumentException(message, "type"); } if (type.IsInterface) { var serializerTypeDefinition = typeof(DiscriminatedInterfaceSerializer <>); return(CreateGenericSerializer(serializerTypeDefinition, type)); } return(null); }
/// <summary> /// Registers a serializer for a type. /// </summary> /// <param name="type">The type.</param> /// <param name="serializer">The serializer.</param> public static void RegisterSerializer(Type type, IBsonSerializer serializer) { if (typeof(IBsonSerializable).IsAssignableFrom(type)) { var message = string.Format("A serializer cannot be registered for type {0} because it implements IBsonSerializable.", BsonUtils.GetFriendlyTypeName(type)); throw new BsonSerializationException(message); } __configLock.EnterWriteLock(); try { if (__serializers.ContainsKey(type)) { var message = string.Format("There is already a serializer registered for type {0}.", type.FullName); throw new BsonSerializationException(message); } __serializers.Add(type, serializer); } finally { __configLock.ExitWriteLock(); } }
// public methods /// <summary> /// Apply an attribute to these serialization options and modify the options accordingly. /// </summary> /// <param name="serializer">The serializer that these serialization options are for.</param> /// <param name="attribute">The serialization options attribute.</param> public override void ApplyAttribute(IBsonSerializer serializer, Attribute attribute) { EnsureNotFrozen(); var message = string.Format("A serialization options attribute of type {0} cannot be applied to serialization options of type {1}.", BsonUtils.GetFriendlyTypeName(attribute.GetType()), BsonUtils.GetFriendlyTypeName(GetType())); throw new NotSupportedException(message); }
/// <summary> /// Gets a serializer for a type. /// </summary> /// <param name="type">The type.</param> /// <returns> /// A serializer. /// </returns> public override IBsonSerializer GetSerializer(Type type) { if (type == null) { throw new ArgumentNullException("type"); } if (type.IsGenericType && type.ContainsGenericParameters) { var message = string.Format("Generic type {0} has unassigned type parameters.", BsonUtils.GetFriendlyTypeName(type)); throw new ArgumentException(message, "type"); } Type serializerType; if (__serializersTypes.TryGetValue(type, out serializerType)) { return(CreateSerializer(serializerType)); } if (type.IsGenericType && !type.ContainsGenericParameters) { Type serializerTypeDefinition; if (__serializersTypes.TryGetValue(type.GetGenericTypeDefinition(), out serializerTypeDefinition)) { return(CreateGenericSerializer(serializerTypeDefinition, type.GetGenericArguments())); } } if (type.IsEnum) { return(CreateGenericSerializer(typeof(EnumSerializer <>), type)); } return(null); }
/// <summary> /// Serializes an object to a BsonWriter. /// </summary> /// <param name="bsonWriter">The BsonWriter.</param> /// <param name="nominalType">The nominal type.</param> /// <param name="value">The object.</param> /// <param name="options">The serialization options.</param> public override void Serialize( BsonWriter bsonWriter, Type nominalType, object value, IBsonSerializationOptions options) { if (value == null) { bsonWriter.WriteNull(); } else { if (nominalType == typeof(object)) { var actualType = value.GetType(); bsonWriter.WriteStartDocument(); bsonWriter.WriteString("_t", TypeNameDiscriminator.GetDiscriminator(actualType)); bsonWriter.WriteName("_v"); Serialize(bsonWriter, actualType, value, options); // recursive call replacing nominalType with actualType bsonWriter.WriteEndDocument(); return; } var dictionary = (IDictionary <TKey, TValue>)value; var dictionarySerializationOptions = EnsureSerializationOptions(options); var dictionaryRepresentation = dictionarySerializationOptions.Representation; var keyValuePairSerializationOptions = dictionarySerializationOptions.KeyValuePairSerializationOptions; if (dictionaryRepresentation == DictionaryRepresentation.Dynamic) { if (typeof(TKey) == typeof(string) || typeof(TKey) == typeof(object)) { dictionaryRepresentation = DictionaryRepresentation.Document; foreach (object key in dictionary.Keys) { var name = key as string; // key might not be a string if (name == null || (name.Length > 0 && name[0] == '$') || name.IndexOf('.') != -1) { dictionaryRepresentation = DictionaryRepresentation.ArrayOfArrays; break; } } } else { dictionaryRepresentation = DictionaryRepresentation.ArrayOfArrays; } } switch (dictionaryRepresentation) { case DictionaryRepresentation.Document: bsonWriter.WriteStartDocument(); foreach (var keyValuePair in dictionary) { bsonWriter.WriteName((string)(object)keyValuePair.Key); BsonSerializer.Serialize(bsonWriter, typeof(TValue), keyValuePair.Value, keyValuePairSerializationOptions.ValueSerializationOptions); } bsonWriter.WriteEndDocument(); break; case DictionaryRepresentation.ArrayOfArrays: case DictionaryRepresentation.ArrayOfDocuments: // override KeyValuePair representation if necessary var keyValuePairRepresentation = (dictionaryRepresentation == DictionaryRepresentation.ArrayOfArrays) ? BsonType.Array : BsonType.Document; if (keyValuePairSerializationOptions.Representation != keyValuePairRepresentation) { keyValuePairSerializationOptions = new KeyValuePairSerializationOptions( keyValuePairRepresentation, keyValuePairSerializationOptions.KeySerializationOptions, keyValuePairSerializationOptions.ValueSerializationOptions); } bsonWriter.WriteStartArray(); foreach (var keyValuePair in dictionary) { _keyValuePairSerializer.Serialize( bsonWriter, typeof(KeyValuePair <TKey, TValue>), keyValuePair, keyValuePairSerializationOptions); } bsonWriter.WriteEndArray(); break; default: var message = string.Format("'{0}' is not a valid IDictionary<{1}, {2}> representation.", dictionaryRepresentation, BsonUtils.GetFriendlyTypeName(typeof(TKey)), BsonUtils.GetFriendlyTypeName(typeof(TValue))); throw new BsonSerializationException(message); } } }
/*******************************************/ public override DataTable Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args) { var bsonReader = context.Reader; var bsonType = bsonReader.CurrentBsonType; if (bsonReader.State != BsonReaderState.Type) { bsonType = bsonReader.GetCurrentBsonType(); } string message; switch (bsonType) { case BsonType.Array: bsonReader.ReadStartArray(); DataTable table = new DataTable(); bool initialised = false; while (bsonReader.State != BsonReaderState.EndOfArray && bsonReader.ReadBsonType() != BsonType.EndOfDocument) { Dictionary <string, object> rowData = BsonSerializer.Deserialize <Dictionary <string, object> >(bsonReader); if (!initialised) { foreach (var kvp in rowData) { table.Columns.Add(new DataColumn(kvp.Key, kvp.Value.GetType())); } initialised = true; } DataRow row = table.NewRow(); foreach (var kvp in rowData) { row[kvp.Key] = kvp.Value; } table.Rows.Add(row); } bsonReader.ReadEndArray(); return(table); default: message = string.Format("Cannot deserialize a '{0}' from BsonType '{1}'.", BsonUtils.GetFriendlyTypeName(typeof(DataTable)), bsonType); throw new FormatException(message); } }
// public methods /// <summary> /// Apply an attribute to these serialization options and modify the options accordingly. /// </summary> /// <param name="serializer">The serializer that these serialization options are for.</param> /// <param name="attribute">The serialization options attribute.</param> public override void ApplyAttribute(IBsonSerializer serializer, Attribute attribute) { EnsureNotFrozen(); var dictionaryOptionsAttribute = attribute as BsonDictionaryOptionsAttribute; if (dictionaryOptionsAttribute != null) { _representation = dictionaryOptionsAttribute.Representation; return; } // for backward compatibility reasons representations Array and Document apply to the Dictionary and not the values var representationAttribute = attribute as BsonRepresentationAttribute; if (representationAttribute != null) { switch (representationAttribute.Representation) { case BsonType.Array: _representation = DictionaryRepresentation.ArrayOfArrays; return; case BsonType.Document: _representation = DictionaryRepresentation.Document; return; } } // any other attributes are applied to the values var valueType = typeof(object); if (serializer.GetType().IsGenericType) { valueType = serializer.GetType().GetGenericArguments()[1]; // TValue } var valueSerializer = BsonSerializer.LookupSerializer(valueType); var valueSerializationOptions = _keyValuePairSerializationOptions.ValueSerializationOptions; if (valueSerializationOptions == null) { var valueDefaultSerializationOptions = valueSerializer.GetDefaultSerializationOptions(); // special case for legacy dictionaries: allow BsonRepresentation on object if (valueDefaultSerializationOptions == null && serializer.GetType() == typeof(DictionarySerializer) && attribute.GetType() == typeof(BsonRepresentationAttribute)) { valueDefaultSerializationOptions = new RepresentationSerializationOptions(BsonType.Null); // will be modified later by ApplyAttribute } if (valueDefaultSerializationOptions == null) { var message = string.Format( "A serialization options attribute of type {0} cannot be used when the serializer is of type {1} and the value serializer is of type {2}.", BsonUtils.GetFriendlyTypeName(attribute.GetType()), BsonUtils.GetFriendlyTypeName(serializer.GetType()), BsonUtils.GetFriendlyTypeName(valueSerializer.GetType())); throw new NotSupportedException(message); } valueSerializationOptions = valueDefaultSerializationOptions.Clone(); } valueSerializationOptions.ApplyAttribute(valueSerializer, attribute); _keyValuePairSerializationOptions = new KeyValuePairSerializationOptions( _keyValuePairSerializationOptions.Representation, _keyValuePairSerializationOptions.KeySerializationOptions, valueSerializationOptions); }
// public methods /// <summary> /// Deserializes an object from a BsonReader. /// </summary> /// <param name="bsonReader">The BsonReader.</param> /// <param name="nominalType">The nominal type of the object.</param> /// <param name="actualType">The actual type of the object.</param> /// <param name="options">The serialization options.</param> /// <returns>An object.</returns> public override object Deserialize( BsonReader bsonReader, Type nominalType, Type actualType, IBsonSerializationOptions options) { VerifyTypes(nominalType, actualType, typeof(SystemProfileInfo)); if (bsonReader.GetCurrentBsonType() == Bson.BsonType.Null) { bsonReader.ReadNull(); return(null); } else { var profileInfo = new SystemProfileInfo(); bsonReader.ReadStartDocument(); BsonType bsonType; while ((bsonType = bsonReader.ReadBsonType()) != BsonType.EndOfDocument) { var name = bsonReader.ReadName(); switch (name) { case "abbreviated": profileInfo.Abbreviated = bsonReader.ReadString(); break; case "client": profileInfo.Client = bsonReader.ReadString(); break; case "command": profileInfo.Command = BsonDocument.ReadFrom(bsonReader); break; case "cursorid": profileInfo.CursorId = BsonValue.ReadFrom(bsonReader).ToInt64(); break; case "err": profileInfo.Error = bsonReader.ReadString(); break; case "exception": profileInfo.Exception = bsonReader.ReadString(); break; case "exceptionCode": profileInfo.ExceptionCode = BsonValue.ReadFrom(bsonReader).ToInt32(); break; case "exhaust": profileInfo.Exhaust = BsonValue.ReadFrom(bsonReader).ToBoolean(); break; case "fastmod": profileInfo.FastMod = BsonValue.ReadFrom(bsonReader).ToBoolean(); break; case "fastmodinsert": profileInfo.FastModInsert = BsonValue.ReadFrom(bsonReader).ToBoolean(); break; case "idhack": profileInfo.IdHack = BsonValue.ReadFrom(bsonReader).ToBoolean(); break; case "info": profileInfo.Info = bsonReader.ReadString(); break; case "keyUpdates": profileInfo.KeyUpdates = BsonValue.ReadFrom(bsonReader).ToInt32(); break; case "millis": profileInfo.Duration = TimeSpan.FromMilliseconds(BsonValue.ReadFrom(bsonReader).ToDouble()); break; case "moved": profileInfo.Moved = BsonValue.ReadFrom(bsonReader).ToBoolean(); break; case "nreturned": profileInfo.NumberReturned = BsonValue.ReadFrom(bsonReader).ToInt32(); break; case "ns": profileInfo.Namespace = bsonReader.ReadString(); break; case "nscanned": profileInfo.NumberScanned = BsonValue.ReadFrom(bsonReader).ToInt32(); break; case "ntoreturn": profileInfo.NumberToReturn = BsonValue.ReadFrom(bsonReader).ToInt32(); break; case "ntoskip": profileInfo.NumberToSkip = BsonValue.ReadFrom(bsonReader).ToInt32(); break; case "op": profileInfo.Op = bsonReader.ReadString(); break; case "query": profileInfo.Query = BsonDocument.ReadFrom(bsonReader); break; case "responseLength": profileInfo.ResponseLength = BsonValue.ReadFrom(bsonReader).ToInt32(); break; case "scanAndOrder": profileInfo.ScanAndOrder = BsonValue.ReadFrom(bsonReader).ToBoolean(); break; case "ts": profileInfo.Timestamp = BsonUtils.ToDateTimeFromMillisecondsSinceEpoch(bsonReader.ReadDateTime()); break; case "updateobj": profileInfo.UpdateObject = BsonDocument.ReadFrom(bsonReader); break; case "upsert": profileInfo.Upsert = BsonValue.ReadFrom(bsonReader).ToBoolean(); break; case "user": profileInfo.User = bsonReader.ReadString(); break; default: break; // ignore unknown elements } } bsonReader.ReadEndDocument(); return(profileInfo); } }
/// <summary> /// Serializes an object to a BsonWriter. /// </summary> /// <param name="bsonWriter">The BsonWriter.</param> /// <param name="nominalType">The nominal type.</param> /// <param name="value">The object.</param> /// <param name="options">The serialization options.</param> public override void Serialize( BsonWriter bsonWriter, Type nominalType, object value, IBsonSerializationOptions options) { if (value == null) { throw new ArgumentNullException("value"); } // could get here with a BsonDocumentWrapper from BsonValueSerializer switch statement var wrapper = value as BsonDocumentWrapper; if (wrapper != null) { BsonDocumentWrapperSerializer.Instance.Serialize(bsonWriter, nominalType, value, null); return; } var rawBsonDocument = value as RawBsonDocument; if (rawBsonDocument != null) { RawBsonDocumentSerializer.Instance.Serialize(bsonWriter, nominalType, value, options); return; } var bsonDocument = (BsonDocument)value; var documentSerializationOptions = (options ?? DocumentSerializationOptions.Defaults) as DocumentSerializationOptions; if (documentSerializationOptions == null) { var message = string.Format( "Serialize method of BsonDocument expected serialization options of type {0}, not {1}.", BsonUtils.GetFriendlyTypeName(typeof(DocumentSerializationOptions)), BsonUtils.GetFriendlyTypeName(options.GetType())); throw new BsonSerializationException(message); } bsonWriter.WriteStartDocument(); BsonElement idElement = null; if (documentSerializationOptions.SerializeIdFirst && bsonDocument.TryGetElement("_id", out idElement)) { bsonWriter.WriteName(idElement.Name); BsonValueSerializer.Instance.Serialize(bsonWriter, typeof(BsonValue), idElement.Value, null); } foreach (var element in bsonDocument) { // if serializeIdFirst is false then idElement will be null and no elements will be skipped if (!object.ReferenceEquals(element, idElement)) { bsonWriter.WriteName(element.Name); BsonValueSerializer.Instance.Serialize(bsonWriter, typeof(BsonValue), element.Value, null); } } bsonWriter.WriteEndDocument(); }
/// <summary> /// Serializes an object to a BsonWriter. /// </summary> /// <param name="bsonWriter">The BsonWriter.</param> /// <param name="nominalType">The nominal type.</param> /// <param name="value">The object.</param> /// <param name="options">The serialization options.</param> public override void Serialize( BsonWriter bsonWriter, Type nominalType, object value, IBsonSerializationOptions options) { if (value == null) { bsonWriter.WriteNull(); } else { var profileInfo = (SystemProfileInfo)value; bsonWriter.WriteStartDocument(); bsonWriter.WriteDateTime("ts", BsonUtils.ToMillisecondsSinceEpoch(profileInfo.Timestamp)); if (profileInfo.Info != null) { bsonWriter.WriteString("info", profileInfo.Info); } if (profileInfo.Op != null) { bsonWriter.WriteString("op", profileInfo.Op); } if (profileInfo.Namespace != null) { bsonWriter.WriteString("ns", profileInfo.Namespace); } if (profileInfo.Command != null) { bsonWriter.WriteName("command"); profileInfo.Command.WriteTo(bsonWriter); } if (profileInfo.Query != null) { bsonWriter.WriteName("query"); profileInfo.Query.WriteTo(bsonWriter); } if (profileInfo.UpdateObject != null) { bsonWriter.WriteName("updateobj"); profileInfo.UpdateObject.WriteTo(bsonWriter); } if (profileInfo.CursorId != 0) { bsonWriter.WriteInt64("cursorid", profileInfo.CursorId); } if (profileInfo.NumberToReturn != 0) { bsonWriter.WriteInt32("ntoreturn", profileInfo.NumberToReturn); } if (profileInfo.NumberToSkip != 0) { bsonWriter.WriteInt32("ntoskip", profileInfo.NumberToSkip); } if (profileInfo.Exhaust) { bsonWriter.WriteBoolean("exhaust", profileInfo.Exhaust); } if (profileInfo.NumberScanned != 0) { bsonWriter.WriteInt32("nscanned", profileInfo.NumberScanned); } if (profileInfo.IdHack) { bsonWriter.WriteBoolean("idhack", profileInfo.IdHack); } if (profileInfo.ScanAndOrder) { bsonWriter.WriteBoolean("scanAndOrder", profileInfo.ScanAndOrder); } if (profileInfo.Moved) { bsonWriter.WriteBoolean("moved", profileInfo.Moved); } if (profileInfo.FastMod) { bsonWriter.WriteBoolean("fastmod", profileInfo.FastMod); } if (profileInfo.FastModInsert) { bsonWriter.WriteBoolean("fastmodinsert", profileInfo.FastModInsert); } if (profileInfo.Upsert) { bsonWriter.WriteBoolean("upsert", profileInfo.Upsert); } if (profileInfo.KeyUpdates != 0) { bsonWriter.WriteInt32("keyUpdates", profileInfo.KeyUpdates); } if (profileInfo.Exception != null) { bsonWriter.WriteString("exception", profileInfo.Exception); } if (profileInfo.ExceptionCode != 0) { bsonWriter.WriteInt32("exceptionCode", profileInfo.ExceptionCode); } if (profileInfo.NumberReturned != 0) { bsonWriter.WriteInt32("nreturned", profileInfo.NumberReturned); } if (profileInfo.ResponseLength != 0) { bsonWriter.WriteInt32("responseLength", profileInfo.ResponseLength); } bsonWriter.WriteDouble("millis", profileInfo.Duration.TotalMilliseconds); if (profileInfo.Client != null) { bsonWriter.WriteString("client", profileInfo.Client); } if (profileInfo.User != null) { bsonWriter.WriteString("user", profileInfo.User); } if (profileInfo.Error != null) { bsonWriter.WriteString("err", profileInfo.Error); } if (profileInfo.Abbreviated != null) { bsonWriter.WriteString("abbreviated", profileInfo.Abbreviated); } bsonWriter.WriteEndDocument(); } }
/// <summary> /// Serializes a value. /// </summary> /// <param name="context">The serialization context.</param> /// <param name="args">The serialization args.</param> /// <param name="value">The object.</param> public override void Serialize(BsonSerializationContext context, BsonSerializationArgs args, object value) { var bsonWriter = context.Writer; if (value == null) { bsonWriter.WriteNull(); } else { var actualType = value.GetType(); if (actualType == typeof(object)) { bsonWriter.WriteStartDocument(); bsonWriter.WriteEndDocument(); } else { // certain types can be written directly as BSON value // if we're not at the top level document, or if we're using the JsonWriter if (bsonWriter.State == BsonWriterState.Value || bsonWriter is JsonWriter) { switch (Type.GetTypeCode(actualType)) { case TypeCode.Boolean: bsonWriter.WriteBoolean((bool)value); return; case TypeCode.DateTime: // TODO: is this right? will lose precision after round trip var bsonDateTime = new BsonDateTime(BsonUtils.ToUniversalTime((DateTime)value)); bsonWriter.WriteDateTime(bsonDateTime.MillisecondsSinceEpoch); return; case TypeCode.Double: bsonWriter.WriteDouble((double)value); return; case TypeCode.Int16: // TODO: is this right? will change type to Int32 after round trip bsonWriter.WriteInt32((short)value); return; case TypeCode.Int32: bsonWriter.WriteInt32((int)value); return; case TypeCode.Int64: bsonWriter.WriteInt64((long)value); return; case TypeCode.Object: if (actualType == typeof(Decimal128)) { var decimal128 = (Decimal128)value; bsonWriter.WriteDecimal128(decimal128); return; } if (actualType == typeof(Guid)) { var guid = (Guid)value; var guidRepresentation = bsonWriter.Settings.GuidRepresentation; var binaryData = new BsonBinaryData(guid, guidRepresentation); bsonWriter.WriteBinaryData(binaryData); return; } if (actualType == typeof(ObjectId)) { bsonWriter.WriteObjectId((ObjectId)value); return; } break; case TypeCode.String: bsonWriter.WriteString((string)value); return; } } SerializeDiscriminatedValue(context, args, value, actualType); } } }
private void TranslateOfType(MethodCallExpression methodCallExpression) { var method = methodCallExpression.Method; if (method.DeclaringType != typeof(Queryable)) { var message = string.Format("OfType method of class {0} is not supported.", BsonUtils.GetFriendlyTypeName(method.DeclaringType)); throw new NotSupportedException(message); } if (!method.IsStatic) { throw new NotSupportedException("Expected OfType to be a static method."); } if (!method.IsGenericMethod) { throw new NotSupportedException("Expected OfType to be a generic method."); } var actualType = method.GetGenericArguments()[0]; var args = methodCallExpression.Arguments.ToArray(); if (args.Length != 1) { throw new NotSupportedException("Expected OfType method to have a single argument."); } var sourceExpression = args[0]; var sourceExpressionTypeInfo = sourceExpression.Type.GetTypeInfo(); if (!sourceExpressionTypeInfo.IsGenericType) { throw new NotSupportedException("Expected source argument to OfType to be a generic type."); } var nominalType = sourceExpressionTypeInfo.GetGenericArguments()[0]; if (_projection != null) { throw new NotSupportedException("OfType after a projection is not supported."); } var discriminatorConvention = BsonSerializer.LookupDiscriminatorConvention(nominalType); var discriminator = discriminatorConvention.GetDiscriminator(nominalType, actualType); if (discriminator == null) { return; // nothing to do } if (discriminator.IsBsonArray) { discriminator = discriminator[discriminator.AsBsonArray.Count - 1]; } var query = Query.EQ(discriminatorConvention.ElementName, discriminator); var injectMethodInfo = typeof(LinqToMongo).GetMethod("Inject"); var body = Expression.Call(injectMethodInfo, Expression.Constant(query)); var parameter = Expression.Parameter(nominalType, "x"); var predicate = Expression.Lambda(body, parameter); CombinePredicateWithWhereClause(methodCallExpression, predicate); _ofType = actualType; }
// public methods /// <summary> /// Deserializes a value. /// </summary> /// <param name="context">The deserialization context.</param> /// <returns>An object.</returns> public override DateTime Deserialize(BsonDeserializationContext context) { var bsonReader = context.Reader; DateTime value; var bsonType = bsonReader.GetCurrentBsonType(); switch (bsonType) { case BsonType.DateTime: // use an intermediate BsonDateTime so MinValue and MaxValue are handled correctly value = new BsonDateTime(bsonReader.ReadDateTime()).ToUniversalTime(); break; case BsonType.Document: value = default(DateTime); _helper.DeserializeMembers(context, (elementName, flag) => { switch (flag) { case Flags.DateTime: bsonReader.SkipValue(); break; // ignore value (use Ticks instead) case Flags.Ticks: value = new DateTime(context.DeserializeWithChildContext(_int64Serializer), DateTimeKind.Utc); break; } }); break; case BsonType.Int64: value = DateTime.SpecifyKind(new DateTime(bsonReader.ReadInt64()), DateTimeKind.Utc); break; case BsonType.String: if (_dateOnly) { value = DateTime.SpecifyKind(DateTime.ParseExact(bsonReader.ReadString(), "yyyy-MM-dd", null), DateTimeKind.Utc); } else { value = JsonConvert.ToDateTime(bsonReader.ReadString()); } break; default: throw CreateCannotDeserializeFromBsonTypeException(bsonType); } if (_dateOnly) { if (value.TimeOfDay != TimeSpan.Zero) { throw new FormatException("TimeOfDay component for DateOnly DateTime value is not zero."); } value = DateTime.SpecifyKind(value, _kind); // not ToLocalTime or ToUniversalTime! } else { switch (_kind) { case DateTimeKind.Local: case DateTimeKind.Unspecified: value = DateTime.SpecifyKind(BsonUtils.ToLocalTime(value), _kind); break; case DateTimeKind.Utc: value = BsonUtils.ToUniversalTime(value); break; } } return(value); }
/// <summary> /// Uploads a GridFS file. /// </summary> /// <param name="stream">The source stream.</param> /// <param name="remoteFileName">The remote file name.</param> /// <param name="createOptions">The create options.</param> /// <returns>The file info of the new GridFS file.</returns> public MongoGridFSFileInfo Upload( Stream stream, string remoteFileName, MongoGridFSCreateOptions createOptions) { if (_settings.ReadPreference != ReadPreference.Primary) { var gridFS = WithReadPreferencePrimary(); return(gridFS.Upload(stream, remoteFileName, createOptions)); } using (_server.RequestStart(ReadPreference.Primary)) { var connectionId = _server.RequestConnectionId; EnsureIndexes(); var database = GetDatabase(ReadPreference.Primary); var chunksCollection = GetChunksCollection(database); var filesCollection = GetFilesCollection(database); var files_id = createOptions.Id ?? ObjectId.GenerateNewId(); var chunkSize = (createOptions.ChunkSize == 0) ? _settings.ChunkSize : createOptions.ChunkSize; var buffer = new byte[chunkSize]; var length = 0L; string md5Client = null; using (var md5Algorithm = _settings.VerifyMD5 ? MD5.Create() : null) { for (var n = 0L; true; n++) { // might have to call Stream.Read several times to get a whole chunk var bytesNeeded = chunkSize; var bytesRead = 0; while (bytesNeeded > 0) { var partialRead = stream.Read(buffer, bytesRead, bytesNeeded); if (partialRead == 0) { break; // EOF may or may not have a partial chunk } bytesNeeded -= partialRead; bytesRead += partialRead; } if (bytesRead == 0) { break; // EOF no partial chunk } length += bytesRead; byte[] data = buffer; if (bytesRead < chunkSize) { data = new byte[bytesRead]; Buffer.BlockCopy(buffer, 0, data, 0, bytesRead); } var chunk = new BsonDocument { { "_id", ObjectId.GenerateNewId() }, { "files_id", files_id }, { "n", n < int.MaxValue ? (BsonValue)(BsonInt32)(int)n : (BsonInt64)n }, { "data", new BsonBinaryData(data) } }; chunksCollection.Insert(chunk, _settings.WriteConcern); if (_settings.VerifyMD5) { md5Algorithm.TransformBlock(data, 0, data.Length, null, 0); } if (bytesRead < chunkSize) { break; // EOF after partial chunk } } if (_settings.VerifyMD5) { md5Algorithm.TransformFinalBlock(new byte[0], 0, 0); md5Client = BsonUtils.ToHexString(md5Algorithm.Hash); } } string md5Server = null; if (_settings.UpdateMD5 || _settings.VerifyMD5) { var md5Command = new CommandDocument { { "filemd5", files_id }, { "root", _settings.Root } }; var md5Result = database.RunCommand(md5Command); md5Server = md5Result.Response["md5"].AsString; } if (_settings.VerifyMD5 && !md5Client.Equals(md5Server, StringComparison.OrdinalIgnoreCase)) { throw new MongoGridFSException(connectionId, "Upload client and server MD5 hashes are not equal."); } var uploadDate = (createOptions.UploadDate == DateTime.MinValue) ? DateTime.UtcNow : createOptions.UploadDate; var aliases = (createOptions.Aliases != null) ? new BsonArray(createOptions.Aliases) : null; BsonDocument fileInfo = new BsonDocument { { "_id", files_id }, { "filename", remoteFileName, !string.IsNullOrEmpty(remoteFileName) }, // optional { "length", length }, { "chunkSize", chunkSize }, { "uploadDate", uploadDate }, { "md5", (md5Server == null) ? (BsonValue)BsonNull.Value : new BsonString(md5Server) }, { "contentType", createOptions.ContentType, !string.IsNullOrEmpty(createOptions.ContentType) }, // optional { "aliases", aliases, aliases != null }, // optional { "metadata", createOptions.Metadata, createOptions.Metadata != null } // optional }; filesCollection.Insert(fileInfo, _settings.WriteConcern); return(FindOneById(files_id)); } }
/// <summary> /// Serializes a value. /// </summary> /// <param name="context">The serialization context.</param> /// <param name="value">The object.</param> public override void Serialize(BsonSerializationContext context, DateTime value) { var bsonWriter = context.Writer; DateTime utcDateTime; if (_dateOnly) { if (value.TimeOfDay != TimeSpan.Zero) { throw new BsonSerializationException("TimeOfDay component is not zero."); } utcDateTime = DateTime.SpecifyKind(value, DateTimeKind.Utc); // not ToLocalTime } else { utcDateTime = BsonUtils.ToUniversalTime(value); } var millisecondsSinceEpoch = BsonUtils.ToMillisecondsSinceEpoch(utcDateTime); switch (_representation) { case BsonType.DateTime: bsonWriter.WriteDateTime(millisecondsSinceEpoch); break; case BsonType.Document: bsonWriter.WriteStartDocument(); bsonWriter.WriteDateTime("DateTime", millisecondsSinceEpoch); bsonWriter.WriteInt64("Ticks", utcDateTime.Ticks); bsonWriter.WriteEndDocument(); break; case BsonType.Int64: bsonWriter.WriteInt64(utcDateTime.Ticks); break; case BsonType.String: if (_dateOnly) { bsonWriter.WriteString(value.ToString("yyyy-MM-dd")); } else { if (value == DateTime.MinValue || value == DateTime.MaxValue) { // serialize MinValue and MaxValue as Unspecified so we do NOT get the time zone offset value = DateTime.SpecifyKind(value, DateTimeKind.Unspecified); } else if (value.Kind == DateTimeKind.Unspecified) { // serialize Unspecified as Local se we get the time zone offset value = DateTime.SpecifyKind(value, DateTimeKind.Local); } bsonWriter.WriteString(JsonConvert.ToString(value)); } break; default: var message = string.Format("'{0}' is not a valid DateTime representation.", _representation); throw new BsonSerializationException(message); } }
public void TestParseHexStringNull() { var actual = BsonUtils.ParseHexString(null); }
// public methods /// <summary> /// Deserializes an object from a BsonReader. /// </summary> /// <param name="bsonReader">The BsonReader.</param> /// <param name="nominalType">The nominal type of the object.</param> /// <param name="actualType">The actual type of the object.</param> /// <param name="options">The serialization options.</param> /// <returns>An object.</returns> public override object Deserialize( BsonReader bsonReader, Type nominalType, Type actualType, IBsonSerializationOptions options) { VerifyTypes(nominalType, actualType, typeof(DateTime)); var dateTimeSerializationOptions = EnsureSerializationOptions <DateTimeSerializationOptions>(options); var bsonType = bsonReader.GetCurrentBsonType(); DateTime value; switch (bsonType) { case BsonType.DateTime: // use an intermediate BsonDateTime so MinValue and MaxValue are handled correctly value = BsonDateTime.Create(bsonReader.ReadDateTime()).Value; break; case BsonType.Document: bsonReader.ReadStartDocument(); bsonReader.ReadDateTime("DateTime"); // ignore value (use Ticks instead) value = new DateTime(bsonReader.ReadInt64("Ticks"), DateTimeKind.Utc); bsonReader.ReadEndDocument(); break; case BsonType.Int64: value = DateTime.SpecifyKind(new DateTime(bsonReader.ReadInt64()), DateTimeKind.Utc); break; case BsonType.String: // note: we're not using XmlConvert because of bugs in Mono if (dateTimeSerializationOptions.DateOnly) { value = DateTime.SpecifyKind(DateTime.ParseExact(bsonReader.ReadString(), "yyyy-MM-dd", null), DateTimeKind.Utc); } else { var formats = new string[] { "yyyy-MM-ddK", "yyyy-MM-ddTHH:mm:ssK", "yyyy-MM-ddTHH:mm:ss.FFFFFFFK" }; value = DateTime.ParseExact(bsonReader.ReadString(), formats, null, DateTimeStyles.AdjustToUniversal | DateTimeStyles.AssumeUniversal); } break; default: var message = string.Format("Cannot deserialize DateTime from BsonType {0}.", bsonType); throw new FileFormatException(message); } if (dateTimeSerializationOptions.DateOnly) { if (value.TimeOfDay != TimeSpan.Zero) { throw new FileFormatException("TimeOfDay component for DateOnly DateTime value is not zero."); } value = DateTime.SpecifyKind(value, dateTimeSerializationOptions.Kind); // not ToLocalTime or ToUniversalTime! } else { switch (dateTimeSerializationOptions.Kind) { case DateTimeKind.Local: case DateTimeKind.Unspecified: value = DateTime.SpecifyKind(BsonUtils.ToLocalTime(value), dateTimeSerializationOptions.Kind); break; case DateTimeKind.Utc: value = BsonUtils.ToUniversalTime(value); break; } } return(value); }
public void TestGreaterThanMaxToDateTimeConversion() { var actual = BsonUtils.ToDateTimeFromMillisecondsSinceEpoch( BsonConstants.DateTimeMaxValueMillisecondsSinceEpoch + 1); }
/// <summary> /// Serializes an object to a BsonWriter. /// </summary> /// <param name="bsonWriter">The BsonWriter.</param> /// <param name="nominalType">The nominal type.</param> /// <param name="value">The object.</param> /// <param name="options">The serialization options.</param> public override void Serialize( BsonWriter bsonWriter, Type nominalType, object value, IBsonSerializationOptions options) { var dateTime = (DateTime)value; var dateTimeSerializationOptions = EnsureSerializationOptions <DateTimeSerializationOptions>(options); DateTime utcDateTime; if (dateTimeSerializationOptions.DateOnly) { if (dateTime.TimeOfDay != TimeSpan.Zero) { throw new BsonSerializationException("TimeOfDay component is not zero."); } utcDateTime = DateTime.SpecifyKind(dateTime, DateTimeKind.Utc); // not ToLocalTime } else { utcDateTime = BsonUtils.ToUniversalTime(dateTime); } var millisecondsSinceEpoch = BsonUtils.ToMillisecondsSinceEpoch(utcDateTime); switch (dateTimeSerializationOptions.Representation) { case BsonType.DateTime: bsonWriter.WriteDateTime(millisecondsSinceEpoch); break; case BsonType.Document: bsonWriter.WriteStartDocument(); bsonWriter.WriteDateTime("DateTime", millisecondsSinceEpoch); bsonWriter.WriteInt64("Ticks", utcDateTime.Ticks); bsonWriter.WriteEndDocument(); break; case BsonType.Int64: bsonWriter.WriteInt64(utcDateTime.Ticks); break; case BsonType.String: if (dateTimeSerializationOptions.DateOnly) { bsonWriter.WriteString(dateTime.ToString("yyyy-MM-dd")); } else { // we're not using XmlConvert.ToString because of bugs in Mono if (dateTime == DateTime.MinValue || dateTime == DateTime.MaxValue) { // serialize MinValue and MaxValue as Unspecified so we do NOT get the time zone offset dateTime = DateTime.SpecifyKind(dateTime, DateTimeKind.Unspecified); } else if (dateTime.Kind == DateTimeKind.Unspecified) { // serialize Unspecified as Local se we get the time zone offset dateTime = DateTime.SpecifyKind(dateTime, DateTimeKind.Local); } bsonWriter.WriteString(dateTime.ToString("yyyy-MM-ddTHH:mm:ss.FFFFFFFK")); } break; default: var message = string.Format("'{0}' is not a valid DateTime representation.", dateTimeSerializationOptions.Representation); throw new BsonSerializationException(message); } }
public void TestMinToMillisConversion() { var actual = BsonUtils.ToMillisecondsSinceEpoch(DateTime.MinValue); Assert.AreEqual(BsonConstants.DateTimeMinValueMillisecondsSinceEpoch, actual); }
/// <summary> /// Serializes an object to a BsonWriter. /// </summary> /// <param name="bsonWriter">The BsonWriter.</param> /// <param name="nominalType">The nominal type.</param> /// <param name="value">The object.</param> /// <param name="options">The serialization options.</param> public override void Serialize( BsonWriter bsonWriter, Type nominalType, object value, IBsonSerializationOptions options) { if (value == null) { bsonWriter.WriteNull(); } else { if (nominalType == typeof(object)) { var actualType = value.GetType(); bsonWriter.WriteStartDocument(); bsonWriter.WriteString("_t", TypeNameDiscriminator.GetDiscriminator(actualType)); bsonWriter.WriteName("_v"); Serialize(bsonWriter, actualType, value, options); // recursive call replacing nominalType with actualType bsonWriter.WriteEndDocument(); return; } // support RepresentationSerializationOptions for backward compatibility var representationSerializationOptions = options as RepresentationSerializationOptions; if (representationSerializationOptions != null) { switch (representationSerializationOptions.Representation) { case BsonType.Array: options = DictionarySerializationOptions.ArrayOfArrays; break; case BsonType.Document: options = DictionarySerializationOptions.Document; break; default: var message = string.Format("BsonType {0} is not a valid representation for a Dictionary.", representationSerializationOptions.Representation); throw new BsonSerializationException(message); } } var dictionary = (IDictionary <TKey, TValue>)value; var dictionarySerializationOptions = EnsureSerializationOptions <DictionarySerializationOptions>(options); var representation = dictionarySerializationOptions.Representation; var itemSerializationOptions = dictionarySerializationOptions.ItemSerializationOptions; if (representation == DictionaryRepresentation.Dynamic) { if (typeof(TKey) == typeof(string) || typeof(TKey) == typeof(object)) { representation = DictionaryRepresentation.Document; foreach (object key in dictionary.Keys) { var name = key as string; // check for null and type string at the same time if (name == null || name[0] == '$' || name.IndexOf('.') != -1) { representation = DictionaryRepresentation.ArrayOfArrays; break; } } } else { representation = DictionaryRepresentation.ArrayOfArrays; } } switch (representation) { case DictionaryRepresentation.Document: bsonWriter.WriteStartDocument(); foreach (KeyValuePair <TKey, TValue> entry in dictionary) { bsonWriter.WriteName((string)(object)entry.Key); BsonSerializer.Serialize(bsonWriter, typeof(TValue), entry.Value, itemSerializationOptions); } bsonWriter.WriteEndDocument(); break; case DictionaryRepresentation.ArrayOfArrays: bsonWriter.WriteStartArray(); foreach (KeyValuePair <TKey, TValue> entry in dictionary) { bsonWriter.WriteStartArray(); BsonSerializer.Serialize(bsonWriter, typeof(TKey), entry.Key); BsonSerializer.Serialize(bsonWriter, typeof(TValue), entry.Value, itemSerializationOptions); bsonWriter.WriteEndArray(); } bsonWriter.WriteEndArray(); break; case DictionaryRepresentation.ArrayOfDocuments: bsonWriter.WriteStartArray(); foreach (KeyValuePair <TKey, TValue> entry in dictionary) { bsonWriter.WriteStartDocument(); bsonWriter.WriteName("k"); BsonSerializer.Serialize(bsonWriter, typeof(TKey), entry.Key); bsonWriter.WriteName("v"); BsonSerializer.Serialize(bsonWriter, typeof(TValue), entry.Value, itemSerializationOptions); bsonWriter.WriteEndDocument(); } bsonWriter.WriteEndArray(); break; default: var message = string.Format( "'{0}' is not a valid {1} representation.", representation, BsonUtils.GetFriendlyTypeName(typeof(IDictionary <TKey, TValue>))); throw new BsonSerializationException(message); } } }
/// <summary> /// Writes BSON binary data to the writer. /// </summary> /// <param name="bytes">The binary data.</param> /// <param name="subType">The binary data subtype.</param> /// <param name="guidRepresentation">The representation for Guids.</param> public override void WriteBinaryData( byte[] bytes, BsonBinarySubType subType, GuidRepresentation guidRepresentation) { if (Disposed) { throw new ObjectDisposedException("JsonWriter"); } if (State != BsonWriterState.Value && State != BsonWriterState.Initial) { ThrowInvalidState("WriteBinaryData", BsonWriterState.Value, BsonWriterState.Initial); } if (_jsonWriterSettings.OutputMode == JsonOutputMode.Shell) { WriteNameHelper(Name); switch (subType) { case BsonBinarySubType.UuidLegacy: case BsonBinarySubType.UuidStandard: if (bytes.Length != 16) { var message = string.Format("Length of binary subtype {0} must be 16, not {1}.", subType, bytes.Length); throw new ArgumentException(message); } if (subType == BsonBinarySubType.UuidLegacy && guidRepresentation == GuidRepresentation.Standard) { throw new ArgumentException("GuidRepresentation for binary subtype UuidLegacy must not be Standard."); } if (subType == BsonBinarySubType.UuidStandard && guidRepresentation != GuidRepresentation.Standard) { var message = string.Format("GuidRepresentation for binary subtype UuidStandard must be Standard, not {0}.", guidRepresentation); throw new ArgumentException(message); } if (_jsonWriterSettings.ShellVersion >= new Version(2, 0, 0)) { if (guidRepresentation == GuidRepresentation.Unspecified) { var s = BsonUtils.ToHexString(bytes); var parts = new string[] { s.Substring(0, 8), s.Substring(8, 4), s.Substring(12, 4), s.Substring(16, 4), s.Substring(20, 12) }; _textWriter.Write("HexData({0}, \"{1}\")", (int)subType, string.Join("-", parts)); } else { string uuidConstructorName; switch (guidRepresentation) { case GuidRepresentation.CSharpLegacy: uuidConstructorName = "CSUUID"; break; case GuidRepresentation.JavaLegacy: uuidConstructorName = "JUUID"; break; case GuidRepresentation.PythonLegacy: uuidConstructorName = "PYUUID"; break; case GuidRepresentation.Standard: uuidConstructorName = "UUID"; break; default: throw new BsonInternalException("Unexpected GuidRepresentation"); } var guid = GuidConverter.FromBytes(bytes, guidRepresentation); _textWriter.Write("{0}(\"{1}\")", uuidConstructorName, guid.ToString()); } } else { _textWriter.Write("new BinData({0}, \"{1}\")", (int)subType, Convert.ToBase64String(bytes)); } break; default: _textWriter.Write("new BinData({0}, \"{1}\")", (int)subType, Convert.ToBase64String(bytes)); break; } } else { WriteStartDocument(); WriteString("$binary", Convert.ToBase64String(bytes)); WriteString("$type", ((int)subType).ToString("x2")); WriteEndDocument(); } State = GetNextState(); }
public void ReadJson_should_return_expected_result_when_using_wrapped_bson_reader(string json, GuidRepresentation guidRepresentation, string nullableHexBytes, BsonBinarySubType subType) { var subject = new BsonBinaryDataConverter(); var expectedResult = nullableHexBytes == null ? null : new BsonBinaryData(BsonUtils.ParseHexString(nullableHexBytes), subType); var result = ReadJsonUsingWrappedBsonReader <BsonBinaryData>(subject, ToBson(json, guidRepresentation), mustBeNested: true, guidRepresentation: guidRepresentation); result.Should().Be(expectedResult); }