Beispiel #1
0
        public void LargeClassTest()
        {
            byte[] array =
            {
                0xFF, 0xFF, 0xFF, 0xFF,
                0xFF, 0xD7, 0xBF, 0xC0,
                0xC9, 0xFD, 0xA3, 0x00,
                0x00, 0x00, 0x00, 0x0D,
            };

            var reader     = new PackedBitReader(array);
            var serializer = new PackedBitSerializer(typeof(BitPackingTest));
            var result     = serializer.Deserialize(reader) as BitPackingTest;

            var trueValues = typeof(BitPackingTest).
                             GetProperties(BindingFlags.Instance | BindingFlags.Public).
                             Where(p => p.Name.StartsWith("ShouldBeTrue")).
                             Select(p => Tuple.Create(p.Name, (bool)p.GetValue(result)));

            Assert.All(trueValues, tv => tv.Item2);

            var falseValues = typeof(BitPackingTest).
                              GetProperties(BindingFlags.Instance | BindingFlags.Public).
                              Where(p => p.Name.StartsWith("ShouldBeFalse")).
                              Select(p => Tuple.Create(p.Name, (bool)p.GetValue(result)));

            Assert.All(falseValues, fv => !fv.Item2);

            Assert.Equal(result.ShouldBe0, (byte)0);
            Assert.Equal(result.ShouldBe0Second, (uint)0);
            Assert.Equal(result.ShouldBe0Third, (byte)0);
            Assert.Equal(result.ShouldBe4, (byte)4);
        }
Beispiel #2
0
        public void ArgumentValidation()
        {
            var reader = new PackedBitReader(sPackedBitWriterOutput);

            string output;

            Assert.ThrowsExact <ArgumentNullException>(() => reader.TryRead(out output, null));
        }
Beispiel #3
0
        public void Decode()
        {
            byte[] bytes    = AlphabetMapper.TranslateMetroidStringToComputerBytes(Encoded);
            byte   checksum = bytes[ChecksumByte - 1];
            byte   shift    = bytes[ShiftByte - 1];

            byte[] decoded = new byte[ChecksumByteCount];
            Buffer.BlockCopy(bytes, 0, decoded, 0, ChecksumByteCount);

            decoded = decoded.RotateLeft(shift);

            byte verifyChecksum = CalculateChecksum(decoded, shift);

            if (verifyChecksum != checksum)
            {
                throw new ChecksumException("Invalid Metroid password");
            }

            // The bitpacking we use assumes that information is packed from the left which means that it makes a big difference for a byte full of bools
            // Information is actually packed from the right of the byte
            // Ergo we just have to flip each byte
            // However first we handle the only 32-bit value (which can't be fixed by a naive flip)
            if (!BitConverter.IsLittleEndian)
            {
                // The game age value comes in little-endian format
                Swap(decoded, GameAgeStartByteIndex, GameAgeEndByteIndex);
                Swap(decoded, GameAgeStartByteIndex + 1, GameAgeEndByteIndex - 1);
            }
            for (int i = 0; i < decoded.Length; i++)
            {
                if (i >= GameAgeStartByteIndex && i <= GameAgeEndByteIndex)
                {
                    continue;
                }
                decoded[i] = decoded[i].ReverseBits();
            }

            var reader     = new PackedBitReader(decoded);
            var serializer = new PackedBitSerializer(typeof(PasswordProperties));

            Properties = serializer.Deserialize(reader) as PasswordProperties;

            Properties.Checksum = checksum;
            Properties.Shift    = shift;
        }
Beispiel #4
0
        public void Basics()
        {
            PackedBitReader reader        = null;
            bool            boolValue     = false;
            sbyte           signedByte    = 0;
            byte            unsignedByte  = 0;
            short           signedShort   = 0;
            ushort          unsignedShort = 0;
            int             signedInt     = 0;
            uint            unsignedInt   = 0;
            long            signedLong    = 0;
            ulong           unsignedLong  = 0;
            string          stringValue   = null;
            double          doubleValue   = 0;
            float           floatValue    = 0;
            bool            success       = false;

            Assert.DoesNotThrow(() => reader = new PackedBitReader(sPackedBitWriterOutput));

            Assert.DoesNotThrow(() => success = reader.TryRead(out boolValue));
            Assert.True(success);
            Assert.True(boolValue);

            Assert.DoesNotThrow(() => success = reader.TryRead(out boolValue));
            Assert.True(success);
            Assert.False(boolValue);

            Assert.DoesNotThrow(() => success = reader.TryRead(out boolValue));
            Assert.True(success);
            Assert.False(boolValue);

            Assert.DoesNotThrow(() => success = reader.TryRead(out boolValue));
            Assert.True(success);
            Assert.True(boolValue);

            Assert.DoesNotThrow(() => success = reader.TryRead(out boolValue));
            Assert.True(success);
            Assert.True(boolValue);

            Assert.DoesNotThrow(() => success = reader.TryRead(out boolValue));
            Assert.True(success);
            Assert.True(boolValue);

            Assert.DoesNotThrow(() => success = reader.TryRead(out boolValue));
            Assert.True(success);
            Assert.True(boolValue);

            Assert.DoesNotThrow(() => success = reader.TryRead(out boolValue));
            Assert.True(success);
            Assert.False(boolValue);

            Assert.DoesNotThrow(() => success = reader.TryRead(out boolValue));
            Assert.True(success);
            Assert.False(boolValue);

            Assert.DoesNotThrow(() => success = reader.TryRead(out boolValue));
            Assert.True(success);
            Assert.True(boolValue);

            Assert.DoesNotThrow(() => success = reader.TryRead(4, out signedByte));
            Assert.True(success);
            Assert.Equal(signedByte, (sbyte)3);

            Assert.DoesNotThrow(() => success = reader.TryRead(4, out unsignedByte));
            Assert.True(success);
            Assert.Equal(unsignedByte, (byte)4);

            Assert.DoesNotThrow(() => success = reader.TryRead(6, out signedShort));
            Assert.True(success);
            Assert.Equal(signedShort, (short)13);

            Assert.DoesNotThrow(() => success = reader.TryRead(6, out unsignedShort));
            Assert.True(success);
            Assert.Equal(unsignedShort, (ushort)14);

            Assert.DoesNotThrow(() => success = reader.TryRead(6, out signedInt));
            Assert.True(success);
            Assert.Equal(signedInt, (int)23);

            Assert.DoesNotThrow(() => success = reader.TryRead(6, out unsignedInt));
            Assert.True(success);
            Assert.Equal(unsignedInt, (uint)24);

            Assert.DoesNotThrow(() => success = reader.TryRead(8, out signedLong));
            Assert.True(success);
            Assert.Equal(signedLong, (long)33);

            Assert.DoesNotThrow(() => success = reader.TryRead(8, out unsignedLong));
            Assert.True(success);
            Assert.Equal(unsignedLong, (ulong)34);

            Assert.DoesNotThrow(() => success = reader.TryRead(out boolValue));
            Assert.True(success);
            Assert.False(boolValue);

            Assert.DoesNotThrow(() => success = reader.TryRead(out boolValue));
            Assert.True(success);
            Assert.True(boolValue);

            Assert.DoesNotThrow(() => success = reader.TryRead(out boolValue));
            Assert.True(success);
            Assert.True(boolValue);

            Assert.DoesNotThrow(() => success = reader.TryRead(out boolValue));
            Assert.True(success);
            Assert.True(boolValue);

            Assert.DoesNotThrow(() => success = reader.TryRead(out boolValue));
            Assert.True(success);
            Assert.True(boolValue);

            Assert.DoesNotThrow(() => success = reader.TryRead(out boolValue));
            Assert.True(success);
            Assert.False(boolValue);

            Assert.DoesNotThrow(() => success = reader.TryRead(out boolValue));
            Assert.True(success);
            Assert.False(boolValue);

            Assert.DoesNotThrow(() => success = reader.TryRead(out boolValue));
            Assert.True(success);
            Assert.True(boolValue);

            Assert.DoesNotThrow(() => success = reader.TryReadSigned(4, out signedByte));
            Assert.True(success);
            Assert.Equal(signedByte, (sbyte)-3);

            Assert.DoesNotThrow(() => success = reader.TryRead(out doubleValue));
            Assert.True(success);
            Assert.Equal(doubleValue, 2.4d);

            Assert.DoesNotThrow(() => success = reader.TryRead(out floatValue));
            Assert.True(success);
            Assert.Equal(floatValue, 88.4f);

            Assert.DoesNotThrow(() => success = reader.TryReadSigned(6, out signedShort));
            Assert.True(success);
            Assert.Equal(signedShort, (short)-13);

            Assert.DoesNotThrow(() => success = reader.TryReadSigned(6, out signedInt));
            Assert.True(success);
            Assert.Equal(signedInt, (int)-23);

            Assert.DoesNotThrow(() => success = reader.TryReadSigned(8, out signedLong));
            Assert.True(success);
            Assert.Equal(signedLong, (long)-33);

            Assert.DoesNotThrow(() => success = reader.TryRead(out stringValue));
            Assert.True(success);
            Assert.Equal(stringValue, "datà");

            Assert.DoesNotThrow(() => success = reader.TryRead(out stringValue, Encoding.ASCII));
            Assert.True(success);
            Assert.Equal(stringValue, "data");

            Assert.DoesNotThrow(() => success = reader.TryRead(2, out signedByte));
            Assert.True(success);
            Assert.Equal(signedByte, (sbyte)3);

            Assert.DoesNotThrow(() => success = reader.TryRead(out boolValue));
            Assert.False(success);
        }
Beispiel #5
0
 private void ReadImperativeBits(PackedBitReader reader, object value, IEnumerable <PropertyInfo> properties, Func <PropertyInfo, BitPair> getBitPair)
 {
     foreach (PropertyInfo prop in properties)
     {
         if (prop.PropertyType == typeof(bool))
         {
             prop.SetValue(value, reader.ReadBool(), null);
         }
         else
         {
             BitPair read     = getBitPair(prop);
             int     bitRange = read.Count;
             if (read.Signed)
             {
                 if (prop.PropertyType == typeof(sbyte))
                 {
                     prop.SetValue(value, reader.ReadSignedInt8(bitRange), null);
                 }
                 else if (prop.PropertyType == typeof(short))
                 {
                     prop.SetValue(value, reader.ReadSignedInt16(bitRange), null);
                 }
                 else if (prop.PropertyType == typeof(int))
                 {
                     prop.SetValue(value, reader.ReadSignedInt32(bitRange), null);
                 }
                 else if (prop.PropertyType == typeof(long))
                 {
                     prop.SetValue(value, reader.ReadSignedInt64(bitRange), null);
                 }
                 else
                 {
                     throw CodePath.Unreachable;
                 }
             }
             else
             {
                 if (prop.PropertyType == typeof(sbyte))
                 {
                     prop.SetValue(value, reader.ReadInt8(bitRange), null);
                 }
                 else if (prop.PropertyType == typeof(short))
                 {
                     prop.SetValue(value, reader.ReadInt16(bitRange), null);
                 }
                 else if (prop.PropertyType == typeof(int))
                 {
                     prop.SetValue(value, reader.ReadInt32(bitRange), null);
                 }
                 else if (prop.PropertyType == typeof(long))
                 {
                     prop.SetValue(value, reader.ReadInt64(bitRange), null);
                 }
                 else if (prop.PropertyType == typeof(byte))
                 {
                     prop.SetValue(value, reader.ReadUInt8(bitRange), null);
                 }
                 else if (prop.PropertyType == typeof(ushort))
                 {
                     prop.SetValue(value, reader.ReadUInt16(bitRange), null);
                 }
                 else if (prop.PropertyType == typeof(uint))
                 {
                     prop.SetValue(value, reader.ReadUInt32(bitRange), null);
                 }
                 else if (prop.PropertyType == typeof(ulong))
                 {
                     prop.SetValue(value, reader.ReadUInt64(bitRange), null);
                 }
                 else
                 {
                     throw CodePath.Unreachable;
                 }
             }
         }
     }
 }
Beispiel #6
0
        /// <summary>
        /// Deserializes a PackedBitReader stream to an object.
        /// </summary>
        /// <param name="reader">The stream to deserialize.</param>
        /// <returns>An object populated by the stream.</returns>
        /// <exception cref="ArgumentNullException"><paramref name="reader" /> is null.</exception>
        public object Deserialize(PackedBitReader reader)
        {
            if (object.ReferenceEquals(reader, null))
            {
                throw new ArgumentNullException(nameof(reader));
            }

            object ret = Activator.CreateInstance(SerializeType);

            if (ImplementsInterface)
            {
                ((IPackedBitSerializable)ret).Deserialize(reader);
            }
            else
            {
                var properties = GetProperties(SerializeType);

                if (HasOrder)
                {
                    properties = properties.OrderBy(p => p.GetCustomAttribute <PackedBitOrderAttribute>().LowBit);
                    ReadImperativeBits(reader, ret, properties, (prop) => {
                        PackedBitOrderAttribute bitOrderAttr = prop.GetCustomAttribute <PackedBitOrderAttribute>();
                        return(new BitPair()
                        {
                            Count = bitOrderAttr.BitCount,
                            Signed = bitOrderAttr.Signed,
                        });
                    });
                }
                else if (HasRange)
                {
                    properties = properties.OrderBy(p => p.GetCustomAttribute <PackedBitRangeAttribute>().LowBit);
                    ReadImperativeBits(reader, ret, properties, (prop) => {
                        PackedBitRangeAttribute bitRangeAttr = prop.GetCustomAttribute <PackedBitRangeAttribute>();
                        return(new BitPair()
                        {
                            Count = bitRangeAttr.HasHighBit ?
                                    bitRangeAttr.HighBit - (bitRangeAttr.LowBit - 1) :
                                    1,
                            Signed = bitRangeAttr.Signed,
                        });
                    });
                }
                else if (HasSize)
                {
                    ReadImperativeBits(reader, ret, properties, (prop) => {
                        PackedBitSizeAttribute bitSizeAttr = prop.GetCustomAttribute <PackedBitSizeAttribute>();
                        return(new BitPair()
                        {
                            Count = bitSizeAttr.BitCount,
                            Signed = bitSizeAttr.Signed,
                        });
                    });
                }
                else
                {
                    throw CodePath.Unreachable;
                }
            }
            return(ret);
        }
Beispiel #7
0
 public void Deserialize(PackedBitReader reader)
 {
     throw new NotImplementedException();
 }