/// <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); }
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); } }
/// <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); } } } }
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); }
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); } } } } }
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); }
/// <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); }
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); } } }
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); }
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); }