/// <summary> /// Deserialises the given <see cref="Array"/> from the given <see cref="BinaryReader"/>s underlying /// <see cref="MemoryStream"/>. Uses <see cref="DeserialiseObjectFromReader(object,BinaryReader)"/> to serialise /// each of the <see cref="Array"/>s elements to the stream. /// </summary> /// <param name="obj"> /// The <see cref="Array"/> to deserialise from the given <see cref="BinaryReader"/>s underlying <see cref="MemoryStream"/>. /// </param> /// <param name="propertyInfo">The <see cref="PropertyInfo"/> holding the <see cref="Array"/>.</param> /// <param name="binaryReader"> /// The <see cref="BinaryReader"/> from whose underlying <see cref="MemoryStream"/> to deserialise the given /// <see cref="PropertyInfo"/>. /// </param> /// <exception cref="ArgumentNullException">Thrown if the <see cref="Array"/>s elements do not have a type.</exception> private Array ReadArrayFromStream(object obj, PropertyInfo propertyInfo, BinaryReader binaryReader) { int arraySize = binaryReader.ReadInt32(); Type elementType = propertyInfo.PropertyType.GetElementType(); Array array = Array.CreateInstance(elementType, arraySize); for (int i = 0; i < arraySize; ++i) { if (elementType.IsClass && !PacketConverterHelper.TypeIsPrimitive(elementType)) { array.SetValue(DeserialiseObjectFromReader(PacketConverterHelper.InstantiateObject(elementType), binaryReader), i); } else { array.SetValue(ReadPrimitiveFromStream(elementType, binaryReader), i); } } return(array); }
/// <summary> /// Deserialises the given <see cref="IList"/> from the given <see cref="BinaryReader"/>s underlying /// <see cref="MemoryStream"/>. Uses <see cref="DeserialiseObjectFromReader(object,BinaryReader)"/> to serialise /// each of the <see cref="IList"/>s elements to the stream. /// </summary> /// <param name="obj"> The <see cref="IList"/> to deserialise from the given <see cref="BinaryReader"/>s underlying /// <see cref="MemoryStream"/>. /// </param> /// <param name="propertyInfo">The <see cref="PropertyInfo"/> holding the <see cref="IList"/>.</param> /// <param name="binaryReader"> /// The <see cref="BinaryReader"/> from whose underlying <see cref="MemoryStream"/> to deserialise the given /// <see cref="PropertyInfo"/>. /// </param> /// <exception cref="NullReferenceException"> /// Thrown if the <see cref="IList"/> held in the <see cref="MemoryStream"/> is null, or if the <see cref="IList"/>s /// elements do not have a type. /// </exception> private IList ReadListFromStream(object obj, PropertyInfo propertyInfo, BinaryReader binaryReader) { int listSize = binaryReader.ReadInt32(); Type listType = propertyInfo.PropertyType.GetGenericArguments()[0]; IList list = (IList)Activator.CreateInstance(typeof(List <>).MakeGenericType(listType)); for (int i = 0; i < listSize; ++i) { if (listType.IsClass && !PacketConverterHelper.TypeIsPrimitive(listType)) { list.Add(DeserialiseObjectFromReader(PacketConverterHelper.InstantiateObject(listType), binaryReader)); } else { list.Add(ReadPrimitiveFromStream(listType, binaryReader)); } } return(list); }
/// <summary> /// Deserialises the given <see cref="PropertyInfo"/> from the given <see cref="BinaryReader"/>s underlying /// <see cref="MemoryStream"/>. /// </summary> /// <param name="obj"> The <see cref="object"/> whose <see cref="PropertyInfo"/> value to deserialise.</param> /// <param name="propertyInfo"> /// The <see cref="PropertyInfo"/> to deserialise from the given <see cref="BinaryReader"/>s underlying /// <see cref="MemoryStream"/>. /// </param> /// <param name="binaryReader"> /// The <see cref="BinaryReader"/> from whose underlying <see cref="MemoryStream"/> to deserialise the given /// <see cref="PropertyInfo"/>. /// </param> /// <returns> /// The <see cref="object"/> deserialised from the <see cref="MemoryStream"/>. This can be null if the /// <see cref="ObjectState"/> is <see cref="ObjectState.Null"/>. /// </returns> private object DeserialiseObjectFromReader(object obj, PropertyInfo propertyInfo, BinaryReader binaryReader) { Type propertyType = propertyInfo.PropertyType; //We have an enumeration if (propertyType.IsEnum) { return(Enum.Parse(propertyType, binaryReader.ReadString())); } //We have an array if (propertyType.IsArray) { return(ReadArrayFromStream(obj, propertyInfo, binaryReader)); } //We have a generic list if (propertyType.IsGenericType && propertyType.GetGenericTypeDefinition() == typeof(List <>)) { return(ReadListFromStream(obj, propertyInfo, binaryReader)); } ObjectState objectState = (ObjectState)binaryReader.ReadByte(); if (PacketConverterHelper.TypeIsPrimitive(propertyType)) //We have a primitive type { //If the primitive object is null we just return null, otherwise we deserialise from the stream return(objectState == ObjectState.NotNull ? ReadPrimitiveFromStream(propertyType, binaryReader) : null); } //We have a complex type //If the custom object is null we just return null, otherwise we deserialise from the stream return(objectState == ObjectState.NotNull ? DeserialiseObjectFromReader(PacketConverterHelper.InstantiateObject(propertyType), binaryReader) : null); }