private static int GetByteSize(FieldInfo fieldInfo, FieldTypeId id, SerializationHintsAttribute attribute)
        {
            if (attribute != null && attribute.BitPacked > 0)
            {
                switch (id)
                {
                case FieldTypeId.Class:
                case FieldTypeId.Double:
                case FieldTypeId.Single:
                case FieldTypeId.Struct:
                case FieldTypeId.String:
                    throw new NotSupportedException("Cannot specify BitPacket hint for this field.");
                }
                if ((attribute.BitPacked % 8) != 0)
                {
                    throw new NotSupportedException("Number of bits in BitPacked must be dividable by 8 to get complecte bytes.");
                }
                return(attribute.BitPacked / 8);
            }
            if (id == FieldTypeId.Enum)
            {
                Type underlayingType = Enum.GetUnderlyingType(fieldInfo.FieldType);
                switch (Type.GetTypeCode(underlayingType))
                {
                case TypeCode.Byte:
                case TypeCode.SByte:
                    return(1);

                case TypeCode.Int16:
                case TypeCode.UInt16:
                    return(2);

                case TypeCode.Int32:
                case TypeCode.UInt32:
                    return(4);

                case TypeCode.Int64:
                case TypeCode.UInt64:
                    return(8);
                }
            }
            return(byteSizes[(int)id]);
        }
示例#2
0
 private static FieldTypeId GetFieldTypeId(FieldInfo fieldInfo, SerializationHintsAttribute attribute)
 {
     Type type = fieldInfo.FieldType;
     if (type.IsPrimitive)
     {
         switch (Type.GetTypeCode(type))
         {
             case TypeCode.Boolean:
                 if (attribute != null && attribute.RangeBias != 0)
                     throw new NotSupportedException("RangeBias not allowed for fields of type bool.");
                 if (attribute != null && attribute.Scale != 0)
                     throw new NotSupportedException("Scale not allowed for fields of type bool.");
                 return FieldTypeId.Boolean;
             case TypeCode.Byte:
                 return FieldTypeId.Byte;
             case TypeCode.SByte:
                 return FieldTypeId.SByte;
             case TypeCode.Char:
                 return FieldTypeId.Char;
             case TypeCode.UInt16:
                 return FieldTypeId.UInt16;
             case TypeCode.Int16:
                 return FieldTypeId.Int32;
             case TypeCode.UInt32:
                 return FieldTypeId.UInt32;
             case TypeCode.Int32:
                 return FieldTypeId.Int32;
             case TypeCode.UInt64:
                 return FieldTypeId.UInt64;
             case TypeCode.Int64:
                 return FieldTypeId.Int64;
             case TypeCode.Single:
                 return FieldTypeId.Single;
             case TypeCode.Double:
                 return FieldTypeId.Double;
             default:
                 throw new NotSupportedException("Unsupported primitive.");
         }
     }
     switch (Type.GetTypeCode(type))
     {
         case TypeCode.String:
             return FieldTypeId.String;
         case TypeCode.DateTime:
             return FieldTypeId.DateTime;
         default:
             if (type == typeof(TimeSpan))
                 return FieldTypeId.TimeSpan;
             if (type.IsEnum)
                 return FieldTypeId.Enum;
             if (type.IsValueType)
             {
                 if ((type.Attributes & ~TypeAttributes.Serializable) != 0)
                     return FieldTypeId.Struct;
                 else
                     return FieldTypeId.NonSerializableFieldType;
             }
             if (type.IsInterface)
                 throw new NotSupportedException("Fields that are interfaces are not possible to serialize.");
             if (type.IsClass)
             {
                 if (type.IsArray)
                     throw new NotSupportedException("Fields that are arrays are not supported.");
                 if ((type.Attributes & ~TypeAttributes.Serializable) != 0)
                 {
                     if (type == typeof(Type))
                         throw new NotSupportedException("Fields of type Type not possible to serialize.");
                     if (type.IsAbstract)
                         throw new NotSupportedException("Fields that are of abstract types are not possible to serialize.");
                     if (!type.IsSealed && (attribute == null || (attribute.Flags & SerializationFlags.FixedType) == 0))
                         throw new NotSupportedException("Fields that are classes must be of a sealed class or must be marked as fixed type with the SerializationHintsAttribute.Flags.");
                     if(attribute == null || (attribute.Flags & SerializationFlags.PointerNeverNull) == 0)
                         throw new NotSupportedException("Fields that are classes cannot be null and must be marked with SerializationFlags.PointerNeverNull.");
                     return FieldTypeId.Class;
                 }
                 return FieldTypeId.NonSerializableFieldType;
             }
             throw new NotSupportedException("Unsupported field type.");
     }
 }
示例#3
0
 private static int GetByteSize(FieldInfo fieldInfo, FieldTypeId id, SerializationHintsAttribute attribute)
 {
     if (attribute != null && attribute.BitPacked > 0)
     {
         switch (id)
         {
             case FieldTypeId.Class:
             case FieldTypeId.Double:
             case FieldTypeId.Single:
             case FieldTypeId.Struct:
             case FieldTypeId.String:
                 throw new NotSupportedException("Cannot specify BitPacket hint for this field.");
         }
         if ((attribute.BitPacked % 8) != 0)
             throw new NotSupportedException("Number of bits in BitPacked must be dividable by 8 to get complecte bytes.");
         return attribute.BitPacked / 8;
     }
     if (id == FieldTypeId.Enum)
     {
         Type underlayingType = Enum.GetUnderlyingType(fieldInfo.FieldType);
         switch (Type.GetTypeCode(underlayingType))
         {
             case TypeCode.Byte:
             case TypeCode.SByte:
                 return 1;
             case TypeCode.Int16:
             case TypeCode.UInt16:
                 return 2;
             case TypeCode.Int32:
             case TypeCode.UInt32:
                 return 4;
             case TypeCode.Int64:
             case TypeCode.UInt64:
                 return 8;
         }
     }
     return byteSizes[(int)id];
 }
        private static FieldTypeId GetFieldTypeId(FieldInfo fieldInfo, SerializationHintsAttribute attribute)
        {
            Type type = fieldInfo.FieldType;

            if (type.IsPrimitive)
            {
                switch (Type.GetTypeCode(type))
                {
                case TypeCode.Boolean:
                    if (attribute != null && attribute.RangeBias != 0)
                    {
                        throw new NotSupportedException("RangeBias not allowed for fields of type bool.");
                    }
                    if (attribute != null && attribute.Scale != 0)
                    {
                        throw new NotSupportedException("Scale not allowed for fields of type bool.");
                    }
                    return(FieldTypeId.Boolean);

                case TypeCode.Byte:
                    return(FieldTypeId.Byte);

                case TypeCode.SByte:
                    return(FieldTypeId.SByte);

                case TypeCode.Char:
                    return(FieldTypeId.Char);

                case TypeCode.UInt16:
                    return(FieldTypeId.UInt16);

                case TypeCode.Int16:
                    return(FieldTypeId.Int32);

                case TypeCode.UInt32:
                    return(FieldTypeId.UInt32);

                case TypeCode.Int32:
                    return(FieldTypeId.Int32);

                case TypeCode.UInt64:
                    return(FieldTypeId.UInt64);

                case TypeCode.Int64:
                    return(FieldTypeId.Int64);

                case TypeCode.Single:
                    return(FieldTypeId.Single);

                case TypeCode.Double:
                    return(FieldTypeId.Double);

                default:
                    throw new NotSupportedException("Unsupported primitive.");
                }
            }
            switch (Type.GetTypeCode(type))
            {
            case TypeCode.String:
                return(FieldTypeId.String);

            case TypeCode.DateTime:
                return(FieldTypeId.DateTime);

            default:
                if (type == typeof(TimeSpan))
                {
                    return(FieldTypeId.TimeSpan);
                }
                if (type.IsEnum)
                {
                    return(FieldTypeId.Enum);
                }
                if (type.IsValueType)
                {
                    if ((type.Attributes & ~TypeAttributes.Serializable) != 0)
                    {
                        return(FieldTypeId.Struct);
                    }
                    else
                    {
                        return(FieldTypeId.NonSerializableFieldType);
                    }
                }
                if (type.IsInterface)
                {
                    throw new NotSupportedException("Fields that are interfaces are not possible to serialize.");
                }
                if (type.IsClass)
                {
                    if (type.IsArray)
                    {
                        throw new NotSupportedException("Fields that are arrays are not supported.");
                    }
                    if ((type.Attributes & ~TypeAttributes.Serializable) != 0)
                    {
                        if (type == typeof(Type))
                        {
                            throw new NotSupportedException("Fields of type Type not possible to serialize.");
                        }
                        if (type.IsAbstract)
                        {
                            throw new NotSupportedException("Fields that are of abstract types are not possible to serialize.");
                        }
                        if (!type.IsSealed && (attribute == null || (attribute.Flags & SerializationFlags.FixedType) == 0))
                        {
                            throw new NotSupportedException("Fields that are classes must be of a sealed class or must be marked as fixed type with the SerializationHintsAttribute.Flags.");
                        }
                        if (attribute == null || (attribute.Flags & SerializationFlags.PointerNeverNull) == 0)
                        {
                            throw new NotSupportedException("Fields that are classes cannot be null and must be marked with SerializationFlags.PointerNeverNull.");
                        }
                        return(FieldTypeId.Class);
                    }
                    return(FieldTypeId.NonSerializableFieldType);
                }
                throw new NotSupportedException("Unsupported field type.");
            }
        }
        private static void DeSerializeField(MemoryStream stream, object obj, FieldInfo fieldInfo)
        {
            SerializationHintsAttribute attribute = GetSerializationHintsAttribute(fieldInfo);
            FieldTypeId id = GetFieldTypeId(fieldInfo, attribute);

            if (id == FieldTypeId.NonSerializableFieldType)
            {
                return;
            }
            int   byteCount = GetByteSize(fieldInfo, id, attribute);
            ulong binValue;

            if (id != FieldTypeId.String && id != FieldTypeId.Class && id != FieldTypeId.Struct)
            {
                binValue = ReadUnsignedLong(stream, byteCount);
            }
            else
            {
                binValue = 0;
            }
            object value = null;

            switch (id)
            {
            case FieldTypeId.Boolean:
                value = binValue != 0;
                break;

            case FieldTypeId.Byte:
                value = (byte)binValue;
                break;

            case FieldTypeId.SByte:
                value = (sbyte)binValue;
                break;

            case FieldTypeId.Char:
                value = (char)binValue;
                break;

            case FieldTypeId.UInt16:
                value = (ushort)binValue;
                break;

            case FieldTypeId.Int16:
                value = (short)binValue;
                break;

            case FieldTypeId.UInt32:
                value = (uint)binValue;
                break;

            case FieldTypeId.Int32:
                value = (int)binValue;
                break;

            case FieldTypeId.UInt64:
                value = (ulong)binValue;
                break;

            case FieldTypeId.Int64:
                value = (long)binValue;
                break;

            case FieldTypeId.Enum:
                Type underlayingType = Enum.GetUnderlyingType(fieldInfo.FieldType);
                switch (Type.GetTypeCode(underlayingType))
                {
                case TypeCode.Byte:
                    value = (byte)binValue;
                    break;

                case TypeCode.SByte:
                    value = (sbyte)binValue;
                    break;

                case TypeCode.Int16:
                    value = (short)binValue;
                    break;

                case TypeCode.UInt16:
                    value = (ushort)binValue;
                    break;

                case TypeCode.Int32:
                    value = (int)binValue;
                    break;

                case TypeCode.UInt32:
                    value = (uint)binValue;
                    break;

                case TypeCode.Int64:
                    value = (long)binValue;
                    break;

                case TypeCode.UInt64:
                    value = (ulong)binValue;
                    break;
                }
                break;

            case FieldTypeId.Single:
                value = BitConverter.ToSingle(BitConverter.GetBytes((uint)binValue), 0);
                break;

            case FieldTypeId.Double:
                value = BitConverter.ToDouble(BitConverter.GetBytes((ulong)binValue), 0);
                break;

            case FieldTypeId.DateTime:
                value = new DateTime((long)binValue);
                break;

            case FieldTypeId.TimeSpan:
                value = new TimeSpan((long)binValue);
                break;

            case FieldTypeId.String:
                uint count = ReadCompressedUnsigned(stream);
                if (count != uint.MaxValue)
                {
                    byte[] bytes = new byte[count];
                    stream.Read(bytes, 0, (int)count);
                    value = Encoding.UTF8.GetString(bytes);
                }
                else
                {
                    value = null;
                }
                break;

            case FieldTypeId.Struct:
            case FieldTypeId.Class:
                value = DeSerializeObject(stream, fieldInfo.FieldType);
                break;

            default:
                throw new NotSupportedException();
            }
            fieldInfo.SetValue(obj, value);
        }
        private static void SerializeField(MemoryStream stream, object obj, FieldInfo fieldInfo)
        {
            object value = fieldInfo.GetValue(obj);
            ulong  binValue;
            SerializationHintsAttribute attribute = GetSerializationHintsAttribute(fieldInfo);
            FieldTypeId id = GetFieldTypeId(fieldInfo, attribute);

            switch (id)
            {
            case FieldTypeId.Boolean:
                binValue = ((bool)value) ? (ulong)1 : (ulong)0;
                break;

            case FieldTypeId.Byte:
                binValue = (byte)value;
                break;

            case FieldTypeId.SByte:
                binValue = (ulong)(sbyte)value;
                break;

            case FieldTypeId.Char:
                binValue = (char)value;
                break;

            case FieldTypeId.UInt16:
                binValue = (ushort)value;
                break;

            case FieldTypeId.Int16:
                binValue = (ulong)(short)value;
                break;

            case FieldTypeId.UInt32:
                binValue = (uint)value;
                break;

            case FieldTypeId.Int32:
                binValue = (ulong)(int)value;
                break;

            case FieldTypeId.UInt64:
                binValue = (ulong)value;
                break;

            case FieldTypeId.Int64:
                binValue = (ulong)(long)value;
                break;

            case FieldTypeId.Enum:
                Type underlayingType = Enum.GetUnderlyingType(fieldInfo.FieldType);
                switch (Type.GetTypeCode(underlayingType))
                {
                case TypeCode.Byte:
                    binValue = (byte)value;
                    break;

                case TypeCode.SByte:
                    binValue = (ulong)(sbyte)value;
                    break;

                case TypeCode.Int16:
                    binValue = (ulong)(short)value;
                    break;

                case TypeCode.UInt16:
                    binValue = (ushort)value;
                    break;

                case TypeCode.Int32:
                    binValue = (ulong)(int)value;
                    break;

                case TypeCode.UInt32:
                    binValue = (uint)value;
                    break;

                case TypeCode.Int64:
                    binValue = (ulong)(long)value;
                    break;

                case TypeCode.UInt64:
                    binValue = (ulong)value;
                    break;

                default:
                    throw new NotSupportedException("Invalid enum.");
                }
                break;

            case FieldTypeId.Single:
                binValue = BitConverter.ToUInt32(BitConverter.GetBytes((float)value), 0);
                break;

            case FieldTypeId.Double:
                binValue = BitConverter.ToUInt64(BitConverter.GetBytes((double)value), 0);
                break;

            case FieldTypeId.DateTime:
                binValue = (ulong)((DateTime)value).Ticks;
                break;

            case FieldTypeId.TimeSpan:
                binValue = (ulong)((TimeSpan)value).Ticks;
                break;

            case FieldTypeId.String:
                if (value != null)
                {
                    byte[] bytes = Encoding.UTF8.GetBytes((string)value);
                    WriteCompressedUnsigned(stream, (uint)bytes.Length);
                    stream.Write(bytes, 0, bytes.Length);
                }
                else
                {
                    WriteCompressedUnsigned(stream, uint.MaxValue);
                }
                return;

            case FieldTypeId.Struct:
                SerializeObject(stream, value, fieldInfo.FieldType);
                return;

            case FieldTypeId.Class:
                if (value == null)
                {
                    throw new NotSupportedException("Fields which are classes must not be null.");
                }
                SerializeObject(stream, value, fieldInfo.FieldType);
                return;

            case FieldTypeId.NonSerializableFieldType:
                return;

            default:
                throw new NotSupportedException();
            }
            int byteCount = GetByteSize(fieldInfo, id, attribute);

            WriteUnsignedLong(stream, binValue, byteCount);
        }