Example #1
0
        private object DeserializeToFields(Type t, object o, DeserializationFlags flags, BindingFlags bindFlags)
        {
            // TODO: there /has/ to be some way to generalize this process
            //       for both fields and properties...

            FieldInfo[] allFields;
            Type        fieldType;
            bool        isArray;
            Type        elemType;
            bool        isGeneric;
            Type        genType;
            object      val;

            if (!flags.HasFlag(DeserializationFlags.Fields))
            {
                return(o);
            }

            allFields = t.GetFields(bindFlags);

            foreach (FieldInfo f in allFields)
            {
                fieldType = f.FieldType;
                isArray   = fieldType.IsArray;
                elemType  = fieldType.GetElementType();
                isGeneric = fieldType.IsGenericType;

                if (isGeneric && fieldType.GetGenericTypeDefinition() == typeof(Primitive <>))
                {
                    genType = fieldType.GetGenericArguments()[0];
                    val     = DeserializePrimitive(f.Name, genType, o, flags);
                }
                else if (isArray)
                {
                    if (PrimitiveTypeUtils.IsPrimitiveType(elemType))
                    {
                        val = DeserializeValueArray(f.Name, elemType, o, flags);
                    }
                    else
                    {
                        val = DeserializeStructureArray(f.Name, elemType, o, flags);
                    }
                }
                else if (PrimitiveTypeUtils.IsPrimitiveType(fieldType))
                {
                    val = DeserializeValue(f.Name, fieldType, o, flags);
                }
                else
                {
                    val = DeserializeStructure(f.Name, fieldType, o, flags);
                }

                if (val != null)
                {
                    f.SetValue(o, val);
                }
            }

            return(o);
        }
Example #2
0
        /// <summary>
        /// Sets an array of values in the file data.
        /// </summary>
        /// <remarks>
        /// If <typeparamref name="T"/> is a multi-byte type, the bytes of each element
        /// will be written in the order specified by the <see cref="Endianness"/> property.
        /// </remarks>
        /// <typeparam name="T">The type of the values to set.</typeparam>
        /// <param name="index">The position in the file data of the first value to get.</param>
        /// <param name="values">The values to be written to the binary file data starting at the index.</param>
        /// <exception cref="ArgumentOutOfRangeException">
        /// If the index is out of range or if the count results in an index that is out of range.
        /// </exception>
        public void Set <T>(int index, T[] values)
            where T : struct
        {
            if (!PrimitiveTypeUtils.IsPrimitiveType <T>())
            {
                throw new ArgumentException(Resources.ArgumentExceptionPrimitiveType, nameof(T));
            }

            int elemSize = PrimitiveTypeUtils.SizeOf <T>();
            int numBytes = elemSize * values.Length;

            RangeCheck(index);
            RangeCheck(index + numBytes - 1);

            // Convert values into a single array of bytes
            byte[] b = new byte[numBytes];
            for (int i = 0; i < values.Length; i++)
            {
                byte[] valueBytes = PrimitiveTypeUtils.GetBytes <T>(values[i]);
                if (Endianness == Endianness.Big)
                {
                    valueBytes = valueBytes.Reverse().ToArray();
                }

                Buffer.BlockCopy(valueBytes, 0, b, i * elemSize, elemSize);
            }

            // Copy byte array to binary file data
            Marshal.Copy(b, 0, dataPtr + index, numBytes);
        }
Example #3
0
        /// <summary>
        /// Gets an array of values from the file data.
        /// </summary>
        /// <remarks>
        /// If <typeparamref name="T"/> is a multi-byte type, the bytes of each element
        /// will be retrieved in the order specified by the <see cref="Endianness"/> property.
        /// </remarks>
        /// <typeparam name="T">The type of the values to get.</typeparam>
        /// <param name="index">The position in the file data of the first value to get.</param>
        /// <param name="count">The number of elements to get.</param>
        /// <returns>
        /// An array of <paramref name="count"/> values retrieved from the binary file data at the specified index.
        /// </returns>
        /// <exception cref="ArgumentOutOfRangeException">
        /// If the index is out of range or if the count results in an index that is out of range.
        /// </exception>
        public T[] Get <T>(int index, int count)
            where T : struct
        {
            if (!PrimitiveTypeUtils.IsPrimitiveType <T>())
            {
                throw new ArgumentException(Resources.ArgumentExceptionPrimitiveType, nameof(T));
            }

            int elemSize = PrimitiveTypeUtils.SizeOf <T>();
            int numBytes = elemSize * count;

            RangeCheck(index);
            RangeCheck(index + numBytes - 1);

            // Get bytes from binary file data
            byte[] b = new byte[numBytes];
            Marshal.Copy(dataPtr + index, b, 0, numBytes);

            // Create array of values
            T[]    values     = new T[count];
            byte[] valueBytes = new byte[elemSize];
            for (int i = 0; i < count; i++)
            {
                Buffer.BlockCopy(b, i * elemSize, valueBytes, 0, elemSize);
                if (Endianness == Endianness.Big)
                {
                    valueBytes = valueBytes.Reverse().ToArray();
                }

                values[i] = PrimitiveTypeUtils.GetValue <T>(valueBytes);
            }

            return(values);
        }
Example #4
0
        /// <summary>
        /// Creates a <see cref="Primitive{T}"/> at the specified offset in the
        /// <see cref="BinaryData"/>.
        /// </summary>
        public Primitive(BinaryData data, int offset)
        {
            if (!PrimitiveTypeUtils.IsPrimitiveType <T>())
            {
                string msg = Resources.ArgumentExceptionPrimitiveType;
                throw new ArgumentException(msg, nameof(T));
            }

            this.DataSource = data;
            this.Symbol     = new SymbolTable(null, null);
        }
Example #5
0
        internal Primitive(BinaryData data, SymbolTable symbol)
        {
            if (!PrimitiveTypeUtils.IsPrimitiveType <T>())
            {
                string msg = Resources.ArgumentExceptionPrimitiveType;
                throw new ArgumentException(msg, nameof(T));
            }
            if (PrimitiveTypeUtils.SizeOf <T>() > symbol.DataLength)
            {
                string msg = "The type provided cannot be larger than the size of the data field.";
                throw new ArgumentException(msg, nameof(T));
            }

            this.DataSource = data;
            this.Symbol     = symbol;
        }
Example #6
0
        private object DeserializeToProperties(Type t, object o, DeserializationFlags flags, BindingFlags bindFlags)
        {
            PropertyInfo[] allProperties;
            Type           propType;
            bool           isArray;
            Type           elemType;
            bool           isGeneric;
            Type           genType;
            object         val;

            if (!flags.HasFlag(DeserializationFlags.Properties))
            {
                return(o);
            }

            allProperties = t.GetProperties(bindFlags);

            foreach (PropertyInfo p in allProperties)
            {
                propType  = p.PropertyType;
                isArray   = propType.IsArray;
                elemType  = propType.GetElementType();
                isGeneric = propType.IsGenericType;

                if (p.GetSetMethod() == null)
                {
                    continue;
                }

                if (isGeneric && propType.GetGenericTypeDefinition() == typeof(Primitive <>))
                {
                    genType = propType.GetGenericArguments()[0];
                    val     = DeserializePrimitive(p.Name, genType, o, flags);
                }
                else if (isArray)
                {
                    if (PrimitiveTypeUtils.IsPrimitiveType(elemType))
                    {
                        val = DeserializeValueArray(p.Name, elemType, o, flags);
                    }
                    else
                    {
                        val = DeserializeStructureArray(p.Name, elemType, o, flags);
                    }
                }
                else if (PrimitiveTypeUtils.IsPrimitiveType(propType))
                {
                    val = DeserializeValue(p.Name, propType, o, flags);
                }
                else
                {
                    val = DeserializeStructure(p.Name, propType, o, flags);
                }

                if (val != null)
                {
                    p.SetValue(o, val);
                }
            }

            return(o);
        }