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