/// <summary> /// Serializes an object to a binary destination. /// </summary> /// <param name="Writer">Serializer.</param> /// <param name="WriteTypeCode">If a type code is to be output.</param> /// <param name="Embedded">If the object is embedded into another.</param> /// <param name="Value">The actual object to serialize.</param> public override async Task Serialize(ISerializer Writer, bool WriteTypeCode, bool Embedded, object Value) { if (Value is null) { if (!WriteTypeCode) { throw new NullReferenceException("Value cannot be null."); } Writer.WriteBits(ObjectSerializer.TYPE_NULL, 6); } else { T[] Array = (T[])Value; Type LastType = typeof(T); IObjectSerializer S = await this.context.GetObjectSerializer(LastType); Type ItemType; bool Nullable; Writer.WriteBits(ObjectSerializer.TYPE_ARRAY, 6); Writer.WriteVariableLengthUInt64((ulong)Array.Length); if (Nullable = S.IsNullable) { Writer.WriteBits(ObjectSerializer.TYPE_NULL, 6); } else { Writer.WriteBits(ObjectSerializer.GetFieldDataTypeCode(LastType), 6); } foreach (T Item in Array) { if (Item == null) { if (Nullable) { Writer.WriteBits(ObjectSerializer.TYPE_NULL, 6); } else { throw new Exception("Elements cannot be null."); } } else { ItemType = Item.GetType(); if (ItemType != LastType) { S = await this.context.GetObjectSerializer(ItemType); LastType = ItemType; } await S.Serialize(Writer, Nullable, true, Item); } } } }
internal static string ToString(object Value) { if (Value is null) { return(string.Empty); } else { return(ToString(Value, ObjectSerializer.GetFieldDataTypeCode(Value.GetType()))); } }
/// <summary> /// Tries to make sure <paramref name="x"/> and <paramref name="y"/> have the same type. /// </summary> /// <param name="x">First value.</param> /// <param name="y">Second value.</param> /// <returns>If <paramref name="x"/> and <paramref name="y"/> are of the same type after the call.</returns> public static bool TryMakeSameType(ref object x, ref object y) { Type xType = x.GetType(); Type yType = y.GetType(); if (xType == yType) { return(true); } uint xTypeCode = ObjectSerializer.GetFieldDataTypeCode(xType); uint yTypeCode = ObjectSerializer.GetFieldDataTypeCode(yType); Upgrade(ref x, ref xTypeCode); Upgrade(ref y, ref yTypeCode); if (xTypeCode == yTypeCode) { return(true); } if (xTypeCode == ObjectSerializer.TYPE_CI_STRING) { y = new CaseInsensitiveString(ToString(y, yTypeCode)); return(true); } else if (yTypeCode == ObjectSerializer.TYPE_CI_STRING) { x = new CaseInsensitiveString(ToString(x, xTypeCode)); return(true); } else if (yTypeCode == ObjectSerializer.TYPE_STRING) { x = ToString(x, xTypeCode); return(true); } switch (xTypeCode) { case ObjectSerializer.TYPE_DECIMAL: if (yTypeCode == ObjectSerializer.TYPE_DOUBLE) { y = (decimal)((double)y); return(true); } else { return(false); } case ObjectSerializer.TYPE_DOUBLE: if (yTypeCode == ObjectSerializer.TYPE_DECIMAL) { x = (decimal)((double)x); return(true); } else { return(false); } case ObjectSerializer.TYPE_STRING: y = ToString(y, yTypeCode); return(true); default: return(false); } }
/// <summary> /// Class member. /// </summary> /// <param name="Name">Member name.</param> /// <param name="FieldCode">Field Code.</param> /// <param name="MemberType">Member type.</param> public Member(string Name, ulong FieldCode, Type MemberType) { this.name = Name; this.fieldCode = FieldCode; this.memberType = MemberType; this.memberTypeInfo = MemberType.GetTypeInfo(); if (this.memberTypeInfo.IsGenericType) { Type GT = this.memberType.GetGenericTypeDefinition(); if (GT == typeof(Nullable <>)) { this.nullable = true; this.memberType = this.memberType.GenericTypeArguments[0]; this.memberTypeInfo = this.memberType.GetTypeInfo(); } } this.memberFieldDataTypeCode = ObjectSerializer.GetFieldDataTypeCode(this.memberType); this.isNestedObject = this.memberFieldDataTypeCode == ObjectSerializer.TYPE_OBJECT; switch (this.memberFieldDataTypeCode) { case ObjectSerializer.TYPE_BOOLEAN: this.memberTypeCode = TypeCode.Boolean; break; case ObjectSerializer.TYPE_BYTE: this.memberTypeCode = TypeCode.Byte; break; case ObjectSerializer.TYPE_INT16: this.memberTypeCode = TypeCode.Int16; break; case ObjectSerializer.TYPE_INT32: this.memberTypeCode = TypeCode.Int32; if (this.memberTypeInfo.IsEnum) { this.isEnum = true; this.hasFlags = true; } break; case ObjectSerializer.TYPE_INT64: this.memberTypeCode = TypeCode.Int64; break; case ObjectSerializer.TYPE_SBYTE: this.memberTypeCode = TypeCode.SByte; break; case ObjectSerializer.TYPE_UINT16: this.memberTypeCode = TypeCode.UInt16; break; case ObjectSerializer.TYPE_UINT32: this.memberTypeCode = TypeCode.UInt32; break; case ObjectSerializer.TYPE_UINT64: this.memberTypeCode = TypeCode.UInt64; break; case ObjectSerializer.TYPE_DECIMAL: this.memberTypeCode = TypeCode.Decimal; break; case ObjectSerializer.TYPE_DOUBLE: this.memberTypeCode = TypeCode.Double; break; case ObjectSerializer.TYPE_SINGLE: this.memberTypeCode = TypeCode.Single; break; case ObjectSerializer.TYPE_DATETIME: this.memberTypeCode = TypeCode.DateTime; break; case ObjectSerializer.TYPE_CHAR: this.memberTypeCode = TypeCode.Char; break; case ObjectSerializer.TYPE_STRING: this.memberTypeCode = TypeCode.String; break; case ObjectSerializer.TYPE_MIN: case ObjectSerializer.TYPE_MAX: case ObjectSerializer.TYPE_NULL: this.memberTypeCode = TypeCode.Empty; break; case ObjectSerializer.TYPE_ENUM: this.memberTypeCode = TypeCode.Object; this.isEnum = true; this.hasFlags = this.memberTypeInfo.IsDefined(typeof(FlagsAttribute), false); break; case ObjectSerializer.TYPE_OBJECT: case ObjectSerializer.TYPE_TIMESPAN: case ObjectSerializer.TYPE_BYTEARRAY: case ObjectSerializer.TYPE_GUID: case ObjectSerializer.TYPE_ARRAY: case ObjectSerializer.TYPE_DATETIMEOFFSET: case ObjectSerializer.TYPE_CI_STRING: default: this.memberTypeCode = TypeCode.Object; break; } }