protected BinaryMember(Type type, BinaryDataAttribute attribute, Type accessorType) { Attribute = attribute; IsValueType = accessorType.IsValueType; Type = type; IsPrimitive = type.IsPrimitive; }
public object ReadPropertyValue(string propertyName, BinaryDataAttribute attribute = null) { var loc = _offsetTable[propertyName]; //if (loc == null) return BypassCommand.Instance; var property = GetType().GetProperty(propertyName, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); attribute = attribute ?? property.GetAttribute <BinaryDataAttribute>(); byte[] buffer; if (attribute.StringReadOptions == StringReadOptions.NullTerminated && loc.Length == 1) { buffer = Binary.ReadBytes(loc.Offset); var encoded = attribute.Encoding.GetChars(buffer); var i = 0; while (i < encoded.Length && encoded[i] != 0) { i++; } if (i < encoded.Length) { buffer = attribute.Encoding.GetBytes(encoded.Take(i).ToArray()); var diff = buffer.Length + 2 - loc.Length; loc.Length = buffer.Length; _offsetTable.ShiftOffsetsFrom(propertyName, diff); } else { //throw new Exception("upsz, nem volt null"); } } else { buffer = Binary.ReadBytes(loc.Offset, loc.Length); } return(ReadValue(buffer, property.PropertyType, attribute)); }
private static object ReadPropertyValue(PropertyInfo property, BinaryDataAttribute attribute, Stream stream) { var propertyType = property.PropertyType; int length; if (ModelInterface.IsAssignableFrom(propertyType)) { return(ReadBlock(stream, propertyType, propertyType, null, null)); } if (propertyType.IsArray && ModelInterface.IsAssignableFrom(propertyType.GetElementType())) { if (!attribute.Length.HasValue) { throw new NotSupportedException("Arrays must have length specified"); } var elementType = propertyType.GetElementType(); length = attribute.Length.Value; var array = Array.CreateInstance(elementType, length); for (var i = 0; i < length; i++) { array.SetValue(ReadBlock(stream, elementType, elementType, null, null), i); } return(array); } var valueType = propertyType.IsEnum ? Enum.GetUnderlyingType(propertyType) : propertyType; int?valueSize; if (attribute.Length.HasValue) { length = attribute.Length.Value; valueSize = valueType.IsValueType ? Marshal.SizeOf(valueType) : (int?)null; } else if (valueType == typeof(DateTime)) { valueSize = length = 0; } else if (valueType.IsValueType) { valueSize = length = Marshal.SizeOf(valueType); } else if (attribute.StringReadOptions == StringReadOptions.NullTerminated) { length = 64; valueSize = null; } else { throw new NotSupportedException("In case of reference types the length property is mandatory!"); } //if (attribute.SkipBytes > 0) stream.Position += attribute.SkipBytes; var byteList = new List <byte>(); var readMore = false; do { var buffer = stream.ReadBytes(length); if (attribute.StringReadOptions == StringReadOptions.NullTerminated) { var encoded = attribute.Encoding.GetChars(buffer); var i = 0; while (i < encoded.Length && encoded[i] != 0) { i++; } if (i < encoded.Length) { var text = attribute.Encoding.GetBytes(encoded.Take(i).ToArray()); byteList.AddRange(text); stream.Position -= (length - text.Length - 2); readMore = false; } else { byteList.AddRange(buffer); readMore = true; } } else { byteList.AddRange(buffer); } } while (readMore); var bytes = byteList.ToArray(); object value; if (propertyType.IsArray && propertyType.GetElementType() == typeof(byte)) { if (attribute.EndianType == EndianType.SwapBytesBy4 || attribute.EndianType == EndianType.SwapBytesBy8) { bytes.SwapBytes((int)attribute.EndianType); } value = bytes; } else if (valueType == typeof(byte)) { value = bytes[0]; } else if (valueType == typeof(string)) { switch (attribute.StringReadOptions) { case StringReadOptions.AutoTrim: var encoded = attribute.Encoding.GetChars(bytes); var i = 0; while (i < encoded.Length && encoded[i] != 0) { i++; } value = attribute.Encoding.GetString(attribute.Encoding.GetBytes(encoded.Take(i).ToArray())); break; case StringReadOptions.ID: value = bytes.ToHex(); break; case StringReadOptions.NullTerminated: case StringReadOptions.Default: value = attribute.Encoding.GetString(bytes); break; default: throw new NotSupportedException("Invalid StringReadOptions value: " + attribute.StringReadOptions); } } else if (valueType == typeof(DateTime)) { var high = stream.ReadUInt(); var low = stream.ReadUInt(); long time = ((long)high << 32) + low; value = DateTime.FromFileTime(time); } else { if (attribute.EndianType == EndianType.BigEndian) { Array.Reverse(bytes); } if (valueSize.HasValue && length < valueSize) { Array.Resize(ref bytes, valueSize.Value); } if (valueType == typeof(short)) { value = BitConverter.ToInt16(bytes, 0); } else if (valueType == typeof(ushort)) { value = BitConverter.ToUInt16(bytes, 0); } else if (valueType == typeof(int)) { value = BitConverter.ToInt32(bytes, 0); } else if (valueType == typeof(uint)) { value = BitConverter.ToUInt32(bytes, 0); } else if (valueType == typeof(long)) { value = BitConverter.ToInt64(bytes, 0); } else if (valueType == typeof(ulong)) { value = BitConverter.ToUInt64(bytes, 0); } else { throw new NotSupportedException("Invalid value type: " + valueType); } } return(value); }
public BinaryProperty(PropertyInfo propertyInfo, BinaryDataAttribute attribute, Type accessorType) : base(propertyInfo.PropertyType, attribute, accessorType) { _propertyInfo = propertyInfo; }
private static object ReadValue(byte[] buffer, Type propertyType, BinaryDataAttribute attribute = null) { var valueType = propertyType.IsEnum ? Enum.GetUnderlyingType(propertyType) : propertyType; if (propertyType.IsArray) { var elementType = propertyType.GetElementType(); if (elementType == typeof(byte)) { if (attribute.EndianType == EndianType.SwapBytesBy4 || attribute.EndianType == EndianType.SwapBytesBy8) { buffer.SwapBytes((int)attribute.EndianType); } return(buffer); } if (elementType.IsEnum) { var array = Array.CreateInstance(propertyType.GetElementType(), buffer.Length); for (var i = 0; i < buffer.Length; i++) { array.SetValue(Enum.ToObject(elementType, buffer[i]), i); } return(array); } throw new NotSupportedException("Invalid array type: " + propertyType); } if (valueType == typeof(byte)) { return(buffer[0]); } if (valueType == typeof(string)) { switch (attribute.StringReadOptions) { case StringReadOptions.AutoTrim: return(ByteArrayExtensions.ToTrimmedString(buffer, attribute.Encoding)); case StringReadOptions.ID: return(buffer.ToHex()); case StringReadOptions.NullTerminated: case StringReadOptions.Default: return(attribute.Encoding.GetString(buffer)); default: throw new NotSupportedException("Invalid StringReadOptions value: " + attribute.StringReadOptions); } } if (valueType == typeof(DateTime)) { return(ByteArrayExtensions.ToDateTime(buffer)); } if (attribute.EndianType == EndianType.BigEndian) { Array.Reverse(buffer); } var valueSize = valueType.IsValueType ? Marshal.SizeOf(valueType) : (int?)null; if (valueSize.HasValue && buffer.Length < valueSize) { Array.Resize(ref buffer, valueSize.Value); } if (valueType == typeof(Version)) { return(ByteArrayExtensions.ToVersion(buffer)); } if (valueType == typeof(short)) { return(BitConverter.ToInt16(buffer, 0)); } if (valueType == typeof(ushort)) { return(BitConverter.ToUInt16(buffer, 0)); } if (valueType == typeof(int)) { return(BitConverter.ToInt32(buffer, 0)); } if (valueType == typeof(uint)) { return(BitConverter.ToUInt32(buffer, 0)); } if (valueType == typeof(long)) { return(BitConverter.ToInt64(buffer, 0)); } if (valueType == typeof(ulong)) { return(BitConverter.ToUInt64(buffer, 0)); } throw new NotSupportedException("Invalid value type: " + valueType); }
public T ReadValue <T>(int offset, int length, BinaryDataAttribute attribute = null) { var buffer = Binary.ReadBytes(offset, length); return((T)ReadValue(buffer, typeof(T), attribute)); }
public BinaryField(FieldInfo fieldInfo, BinaryDataAttribute attribute, Type accessorType) : base(fieldInfo.FieldType, attribute, accessorType) { _fieldInfo = fieldInfo; }