Exemplo n.º 1
0
        /// <summary>
        /// Serialises the given <see cref="IList"/> to the given <see cref="BinaryWriter"/>s underlying <see cref="MemoryStream"/>.
        /// Uses <see cref="SerialiseObjectToWriter(object,BinaryWriter)"/> to serialise each of the <see cref="IList"/>s
        /// elements to the stream.
        /// </summary>
        /// <param name="obj">
        /// The <see cref="IList"/> to serialise to the given <see cref="BinaryWriter"/>s underlying <see cref="MemoryStream"/>.
        /// </param>
        /// <param name="propertyInfo">The <see cref="PropertyInfo"/> holding the <see cref="IList"/>. </param>
        /// <param name="binaryWriter">
        /// The <see cref="BinaryWriter"/> to whose underlying <see cref="MemoryStream"/> to serialise the given <see cref="PropertyInfo"/>.
        /// </param>
        /// <exception cref="NullReferenceException">
        /// Thrown if the <see cref="IList"/> held in the given <see cref="PropertyInfo"/> is null, or if the <see cref="IList"/>s
        /// elements do not have a type.
        /// </exception>
        private void SerialiseListToWriter(object obj, PropertyInfo propertyInfo, BinaryWriter binaryWriter)
        {
            Type elementType = propertyInfo.PropertyType.GetGenericArguments()[0];

            IList list = (IList)Activator.CreateInstance(typeof(List <>).MakeGenericType(elementType));

            IEnumerable currentList = (IEnumerable)propertyInfo.GetValue(obj);

            foreach (object element in currentList)
            {
                list.Add(element);
            }

            binaryWriter.Write(list.Count);

            if (elementType.IsClass && !PacketConverterHelper.TypeIsPrimitive(elementType))
            {
                foreach (object element in list)
                {
                    SerialiseObjectToWriter(element, binaryWriter);
                }
            }
            else //Primitive type
            {
                foreach (object primitiveElement in list)
                {
                    dynamic primitiveValue = primitiveElement;
                    binaryWriter.Write(primitiveValue);
                }
            }
        }
Exemplo n.º 2
0
        /// <inheritdoc />
        public P GetPacket <P>(byte[] serialisedPacket) where P : Packet
        {
            MemoryStream memoryStream = new MemoryStream(serialisedPacket, 0, serialisedPacket.Length);
            BinaryReader binaryReader = new BinaryReader(memoryStream);

            //Temporary object whose properties will be set during deserialisation
            P packet = PacketConverterHelper.InstantiateGenericPacket <P>();

            DeserialiseObjectFromReader(packet, binaryReader);

            return(packet);
        }
Exemplo n.º 3
0
        /// <inheritdoc />
        public Packet GetPacket(Type packetType, byte[] serialisedPacket)
        {
            MemoryStream memoryStream = new MemoryStream(serialisedPacket, 0, serialisedPacket.Length);
            BinaryReader binaryReader = new BinaryReader(memoryStream);

            //Temporary object whose properties will be set during deserialisation
            Packet packet = PacketConverterHelper.InstantiatePacket(packetType);

            DeserialiseObjectFromReader(packet, binaryReader);

            return(packet);
        }
Exemplo n.º 4
0
        /// <summary>
        /// Serialises the given <see cref="PropertyInfo"/> to the given <see cref="BinaryWriter"/>s underlying <see cref="MemoryStream"/>.
        /// </summary>
        /// <param name="obj">The <see cref="object"/> whose <see cref="PropertyInfo"/> value to serialise.</param>
        /// <param name="propertyInfo">
        /// The <see cref="PropertyInfo"/> to serialise to the given <see cref="BinaryWriter"/>s underlying <see cref="MemoryStream"/>.
        /// </param>
        /// <param name="binaryWriter">
        /// The <see cref="BinaryWriter"/> to whose underlying <see cref="MemoryStream"/> to serialise the given <see cref="PropertyInfo"/>.
        /// </param>
        private void SerialiseObjectToWriter(object obj, PropertyInfo propertyInfo, BinaryWriter binaryWriter)
        {
            Type    propertyType  = propertyInfo.PropertyType;
            dynamic propertyValue = propertyInfo.GetValue(obj);

            //We have an enum
            if (propertyType.IsEnum)
            {
                binaryWriter.Write(propertyValue.ToString());
            }
            //We have an array
            else if (propertyType.IsArray)
            {
                SerialiseArrayToWriter(obj, propertyInfo, binaryWriter);
            }
            //We have a list
            else if (propertyType.IsGenericType && propertyType.GetGenericTypeDefinition() == typeof(List <>))
            {
                SerialiseListToWriter(obj, propertyInfo, binaryWriter);
            }
            //We have a non-primitive type
            else if (!PacketConverterHelper.TypeIsPrimitive(propertyType))
            {
                if (propertyValue != null) //Not null non-primitive type value
                {
                    //There is a value to read from the network stream
                    binaryWriter.Write((byte)ObjectState.NotNull);
                    SerialiseObjectToWriter(propertyValue, binaryWriter);
                }
                else //Null non-primitive type value
                {
                    //There isn't a value to read from the network stream
                    binaryWriter.Write((byte)ObjectState.Null);
                }
            }
            //We have a primitive type
            else
            {
                if (propertyValue != null) //Not null primitive type value
                {
                    //There is a value to read from the network stream
                    binaryWriter.Write((byte)ObjectState.NotNull);
                    //We write the value to the stream
                    binaryWriter.Write(propertyValue);
                }
                else //Null primitive type value
                {
                    //There isn't a value to read from the network stream
                    binaryWriter.Write((byte)ObjectState.Null);
                }
            }
        }
Exemplo n.º 5
0
        /// <summary>
        /// Returns an array of the <see cref="PropertyInfo"/>s that need to be serialised on the given <see cref="Type"/>.
        /// If the given <see cref="Type"/> has already been cached, it will use the cached <see cref="PropertyInfo"/> array,
        /// to save CPU time.
        /// </summary>
        /// <param name="type">The <see cref="Type"/> whose serialisable properties to get.</param>
        /// <returns>
        /// An array of all <see cref="PropertyInfo"/>s that should be serialised on the given <see cref="Type"/>
        /// </returns>
        private PropertyInfo[] GetTypeProperties(Type type)
        {
            lock (packetPropertyCacheLock)
            {
                //Cache the properties to serialise if we haven't already
                if (!packetPropertyCache.ContainsKey(type))
                {
                    packetPropertyCache[type] = PacketConverterHelper.GetTypeProperties(type);
                }

                return(packetPropertyCache[type]);
            }
        }
Exemplo n.º 6
0
        /// <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);
        }
Exemplo n.º 7
0
        /// <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);
        }
Exemplo n.º 8
0
        /// <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);
        }
Exemplo n.º 9
0
        /// <summary>
        /// Serialises the given <see cref="Array"/> to the given <see cref="BinaryWriter"/>s underlying <see cref="MemoryStream"/>.
        /// Uses <see cref="SerialiseObjectToWriter(object,BinaryWriter)"/> to serialise each of the <see cref="Array"/>s
        /// elements to the stream.
        /// </summary>
        /// <param name="obj">
        /// The <see cref="Array"/> to serialise to the given <see cref="BinaryWriter"/>s underlying <see cref="MemoryStream"/>.
        /// </param>
        /// <param name="propertyInfo">The <see cref="PropertyInfo"/> holding the <see cref="Array"/>.</param>
        /// <param name="binaryWriter">
        /// The <see cref="BinaryWriter"/> to whose underlying <see cref="MemoryStream"/> to serialise the given <see cref="PropertyInfo"/>.
        /// </param>
        /// <exception cref="NullReferenceException">
        /// Thrown if the <see cref="Array"/> held in the given <see cref="PropertyInfo"/> is null, or if the <see cref="Array"/>s
        /// elements do not have a type.
        /// </exception>
        private void SerialiseArrayToWriter(object obj, PropertyInfo propertyInfo, BinaryWriter binaryWriter)
        {
            Type  elementType = propertyInfo.PropertyType.GetElementType();
            Array array       = (Array)propertyInfo.GetValue(obj);

            binaryWriter.Write(array?.Length ?? 0);

            if (elementType.IsClass && !PacketConverterHelper.TypeIsPrimitive(elementType))
            {
                foreach (object element in array)
                {
                    SerialiseObjectToWriter(element, binaryWriter);
                }
            }
            else //Primitive element type
            {
                foreach (object primitiveElement in array)
                {
                    dynamic primitiveValue = primitiveElement;
                    binaryWriter.Write(primitiveValue);
                }
            }
        }