Beispiel #1
0
        private void SetValue(SettingEntryType type, object value)
        {
            //TODO: what if new length != old
            byte[] buffer;
            switch (type)
            {
            case SettingEntryType.UnicodeString:
            case SettingEntryType.Binary:
                buffer = type == SettingEntryType.UnicodeString
                                     ? Encoding.BigEndianUnicode.GetBytes((string)value)
                                     : (byte[])value;
                BinaryValue = buffer;
                SetValue(BinaryValue.Length);
                break;

            case SettingEntryType.DateTime:
                buffer = ByteArrayExtensions.FromDateTime((DateTime)value);
                Buffer.BlockCopy(buffer, 0, NumericValue, 0, 8);
                break;

            case SettingEntryType.Int32:
                SetNumericValue(BitConverter.GetBytes((int)value));
                break;

            case SettingEntryType.Int64:
                SetNumericValue(BitConverter.GetBytes((long)value));
                break;

            case SettingEntryType.Float:
                SetNumericValue(BitConverter.GetBytes((float)value));
                break;

            case SettingEntryType.Double:
                SetNumericValue(BitConverter.GetBytes((double)value));
                break;

            default:
                throw new NotSupportedException("Invalid Type: " + type);
            }
        }
        public void WritePropertyValue(string propertyName, object value)
        {
            var valueType = value.GetType();
            var loc       = _offsetTable[propertyName];
            var property  = GetType().GetProperty(propertyName, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
            var attribute = property.GetAttribute <BinaryDataAttribute>();

            byte[] buffer;
            var    endian   = false;
            var    noresize = false;

            if (attribute.StringReadOptions == StringReadOptions.NullTerminated)
            {
                buffer = attribute.Encoding.GetBytes((string)value + "\0");
                var length = buffer.Length - 2;
                var diff   = length - loc.Length;

                _offsetTable.ShiftOffsetsFrom(propertyName, diff);
                var oldpos = loc.Offset + loc.Length;
                Binary.MoveBytes(oldpos, oldpos + diff, Binary.Length - oldpos);
                if (diff < 0)
                {
                    Binary.Resize(Binary.Length + diff);
                }
                loc.Length = length;

                noresize = true;
            }
            else if (attribute.StringReadOptions == StringReadOptions.ID)
            {
                buffer = ((string)value).FromHex();
                Array.Reverse(buffer); //TODO: support endian in FromHex
            }
            else if (value is string)
            {
                buffer = attribute.Encoding.GetBytes((string)value);
            }
            else if (value is DateTime)
            {
                buffer = ByteArrayExtensions.FromDateTime((DateTime)value);
            }
            else if (value is Version)
            {
                buffer = ByteArrayExtensions.FromVersion((Version)value);
            }
            else if (valueType.IsArray)
            {
                var elementType = valueType.GetElementType();
                if (elementType == typeof(byte))
                {
                    buffer = (byte[])value;
                }
                else if (elementType.IsEnum)
                {
                    buffer = new byte[loc.Length];
                    var array = (Array)value;
                    for (var i = 0; i < loc.Length; i++)
                    {
                        buffer[i] = Convert.ToByte(array.GetValue(i));
                    }
                }
                else
                {
                    throw new NotSupportedException("Invalid array type: " + valueType);
                }
            }
            else
            {
                if (value is Enum)
                {
                    valueType = Enum.GetUnderlyingType(valueType);
                }

                if (valueType == typeof(byte))
                {
                    buffer = new[] { (byte)value }
                }
                ;
                else if (valueType == typeof(short))
                {
                    buffer = BitConverter.GetBytes((short)value);
                }
                else if (valueType == typeof(ushort))
                {
                    buffer = BitConverter.GetBytes((ushort)value);
                }
                else if (valueType == typeof(int))
                {
                    buffer = BitConverter.GetBytes((int)value);
                }
                else if (valueType == typeof(uint))
                {
                    buffer = BitConverter.GetBytes((uint)value);
                }
                else if (valueType == typeof(long))
                {
                    buffer = BitConverter.GetBytes((long)value);
                }
                else if (valueType == typeof(ulong))
                {
                    buffer = BitConverter.GetBytes((ulong)value);
                }
                else
                {
                    throw new NotSupportedException("Unknown value type: " + valueType.Name);
                }
                endian = true;
            }

            if (!noresize)
            {
                Array.Resize(ref buffer, loc.Length);
            }
            if (endian && attribute.EndianType == EndianType.BigEndian)
            {
                Array.Reverse(buffer);
            }

            Binary.WriteBytes(loc.Offset, buffer, 0, loc.Length);
        }