public void ToXXX()
        {
            var sut = new BigEndianBitConverter();

            var data = new byte[] { 0, 0, 0, 0, 0, 0, 0, 3 };

            Check.That(sut.ToBoolean(data, 0)).IsFalse();
            Check.That(sut.ToBoolean(data, 7)).IsTrue();
            Check.That(sut.ToChar(data, 0)).IsEqualTo('\0');
            Check.That(sut.ToChar(data, 6)).IsEqualTo('\u0003');
            Check.That(sut.ToInt16(data, 0)).IsEqualTo(0);
            Check.That(sut.ToInt16(data, 6)).IsEqualTo(3);
            Check.That(sut.ToUInt16(data, 0)).IsEqualTo(0u);
            Check.That(sut.ToUInt16(data, 6)).IsEqualTo(3u);
            Check.That(sut.ToInt32(data, 0)).IsEqualTo(0);
            Check.That(sut.ToInt32(data, 4)).IsEqualTo(3);
            Check.That(sut.ToUInt32(data, 0)).IsEqualTo(0u);
            Check.That(sut.ToUInt32(data, 4)).IsEqualTo(3u);
            Check.That(sut.ToInt64(data, 0)).IsEqualTo(3L);
            Check.That(sut.ToUInt64(data, 0)).IsEqualTo(3UL);

            data = new byte[] { 0x41, 0x20, 0, 0, 0, 0, 0, 0 };
            Check.That(sut.ToSingle(data, 0)).IsEqualTo(10.0f);
            Check.That(sut.ToSingle(data, 4)).IsEqualTo(0.0f);

            data = new byte[] { 0x40, 0x24, 0, 0, 0, 0, 0, 0 };
            Check.That(sut.ToDouble(data, 0)).IsEqualTo(10.0);
        }
Beispiel #2
0
        public void BigEndianBitConverter_Double()
        {
            const int n = sizeof(Double);

            const Double pos  = Math.PI;
            const Double zero = 0;
            const Double neg  = -pos;

            var posRepr = GetCanonicalRepresentation(pos);
            var negRepr = GetCanonicalRepresentation(neg);

            // --------------------------------------------------------------

            var buffer = new byte[n];

            BigEndianBitConverter.FillBytes(pos, buffer);
            Assert.IsTrue(buffer.SequenceEqual(posRepr));
            Assert.IsTrue(BigEndianBitConverter.GetBytes(pos).SequenceEqual(buffer));
            Assert.AreEqual(pos, BigEndianBitConverter.ToDouble(buffer));

            BigEndianBitConverter.FillBytes(zero, buffer);
            Assert.IsTrue(buffer.SequenceEqual(new byte[n]));
            Assert.IsTrue(BigEndianBitConverter.GetBytes(zero).SequenceEqual(buffer));
            Assert.AreEqual(zero, BigEndianBitConverter.ToDouble(buffer));

            BigEndianBitConverter.FillBytes(neg, buffer);
            Assert.IsTrue(buffer.SequenceEqual(negRepr));
            Assert.IsTrue(BigEndianBitConverter.GetBytes(neg).SequenceEqual(buffer));
            Assert.AreEqual(neg, BigEndianBitConverter.ToDouble(buffer));
        }
Beispiel #3
0
        public static Item DecodeItem(byte[] data, BigEndianBitConverter converter, int offset = 0)
        {
            int    spriteLength = converter.ToInt32(data, offset);
            string sprite       = System.Text.Encoding.UTF8.GetString(data, 4 + offset, spriteLength);

            int    nameLength = converter.ToInt32(data, 4 + spriteLength + offset);
            string name       = System.Text.Encoding.UTF8.GetString(data, 8 + spriteLength + offset, nameLength);

            int    descriptionLength = converter.ToInt32(data, 8 + spriteLength + nameLength + offset);
            string description       = System.Text.Encoding.UTF8.GetString(data, 12 + spriteLength + nameLength + offset, descriptionLength);

            int    typeLength = converter.ToInt32(data, 12 + spriteLength + nameLength + descriptionLength + offset);
            string type       = System.Text.Encoding.UTF8.GetString(data, 16 + spriteLength + nameLength + descriptionLength + offset, typeLength);

            int maxStack = converter.ToInt32(data, 16 + spriteLength + nameLength + descriptionLength + typeLength + offset);
            int quantity = converter.ToInt32(data, 20 + spriteLength + nameLength + descriptionLength + typeLength + offset);

            if (type == "weapon")
            {
                int    weaponClassLength = converter.ToInt32(data, 24 + spriteLength + nameLength + descriptionLength + typeLength + offset);
                string weaponClass       = System.Text.Encoding.UTF8.GetString(data, 28 + spriteLength + nameLength + descriptionLength + typeLength + offset, weaponClassLength);

                double damage = converter.ToDouble(data, 28 + spriteLength + nameLength + descriptionLength + typeLength + weaponClassLength + offset);

                int    damageTypeLength = converter.ToInt32(data, 36 + spriteLength + nameLength + descriptionLength + typeLength + weaponClassLength + offset);
                string damageType       = System.Text.Encoding.UTF8.GetString(data, 40 + spriteLength + nameLength + descriptionLength + typeLength + weaponClassLength + offset, damageTypeLength);

                return(new Weapon(null, sprite, name, description, type, weaponClass, damage, damageType));
            }
            else
            {
                return(new Item(null, sprite, name, description, type, maxStack, quantity));
            }
        }
Beispiel #4
0
        // TODO: Decode native nvlist
        static bool DecodeNvList(byte[] nvlist, out Dictionary <string, NVS_Item> decodedNvList, bool xdr,
                                 bool littleEndian)
        {
            decodedNvList = new Dictionary <string, NVS_Item>();

            if (nvlist == null || nvlist.Length < 16)
            {
                return(false);
            }

            if (!xdr)
            {
                return(false);
            }

            int offset = 8;

            while (offset < nvlist.Length)
            {
                NVS_Item item    = new NVS_Item();
                int      currOff = offset;

                item.encodedSize = BigEndianBitConverter.ToUInt32(nvlist, offset);

                // Finished
                if (item.encodedSize == 0)
                {
                    break;
                }

                offset          += 4;
                item.decodedSize = BigEndianBitConverter.ToUInt32(nvlist, offset);
                offset          += 4;
                uint nameLength = BigEndianBitConverter.ToUInt32(nvlist, offset);
                offset += 4;
                if (nameLength % 4 > 0)
                {
                    nameLength += 4 - nameLength % 4;
                }
                byte[] nameBytes = new byte[nameLength];
                Array.Copy(nvlist, offset, nameBytes, 0, nameLength);
                item.name     = StringHandlers.CToString(nameBytes);
                offset       += (int)nameLength;
                item.dataType = (NVS_DataTypes)BigEndianBitConverter.ToUInt32(nvlist, offset);
                offset       += 4;
                item.elements = BigEndianBitConverter.ToUInt32(nvlist, offset);
                offset       += 4;

                if (item.elements == 0)
                {
                    decodedNvList.Add(item.name, item);
                    continue;
                }

                switch (item.dataType)
                {
                case NVS_DataTypes.DATA_TYPE_BOOLEAN:
                case NVS_DataTypes.DATA_TYPE_BOOLEAN_ARRAY:
                case NVS_DataTypes.DATA_TYPE_BOOLEAN_VALUE:
                    if (item.elements > 1)
                    {
                        bool[] boolArray = new bool[item.elements];
                        for (int i = 0; i < item.elements; i++)
                        {
                            uint temp = BigEndianBitConverter.ToUInt32(nvlist, offset);
                            boolArray[i] = temp > 0;
                            offset      += 4;
                        }

                        item.value = boolArray;
                    }
                    else
                    {
                        uint temp = BigEndianBitConverter.ToUInt32(nvlist, offset);
                        item.value = temp > 0;
                        offset    += 4;
                    }

                    break;

                case NVS_DataTypes.DATA_TYPE_BYTE:
                case NVS_DataTypes.DATA_TYPE_BYTE_ARRAY:
                case NVS_DataTypes.DATA_TYPE_UINT8:
                case NVS_DataTypes.DATA_TYPE_UINT8_ARRAY:
                    if (item.elements > 1)
                    {
                        byte[] byteArray = new byte[item.elements];
                        Array.Copy(nvlist, offset, byteArray, 0, item.elements);
                        offset += (int)item.elements;
                        if (item.elements % 4 > 0)
                        {
                            offset += 4 - (int)(item.elements % 4);
                        }
                        item.value = byteArray;
                    }
                    else
                    {
                        item.value = nvlist[offset];
                        offset    += 4;
                    }

                    break;

                case NVS_DataTypes.DATA_TYPE_DOUBLE:
                    if (item.elements > 1)
                    {
                        double[] doubleArray = new double[item.elements];
                        for (int i = 0; i < item.elements; i++)
                        {
                            double temp = BigEndianBitConverter.ToDouble(nvlist, offset);
                            doubleArray[i] = temp;
                            offset        += 8;
                        }

                        item.value = doubleArray;
                    }
                    else
                    {
                        item.value = BigEndianBitConverter.ToDouble(nvlist, offset);
                        offset    += 8;
                    }

                    break;

                case NVS_DataTypes.DATA_TYPE_HRTIME:
                    if (item.elements > 1)
                    {
                        DateTime[] hrtimeArray = new DateTime[item.elements];
                        for (int i = 0; i < item.elements; i++)
                        {
                            DateTime temp =
                                DateHandlers.UnixHrTimeToDateTime(BigEndianBitConverter.ToUInt64(nvlist, offset));
                            hrtimeArray[i] = temp;
                            offset        += 8;
                        }

                        item.value = hrtimeArray;
                    }
                    else
                    {
                        item.value =
                            DateHandlers.UnixHrTimeToDateTime(BigEndianBitConverter.ToUInt64(nvlist, offset));
                        offset += 8;
                    }

                    break;

                case NVS_DataTypes.DATA_TYPE_INT16:
                case NVS_DataTypes.DATA_TYPE_INT16_ARRAY:
                    if (item.elements > 1)
                    {
                        short[] shortArray = new short[item.elements];
                        for (int i = 0; i < item.elements; i++)
                        {
                            short temp = BigEndianBitConverter.ToInt16(nvlist, offset);
                            shortArray[i] = temp;
                            offset       += 4;
                        }

                        item.value = shortArray;
                    }
                    else
                    {
                        item.value = BigEndianBitConverter.ToInt16(nvlist, offset);
                        offset    += 4;
                    }

                    break;

                case NVS_DataTypes.DATA_TYPE_INT32:
                case NVS_DataTypes.DATA_TYPE_INT32_ARRAY:
                    if (item.elements > 1)
                    {
                        int[] intArray = new int[item.elements];
                        for (int i = 0; i < item.elements; i++)
                        {
                            int temp = BigEndianBitConverter.ToInt32(nvlist, offset);
                            intArray[i] = temp;
                            offset     += 4;
                        }

                        item.value = intArray;
                    }
                    else
                    {
                        item.value = BigEndianBitConverter.ToInt32(nvlist, offset);
                        offset    += 4;
                    }

                    break;

                case NVS_DataTypes.DATA_TYPE_INT64:
                case NVS_DataTypes.DATA_TYPE_INT64_ARRAY:
                    if (item.elements > 1)
                    {
                        long[] longArray = new long[item.elements];
                        for (int i = 0; i < item.elements; i++)
                        {
                            long temp = BigEndianBitConverter.ToInt64(nvlist, offset);
                            longArray[i] = temp;
                            offset      += 8;
                        }

                        item.value = longArray;
                    }
                    else
                    {
                        item.value = BigEndianBitConverter.ToInt64(nvlist, offset);
                        offset    += 8;
                    }

                    break;

                case NVS_DataTypes.DATA_TYPE_INT8:
                case NVS_DataTypes.DATA_TYPE_INT8_ARRAY:
                    if (item.elements > 1)
                    {
                        sbyte[] sbyteArray = new sbyte[item.elements];
                        for (int i = 0; i < item.elements; i++)
                        {
                            sbyte temp = (sbyte)nvlist[offset];
                            sbyteArray[i] = temp;
                            offset++;
                        }

                        item.value = sbyteArray;
                        if (sbyteArray.Length % 4 > 0)
                        {
                            offset += 4 - sbyteArray.Length % 4;
                        }
                    }
                    else
                    {
                        item.value = BigEndianBitConverter.ToInt64(nvlist, offset);
                        offset    += 4;
                    }

                    break;

                case NVS_DataTypes.DATA_TYPE_STRING:
                case NVS_DataTypes.DATA_TYPE_STRING_ARRAY:
                    if (item.elements > 1)
                    {
                        string[] stringArray = new string[item.elements];
                        for (int i = 0; i < item.elements; i++)
                        {
                            uint strLength = BigEndianBitConverter.ToUInt32(nvlist, offset);
                            offset += 4;
                            byte[] strBytes = new byte[strLength];
                            Array.Copy(nvlist, offset, strBytes, 0, strLength);
                            stringArray[i] = StringHandlers.CToString(strBytes);
                            offset        += (int)strLength;
                            if (strLength % 4 > 0)
                            {
                                offset += 4 - (int)(strLength % 4);
                            }
                        }

                        item.value = stringArray;
                    }
                    else
                    {
                        uint strLength = BigEndianBitConverter.ToUInt32(nvlist, offset);
                        offset += 4;
                        byte[] strBytes = new byte[strLength];
                        Array.Copy(nvlist, offset, strBytes, 0, strLength);
                        item.value = StringHandlers.CToString(strBytes);
                        offset    += (int)strLength;
                        if (strLength % 4 > 0)
                        {
                            offset += 4 - (int)(strLength % 4);
                        }
                    }

                    break;

                case NVS_DataTypes.DATA_TYPE_UINT16:
                case NVS_DataTypes.DATA_TYPE_UINT16_ARRAY:
                    if (item.elements > 1)
                    {
                        ushort[] ushortArray = new ushort[item.elements];
                        for (int i = 0; i < item.elements; i++)
                        {
                            ushort temp = BigEndianBitConverter.ToUInt16(nvlist, offset);
                            ushortArray[i] = temp;
                            offset        += 4;
                        }

                        item.value = ushortArray;
                    }
                    else
                    {
                        item.value = BigEndianBitConverter.ToUInt16(nvlist, offset);
                        offset    += 4;
                    }

                    break;

                case NVS_DataTypes.DATA_TYPE_UINT32:
                case NVS_DataTypes.DATA_TYPE_UINT32_ARRAY:
                    if (item.elements > 1)
                    {
                        uint[] uintArray = new uint[item.elements];
                        for (int i = 0; i < item.elements; i++)
                        {
                            uint temp = BigEndianBitConverter.ToUInt32(nvlist, offset);
                            uintArray[i] = temp;
                            offset      += 4;
                        }

                        item.value = uintArray;
                    }
                    else
                    {
                        item.value = BigEndianBitConverter.ToUInt32(nvlist, offset);
                        offset    += 4;
                    }

                    break;

                case NVS_DataTypes.DATA_TYPE_UINT64:
                case NVS_DataTypes.DATA_TYPE_UINT64_ARRAY:
                    if (item.elements > 1)
                    {
                        ulong[] ulongArray = new ulong[item.elements];
                        for (int i = 0; i < item.elements; i++)
                        {
                            ulong temp = BigEndianBitConverter.ToUInt64(nvlist, offset);
                            ulongArray[i] = temp;
                            offset       += 8;
                        }

                        item.value = ulongArray;
                    }
                    else
                    {
                        item.value = BigEndianBitConverter.ToUInt64(nvlist, offset);
                        offset    += 8;
                    }

                    break;

                case NVS_DataTypes.DATA_TYPE_NVLIST:
                    if (item.elements > 1)
                    {
                        goto default;
                    }

                    byte[] subListBytes = new byte[item.encodedSize - (offset - currOff)];
                    Array.Copy(nvlist, offset, subListBytes, 0, subListBytes.Length);
                    if (DecodeNvList(subListBytes, out Dictionary <string, NVS_Item> subList, true, littleEndian))
                    {
                        item.value = subList;
                    }
                    else
                    {
                        goto default;
                    }
                    offset = (int)(currOff + item.encodedSize);
                    break;

                default:
                    byte[] unknown = new byte[item.encodedSize - (offset - currOff)];
                    Array.Copy(nvlist, offset, unknown, 0, unknown.Length);
                    item.value = unknown;
                    offset     = (int)(currOff + item.encodedSize);
                    break;
                }

                decodedNvList.Add(item.name, item);
            }

            return(decodedNvList.Count > 0);
        }