Exemplo n.º 1
0
 protected BinaryMember(Type type, BinaryDataAttribute attribute, Type accessorType)
 {
     Attribute   = attribute;
     IsValueType = accessorType.IsValueType;
     Type        = type;
     IsPrimitive = type.IsPrimitive;
 }
Exemplo n.º 2
0
        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));
        }
Exemplo n.º 3
0
        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);
        }
Exemplo n.º 4
0
 public BinaryProperty(PropertyInfo propertyInfo, BinaryDataAttribute attribute, Type accessorType)
     : base(propertyInfo.PropertyType, attribute, accessorType)
 {
     _propertyInfo = propertyInfo;
 }
Exemplo n.º 5
0
        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);
        }
Exemplo n.º 6
0
        public T ReadValue <T>(int offset, int length, BinaryDataAttribute attribute = null)
        {
            var buffer = Binary.ReadBytes(offset, length);

            return((T)ReadValue(buffer, typeof(T), attribute));
        }
Exemplo n.º 7
0
 public BinaryField(FieldInfo fieldInfo, BinaryDataAttribute attribute, Type accessorType)
     : base(fieldInfo.FieldType, attribute, accessorType)
 {
     _fieldInfo = fieldInfo;
 }