コード例 #1
0
        /// <summary>
        /// Tries to read a custom type.
        /// </summary>
        /// <param name="reader">The reader.</param>
        /// <param name="result">The result.</param>
        /// <returns>True if the custom type could be readed successfully; otherwise false.</returns>
        public static bool ReadCustomType(IBinaryReader reader, out object result)
        {
            CustomTypeInfo info;
            byte           typeCode = reader.ReadByte();

            if (!CustomTypeCache.TryGet(typeCode, out info) && !Protocol.AllowRawCustomValues)
            {
                if (log.IsDebugEnabled)
                {
                    log.DebugFormat("Could not find custom type for type code {0}", new object[] { typeCode });
                }
                result = null;
                return(false);
            }
            short length = reader.ReadInt16();

            if ((length < 0) || ((reader.BaseStream.Length - reader.BaseStream.Position) < length))
            {
                if (log.IsDebugEnabled)
                {
                    log.DebugFormat("Invalid length for custom type: length={0}, bytesLeft={1}", new object[] { length, reader.BaseStream.Length - reader.BaseStream.Position });
                }
                result = null;
                return(false);
            }
            byte[] arg = reader.ReadBytes(length);
            result = (info != null) ? info.DeserializeFunction(arg) : new RawCustomValue(typeCode, arg);
            return(true);
        }
コード例 #2
0
        private static void WriteDictionary(IBinaryWriter writer, object dict)
        {
            Type[] genericArguments = dict.GetType().GetGenericArguments();
            bool   setType          = genericArguments[0] == typeof(object);
            bool   flag2            = genericArguments[1] == typeof(object);

            if (setType)
            {
                writer.WriteByte(0);
            }
            else
            {
                GpType gpType = GpBinaryByteTypeConverter.GetGpType(genericArguments[0]);
                switch (gpType)
                {
                case GpType.Unknown:
                case GpType.Dictionary:
                    throw new InvalidDataException("Unexpected - cannot serialize Dictionary with key type: " + genericArguments[0]);
                }
                writer.WriteByte((byte)gpType);
            }
            if (flag2)
            {
                writer.WriteByte(0);
            }
            else
            {
                GpType type2 = GpBinaryByteTypeConverter.GetGpType(genericArguments[1]);
                if (type2 == GpType.Unknown)
                {
                    CustomTypeInfo info;
                    if (!CustomTypeCache.TryGet(genericArguments[1], out info))
                    {
                        throw new InvalidDataException("Unexpected - cannot serialize Dictionary with value type: " + genericArguments[1]);
                    }
                    writer.WriteByte(0x63);
                    writer.WriteByte(info.Code);
                }
                else
                {
                    writer.WriteByte((byte)type2);
                    if (type2 == GpType.Dictionary)
                    {
                        WriteDictionaryHeader(writer, genericArguments[1]);
                    }
                    else if ((type2 == GpType.Array) && !WriteArrayHeader(writer, genericArguments[1].GetElementType()))
                    {
                        throw new InvalidDataException("Unexpected - cannot serialize Dictionary with value type: " + genericArguments[1]);
                    }
                }
            }
            IDictionary dictionary = (IDictionary)dict;

            writer.WriteInt16((short)dictionary.Count);
            foreach (DictionaryEntry entry in dictionary)
            {
                Write(writer, entry.Key, setType);
                Write(writer, entry.Value, flag2);
            }
        }
コード例 #3
0
        /// <summary>
        /// Writes an array.
        /// </summary>
        /// <param name="writer"> The writer.</param>
        /// <param name="serObject">The ser object.</param>
        private static void WriteArray(IBinaryWriter writer, IList serObject)
        {
            Type   elementType = serObject.GetType().GetElementType();
            GpType gpType      = GpBinaryByteTypeConverter.GetGpType(elementType);

            if (gpType == GpType.Unknown)
            {
                if (elementType == typeof(RawCustomArray))
                {
                    writer.WriteInt16((short)serObject.Count);
                    for (int i = 0; i < serObject.Count; i++)
                    {
                        WriteCustomTypeArray(writer, (RawCustomArray)serObject[i], i == 0);
                    }
                }
                else
                {
                    CustomTypeInfo info;
                    if (!CustomTypeCache.TryGet(elementType, out info))
                    {
                        throw new InvalidDataException(string.Format("Arrays of type '{0}' are not supported.", elementType));
                    }
                    WriteCustomTypeArray(writer, info, serObject);
                }
            }
            else
            {
                writer.WriteInt16((short)serObject.Count);
                writer.WriteByte((byte)gpType);
                if (gpType == GpType.Dictionary)
                {
                    bool flag;
                    bool flag2;
                    WriteDictionaryHeader(writer, serObject, out flag, out flag2);
                    foreach (object obj2 in serObject)
                    {
                        WriteDictionaryElements(writer, obj2, flag, flag2);
                    }
                }
                else
                {
                    foreach (object obj3 in serObject)
                    {
                        Write(writer, obj3, false);
                    }
                }
            }
        }
コード例 #4
0
        private static bool ReadCustomTypeArray(IBinaryReader reader, int size, out object result)
        {
            CustomTypeInfo info;
            byte           typeCode = reader.ReadByte();

            if (!CustomTypeCache.TryGet(typeCode, out info) && !Protocol.AllowRawCustomValues)
            {
                if (log.IsDebugEnabled)
                {
                    log.DebugFormat("Could not find custom type for type code {0}", new object[] { typeCode });
                }
                result = null;
                return(false);
            }
            if ((size < 0) || ((size * 2) > (reader.BaseStream.Length - reader.BaseStream.Position)))
            {
                if (log.IsDebugEnabled)
                {
                    log.DebugFormat("Invalid length for array of type {2}: length={0}, bytesLeft={1}", new object[] { size, reader.BaseStream.Length - reader.BaseStream.Position, info.Type });
                }
                result = null;
                return(false);
            }
            if (info != null)
            {
                Array array = Array.CreateInstance(info.Type, size);
                for (short i = 0; i < size; i = (short)(i + 1))
                {
                    int    length = reader.ReadInt16();
                    byte[] arg    = reader.ReadBytes(length);
                    object obj2   = info.DeserializeFunction(arg);
                    array.SetValue(obj2, (int)i);
                }
                result = array;
            }
            else
            {
                RawCustomArray array2 = new RawCustomArray(typeCode, size);
                for (short j = 0; j < size; j = (short)(j + 1))
                {
                    int    num5    = reader.ReadInt16();
                    byte[] buffer2 = reader.ReadBytes(num5);
                    array2[j] = buffer2;
                }
                result = array2;
            }
            return(true);
        }
コード例 #5
0
 public static void Write(Stream stream, object value)
 {
     if (value == null)
     {
         stream.WriteByte(0x2a);
     }
     else
     {
         Type type = value.GetType();
         if (type.IsArray)
         {
             WriteArray(stream, type, value);
         }
         else
         {
             GpTypeV17     gpType    = GetGpType(type);
             WriteDelegate delegate2 = writeMethods[(int)gpType];
             if (delegate2 != null)
             {
                 stream.WriteByte((byte)gpType);
                 delegate2(stream, value);
             }
             else
             {
                 CustomTypeInfo info;
                 if (CustomTypeCache.TryGet(type, out info))
                 {
                     WriteCustomType(stream, info, value, true);
                 }
                 else if (type == typeof(RawCustomValue))
                 {
                     WriteCustomType(stream, (RawCustomValue)value, true);
                 }
                 else
                 {
                     if (type != typeof(RawCustomArray))
                     {
                         throw new InvalidDataException("cannot serialize(): " + type);
                     }
                     WriteCustomTypeArray(stream, (RawCustomArray)value, true);
                 }
             }
         }
     }
 }
コード例 #6
0
        public static bool ReadCustomType(byte[] data, ref int offset, out object result)
        {
            byte           num;
            CustomTypeInfo info;
            uint           num2;

            byte[] buffer;
            if (!BigEndianReader.TryReadByte(data, ref offset, out num))
            {
                result = null;
                return(false);
            }
            if (!CustomTypeCache.TryGet(num, out info) && !Protocol.AllowRawCustomValues)
            {
                if (log.IsDebugEnabled)
                {
                    log.DebugFormat("Could not find custom type for type code {0}", new object[] { num });
                }
                result = null;
                return(false);
            }
            if (!TryReadCompresssedUInt32(data, ref offset, out num2))
            {
                result = null;
                return(false);
            }
            if (!BigEndianReader.TryReadByteArray(data, ref offset, (int)num2, out buffer))
            {
                if (log.IsDebugEnabled)
                {
                    log.DebugFormat("Invalid length for custom type: length={0}, bytesLeft={1}", new object[] { num2, data.Length - offset });
                }
                result = null;
                return(false);
            }
            result = (info != null) ? info.DeserializeFunction(buffer) : new RawCustomValue(num, buffer);
            return(true);
        }
コード例 #7
0
        /// <summary>
        /// Serializes an object.
        /// </summary>
        /// <param name="writer">The writer.</param>
        /// <param name="value">The object to write.</param>
        /// <param name="setType">The set type.</param>
        /// <exception cref="T:System.IO.InvalidDataException">
        /// The type of the <paramref name="value"/> can not be serialized.
        /// </exception>
        /// <exception cref="T:System.ArrayTypeMismatchException">
        /// A collection with different types can not be serialized.
        /// </exception>
        private static void Write(IBinaryWriter writer, object value, bool setType)
        {
            Type   type   = (value == null) ? null : value.GetType();
            GpType gpType = GpBinaryByteTypeConverter.GetGpType(type);
            GpType type3  = gpType;

            if (type3 != GpType.Unknown)
            {
                if ((type3 == GpType.Array) && (value is byte[]))
                {
                    gpType = GpType.ByteArray;
                }
            }
            else
            {
                CustomTypeInfo info;
                if (type == typeof(RawCustomArray))
                {
                    WriteCustomTypeArray(writer, (RawCustomArray)value, true);
                    return;
                }
                if (CustomTypeCache.TryGet(type, out info))
                {
                    if (setType)
                    {
                        writer.WriteByte(0x63);
                    }
                    WriteCustomType(writer, info, value);
                    return;
                }
                if (type != typeof(RawCustomValue))
                {
                    throw new InvalidDataException("cannot serialize(): " + type);
                }
                if (setType)
                {
                    writer.WriteByte(0x63);
                }
                WriteCustomType(writer, (RawCustomValue)value);
                return;
            }
            if (setType)
            {
                writer.WriteByte((byte)gpType);
            }
            GpType type4 = gpType;

            if (type4 != GpType.Null)
            {
                switch (type4)
                {
                case GpType.Byte:
                    writer.WriteByte((byte)value);
                    return;

                case GpType.Custom:
                    WriteCustomType(writer, (RawCustomValue)value);
                    return;

                case GpType.Double:
                    writer.WriteDouble((double)value);
                    return;

                case GpType.EventData:
                    WriteEventData(writer, (EventData)value);
                    return;

                case GpType.Float:
                    writer.WriteSingle((float)value);
                    return;

                case GpType.Hashtable:
                    WriteHashTable(writer, (Hashtable)value);
                    return;

                case GpType.Integer:
                    writer.WriteInt32((int)value);
                    return;

                case GpType.Short:
                    writer.WriteInt16((short)value);
                    return;

                case GpType.Long:
                    writer.WriteInt64((long)value);
                    return;

                case GpType.Boolean:
                    writer.WriteBoolean((bool)value);
                    return;

                case GpType.OperationResponse:
                    WriteOperationResponse(writer, (OperationResponse)value);
                    return;

                case GpType.OperationRequest:
                    WriteOperationRequest(writer, (OperationRequest)value);
                    return;

                case GpType.String:
                    writer.WriteUTF((string)value);
                    return;

                case GpType.Vector:
                    WriteVector(writer, (IList)value);
                    return;

                case GpType.ByteArray:
                    WriteByteArray(writer, (byte[])value);
                    return;

                case GpType.Array:
                    WriteArray(writer, (IList)value);
                    return;

                case GpType.ObjectArray:
                    WriteObjectArray(writer, (IList)value);
                    return;

                case GpType.Dictionary:
                    WriteDictionary(writer, value);
                    return;
                }
            }
            else
            {
                if (!setType)
                {
                    throw new InvalidOperationException("cannot serialize null values inside an array");
                }
                return;
            }
            throw new InvalidDataException("Unexpected - cannot serialize gp type: " + gpType);
        }
コード例 #8
0
        private static void WriteArray(Stream stream, Type type, object value)
        {
            Type elementType = type.GetElementType();

            if (elementType == null)
            {
                throw new InvalidDataException(string.Format("Arraysof type {0} are not supported", type));
            }
            if (elementType.IsPrimitive)
            {
                switch (Type.GetTypeCode(elementType))
                {
                case TypeCode.Boolean:
                    WriteBoolArray(stream, (bool[])value, true);
                    return;

                case TypeCode.Byte:
                    stream.WriteByte(120);
                    WriteByteArray(stream, (byte[])value);
                    return;

                case TypeCode.Int16:
                    stream.WriteByte(0xeb);
                    WriteInt16Array(stream, (short[])value);
                    return;

                case TypeCode.Int32:
                    WriteInt32ArrayCompressed(stream, (int[])value, true);
                    return;

                case TypeCode.Int64:
                    WriteInt64ArrayCompressed(stream, (long[])value, true);
                    return;

                case TypeCode.Single:
                    WriteSingleArray(stream, (float[])value, true);
                    return;

                case TypeCode.Double:
                    WriteDoubleArray(stream, (double[])value, true);
                    return;
                }
            }
            if (elementType.IsArray)
            {
                WriteArrayInArray(stream, value);
            }
            if (elementType == typeof(string))
            {
                WriteStringArray(stream, (string[])value, true);
            }
            else if (elementType == typeof(object))
            {
                stream.WriteByte(0x7a);
                WriteObjectArray(stream, (object[])value);
            }
            else if (elementType == typeof(Hashtable))
            {
                Hashtable[] hashtableArray = (Hashtable[])value;
                stream.WriteByte(0xe8);
                WriteIntLength(stream, hashtableArray.Length);
                foreach (Hashtable hashtable in hashtableArray)
                {
                    WriteHashTable(stream, hashtable);
                }
            }
            else
            {
                CustomTypeInfo info;
                if (elementType.IsGenericType)
                {
                    Type genericTypeDefinition = elementType.GetGenericTypeDefinition();
                    if (typeof(Dictionary <,>) == genericTypeDefinition)
                    {
                        WriteDelegate delegate2;
                        WriteDelegate delegate3;
                        IDictionary[] dictionaryArray = (IDictionary[])value;
                        stream.WriteByte(0xc4);
                        WriteDictionaryHeader(stream, elementType, out delegate2, out delegate3);
                        WriteIntLength(stream, dictionaryArray.Length);
                        foreach (IDictionary dictionary in dictionaryArray)
                        {
                            WriteDictionaryElements(stream, dictionary, delegate2, delegate3);
                        }
                    }
                }
                if (CustomTypeCache.TryGet(elementType, out info))
                {
                    WriteCustomTypeArray(stream, info, (IList)value);
                }
            }
        }
コード例 #9
0
        private static bool ReadDictionary(IBinaryReader reader, out object result)
        {
            ReadDelegate readDelegate;
            Type         clrArrayType;
            ReadDelegate delegate3;
            Type         dictArrayType;

            result = null;
            GpType gpType = (GpType)reader.ReadByte();

            if (gpType == GpType.Unknown)
            {
                clrArrayType = typeof(object);
                readDelegate = new ReadDelegate(GpBinaryByteReader.Read);
            }
            else
            {
                clrArrayType = GpBinaryByteTypeConverter.GetClrArrayType(gpType);
                readDelegate = GetReadDelegate(gpType);
            }
            GpType type3 = (GpType)reader.ReadByte();

            switch (type3)
            {
            case GpType.Unknown:
                dictArrayType = typeof(object);
                delegate3     = new ReadDelegate(GpBinaryByteReader.Read);
                break;

            case GpType.Dictionary:
                dictArrayType = ReadDictionaryType(reader);
                delegate3     = new ReadDelegate(GpBinaryByteReader.ReadDictionary);
                break;

            case GpType.Array:
                dictArrayType = GetDictArrayType(reader);
                delegate3     = new ReadDelegate(GpBinaryByteReader.ReadArray);
                break;

            case GpType.ObjectArray:
                dictArrayType = typeof(object[]);
                delegate3     = new ReadDelegate(GpBinaryByteReader.ReadObjectArray);
                break;

            case GpType.Custom:
                CustomTypeInfo info;
                if (!CustomTypeCache.TryGet(reader.ReadByte(), out info))
                {
                    return(false);
                }
                dictArrayType = info.Type;
                delegate3     = new ReadDelegate(GpBinaryByteReader.ReadCustomType);
                break;

            default:
                dictArrayType = GpBinaryByteTypeConverter.GetClrArrayType(type3);
                delegate3     = GetReadDelegate(type3);
                if ((dictArrayType == null) || (delegate3 == null))
                {
                    return(false);
                }
                break;
            }
            IDictionary dictionary = Activator.CreateInstance(typeof(Dictionary <,>).MakeGenericType(new Type[] { clrArrayType, dictArrayType })) as IDictionary;

            if (dictionary == null)
            {
                return(false);
            }
            short num2 = reader.ReadInt16();

            for (int i = 0; i < num2; i++)
            {
                object obj2;
                object obj3;
                if (!readDelegate(reader, out obj2))
                {
                    return(false);
                }
                if (!delegate3(reader, out obj3))
                {
                    return(false);
                }
                dictionary.Add(obj2, obj3);
            }
            result = dictionary;
            return(true);
        }
コード例 #10
0
        private static bool ReadCustomTypeArray(byte[] data1, ref int offset, out object result)
        {
            uint           num;
            CustomTypeInfo info;

            if (!TryReadCompresssedUInt32(data1, ref offset, out num))
            {
                if (log.IsDebugEnabled)
                {
                    log.DebugFormat("Could not read size of custom type array custom type", new object[0]);
                }
                result = null;
                return(false);
            }
            if (offset >= data1.Length)
            {
                result = null;
                return(false);
            }
            byte typeCode = data1[offset++];

            if (!CustomTypeCache.TryGet(typeCode, out info) && !Protocol.AllowRawCustomValues)
            {
                if (log.IsDebugEnabled)
                {
                    log.DebugFormat("Could not find custom type for type code {0}", new object[] { typeCode });
                }
                result = null;
                return(false);
            }
            if (info != null)
            {
                Array array = Array.CreateInstance(info.Type, new long[] { (long)num });
                for (short i = 0; i < num; i = (short)(i + 1))
                {
                    uint   num4;
                    byte[] buffer;
                    if (!TryReadCompresssedUInt32(data1, ref offset, out num4))
                    {
                        result = null;
                        return(false);
                    }
                    if (!BigEndianReader.TryReadByteArray(data1, ref offset, (int)num4, out buffer))
                    {
                        result = null;
                        return(false);
                    }
                    object obj2 = info.DeserializeFunction(buffer);
                    array.SetValue(obj2, (int)i);
                }
                result = array;
            }
            else
            {
                RawCustomArray array2 = new RawCustomArray(typeCode, (int)num);
                for (short j = 0; j < num; j = (short)(j + 1))
                {
                    uint   num6;
                    byte[] buffer2;
                    if (!TryReadCompresssedUInt32(data1, ref offset, out num6))
                    {
                        result = null;
                        return(false);
                    }
                    if (!BigEndianReader.TryReadByteArray(data1, ref offset, (int)num6, out buffer2))
                    {
                        result = null;
                        return(false);
                    }
                    array2[j] = buffer2;
                }
                result = array2;
            }
            return(true);
        }