Example #1
0
    public static UInt64 ReadUInt64(this BitStreamReader reader)
    {
        UInt32 left  = reader.ReadUInt32();
        UInt32 right = reader.ReadUInt32();

        return(BitConverterX.UInt32ToUInt64(left, right));
    }
Example #2
0
    public static string ReadString(this BitStreamReader reader)
    {
        UInt32        size          = reader.ReadUInt32();
        StringBuilder stringBuilder = new StringBuilder((int)size);

        for (int i = 0; i < size; i++)
        {
            stringBuilder.Append(reader.ReadChar());
        }

        return(stringBuilder.ToString());
    }
        public void Test_ReadUInt32()
        {
            BitStreamWriter writer = new BitStreamWriter(stream);
            BitStreamReader reader = new BitStreamReader(stream);

            writer.Write(36, 6);
            uint result = reader.ReadUInt32(_fixture.index, 6);

            _fixture.index += 6;

            Assert.Equal((uint)36, result);
        }
Example #4
0
        public void ShouldNot_AssertMixedBehavior()
        {
            var bytes  = new byte[] { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
            var stream = new BitStream(bytes);

            stream.AllowUnalignedOperations = true;
            var reader = new BitStreamReader(stream);
            var bit1   = reader.ReadUInt4();

            Assert.AreEqual(4, stream.BitsPosition);
            Assert.AreEqual(0, stream.Position);
            var bit2 = reader.ReadUInt4();

            Assert.AreEqual(0, stream.BitsPosition);
            Assert.AreEqual(1, stream.Position);
            var bit3 = reader.ReadUInt24();

            Assert.AreEqual(0, stream.BitsPosition);
            Assert.AreEqual(4, stream.Position);
            var bit4 = reader.ReadUInt24();

            Assert.AreEqual(0, stream.BitsPosition);
            Assert.AreEqual(7, stream.Position);
            var bit5 = reader.ReadUInt32();

            Assert.AreEqual(0, stream.BitsPosition);
            Assert.AreEqual(11, stream.Position);
            var bit6 = reader.ReadUInt4();

            Assert.AreEqual(4, stream.BitsPosition);
            Assert.AreEqual(11, stream.Position);
            var bit7 = reader.ReadUInt12();

            Assert.AreEqual(0, stream.BitsPosition);
            Assert.AreEqual(13, stream.Position);
        }
        /// <summary>
        /// Uncompress - uncompress the byte[] in the reader to a byte[] to return
        /// </summary>
        /// <param name="bitCount">number of bits each element is compressed to</param>
        /// <param name="reader">a reader over the compressed byte[]</param>
        /// <param name="encodingType">int, short or byte?</param>
        /// <param name="unitsToDecode">number of logical units to decode</param>
        /// <returns>Uncompressed byte[]</returns>
        internal byte[] Uncompress(int bitCount, BitStreamReader reader, GorillaEncodingType encodingType, int unitsToDecode)
        {
            if (null == reader)
            {
                throw new ArgumentNullException("reader");
            }
            if (bitCount < 0)
            {
                throw new ArgumentOutOfRangeException("bitCount");
            }
            if (unitsToDecode < 0)
            {
                throw new ArgumentOutOfRangeException("unitsToDecode");
            }

            int bitsToWrite = 0;

            // Test whether the items are signed. For unsigned number, we don't need mask
            // If we are trying to compress signed long values with bit count = 5
            // The mask will be 1111 1111 1111 0000. The way it is done is, if the 5th
            // bit is 1, the number is negative numbe, othrwise it's positive. Testing
            // will be non-zero, ONLY if the 5th bit is 1, in which case we OR with the mask
            // otherwise we leave the number as it is.
            uint bitMask = 0;
            //adjust if the bitcount is 0
            //(this makes bitCount 32)
            switch (encodingType)
            {
                case GorillaEncodingType.Int:
                    {
                        if (bitCount == 0)
                        {
                            bitCount = Native.BitsPerInt;
                        }
                        bitsToWrite = Native.BitsPerInt;
                        //we decode int's as unsigned, so we need to create a mask
                        bitMask = (unchecked((uint)~0) << (bitCount - 1));
                        break;
                    }
                case GorillaEncodingType.Short:
                    {
                        if (bitCount == 0)
                        {
                            bitCount = Native.BitsPerShort;
                        }
                        bitsToWrite = Native.BitsPerShort;
                        //shorts are decoded as unsigned values, no mask required
                        bitMask = 0;
                        break;
                    }
                case GorillaEncodingType.Byte:
                    {
                        if (bitCount == 0)
                        {
                            bitCount = Native.BitsPerByte;
                        }
                        bitsToWrite = Native.BitsPerByte;
                        //bytes are decoded as unsigned values, no mask required
                        bitMask = 0;
                        break;
                    }
                default:
                    {
                        throw new ArgumentException(StrokeCollectionSerializer.ISFDebugMessage("bogus GorillaEncodingType passed to Uncompress"));
                    }
            }
            List<byte> output = new List<byte>((bitsToWrite / 8) * unitsToDecode);
            BitStreamWriter writer = new BitStreamWriter(output);
            uint bitData = 0;

            while (!reader.EndOfStream && unitsToDecode > 0)
            {
                //we're going to cast to an uint anyway, just read as one
                bitData = reader.ReadUInt32(bitCount);
                // Construct the item
                bitData = ((bitData & bitMask) != 0) ? bitMask | bitData : bitData;
                writer.WriteReverse(bitData, bitsToWrite);
                unitsToDecode--;
            }

            return output.ToArray();
        }
        /// <summary>
        /// Uncompress - uncompress a byte[] into an int[] of point data (x,x,x,x,x)
        /// </summary>
        /// <param name="bitCount">The number of bits each element uses in input</param>
        /// <param name="input">compressed data</param>
        /// <param name="inputIndex">index to begin decoding at</param>
        /// <param name="dtxf">data xf, can be null</param>
        /// <param name="outputBuffer">output buffer that is prealloc'd to write to</param>
        /// <param name="outputBufferIndex">the index of the output buffer to write to</param>
        internal uint Uncompress(int bitCount, byte[] input, int inputIndex, DeltaDelta dtxf, int[] outputBuffer, int outputBufferIndex)
        {
            if (null == input)
            {
                throw new ArgumentNullException("input");
            }
            if (inputIndex >= input.Length)
            {
                throw new ArgumentOutOfRangeException("inputIndex");
            }
            if (null == outputBuffer)
            {
                throw new ArgumentNullException("outputBuffer");
            }
            if (outputBufferIndex >= outputBuffer.Length)
            {
                throw new ArgumentOutOfRangeException("outputBufferIndex");
            }

            if (bitCount < 0)
            {
                throw new ArgumentOutOfRangeException("bitCount");
            }

            // Adjust bit count if 0 passed in
            if (bitCount == 0)
            {
                //adjust if the bitcount is 0
                //(this makes bitCount 32)
                bitCount = (int)(Native.SizeOfInt << 3);
            }

            // Test whether the items are signed. For unsigned number, we don't need mask
            // If we are trying to compress signed long values with bit count = 5
            // The mask will be 1111 1111 1111 0000. The way it is done is, if the 5th
            // bit is 1, the number is negative numbe, othrwise it's positive. Testing
            // will be non-zero, ONLY if the 5th bit is 1, in which case we OR with the mask
            // otherwise we leave the number as it is.
            uint bitMask = (unchecked((uint)~0) << (bitCount - 1));
            uint bitData = 0;
            BitStreamReader reader = new BitStreamReader(input, inputIndex);

            if(dtxf != null)
            {
                while (!reader.EndOfStream)
                {
                    bitData = reader.ReadUInt32(bitCount);
                    // Construct the item
                    bitData = ((bitData & bitMask) != 0) ? bitMask | bitData : bitData;
                    int result = dtxf.InverseTransform((int)bitData, 0);
                    Debug.Assert(outputBufferIndex < outputBuffer.Length);
                    outputBuffer[outputBufferIndex++] = result;
                    if (outputBufferIndex == outputBuffer.Length)
                    {
                        //only write as much as the outputbuffer can hold
                        //this is assumed by calling code
                        break;
                    }
                }
            }
            else
            {
                while (!reader.EndOfStream)
                {
                    bitData = reader.ReadUInt32(bitCount);
                    // Construct the item
                    bitData = ((bitData & bitMask) != 0) ? bitMask | bitData : bitData;
                    Debug.Assert(outputBufferIndex < outputBuffer.Length);
                    outputBuffer[outputBufferIndex++] = (int)bitData;
                    if (outputBufferIndex == outputBuffer.Length)
                    {
                        //only write as much as the outputbuffer can hold
                        //this is assumed by calling code
                        break;
                    }
                }
            }

            // Calculate how many bytes were read from input buffer
            return (uint)((outputBuffer.Length * bitCount + 7) >> 3);
        }
        private static MeshBox ParseMeshBox(Stream s)
        {
            var ret = new MeshBox();

            var boxSize   = ReadUInt32(s);
            var boxHeader = ReadUInt32(s);

            var coordinate_count = ReadUInt32(s);

            ret.coordinates = new float[coordinate_count];
            for (uint i = 0; i < coordinate_count; i++)
            {
                ret.coordinates[i] = ReadSingle(s);
            }

            var ccsb = (int)Math.Ceiling(Math.Log(coordinate_count * 2, 2));

            var vertex_count = ReadUInt32(s);

            ret.verticies = new MeshBoxVertex[vertex_count];

            {
                var br = new BitStreamReader(s);
                for (uint i = 0; i < vertex_count; i++)
                {
                    ret.verticies[i] = new MeshBoxVertex()
                    {
                        x_index_delta = FromEncodedUInt(br.ReadUInt32(ccsb)),
                        y_index_delta = FromEncodedUInt(br.ReadUInt32(ccsb)),
                        z_index_delta = FromEncodedUInt(br.ReadUInt32(ccsb)),
                        u_index_delta = FromEncodedUInt(br.ReadUInt32(ccsb)),
                        v_index_delta = FromEncodedUInt(br.ReadUInt32(ccsb))
                    };
                }
            }

            var vertex_list_count = ReadUInt32(s);

            ret.vertex_lists = new MeshBoxVertexList[vertex_list_count];
            var vcsb = (int)Math.Ceiling(Math.Log(vertex_count * 2, 2));

            {
                var br = new BitStreamReader(s);
                for (uint i = 0; i < vertex_list_count; i++)
                {
                    var vertex_list = new MeshBoxVertexList()
                    {
                        texture_id = s.ReadByte(),
                        index_type = (MeshBoxIndexType)s.ReadByte()
                    };

                    var index_count = ReadUInt32(s);
                    vertex_list.index_as_delta = new int[index_count];
                    for (uint n = 0; n < index_count; n++)
                    {
                        vertex_list.index_as_delta[n] = FromEncodedUInt(br.ReadUInt32(vcsb));
                    }

                    ret.vertex_lists[i] = vertex_list;
                }
            }


            return(ret);
        }
Example #8
0
        /// <summary>
        /// Uncompress - uncompress the byte[] in the reader to a byte[] to return
        /// </summary>
        /// <param name="bitCount">number of bits each element is compressed to</param>
        /// <param name="reader">a reader over the compressed byte[]</param>
        /// <param name="encodingType">int, short or byte?</param>
        /// <param name="unitsToDecode">number of logical units to decode</param>
        /// <returns>Uncompressed byte[]</returns>
        internal byte[] Uncompress(int bitCount, BitStreamReader reader, GorillaEncodingType encodingType, int unitsToDecode)
        {
            if (null == reader)
            {
                throw new ArgumentNullException("reader");
            }
            if (bitCount < 0)
            {
                throw new ArgumentOutOfRangeException("bitCount");
            }
            if (unitsToDecode < 0)
            {
                throw new ArgumentOutOfRangeException("unitsToDecode");
            }

            int bitsToWrite = 0;

            // Test whether the items are signed. For unsigned number, we don't need mask
            // If we are trying to compress signed long values with bit count = 5
            // The mask will be 1111 1111 1111 0000. The way it is done is, if the 5th
            // bit is 1, the number is negative numbe, othrwise it's positive. Testing
            // will be non-zero, ONLY if the 5th bit is 1, in which case we OR with the mask
            // otherwise we leave the number as it is.
            uint bitMask = 0;

            //adjust if the bitcount is 0
            //(this makes bitCount 32)
            switch (encodingType)
            {
            case GorillaEncodingType.Int:
            {
                if (bitCount == 0)
                {
                    bitCount = Native.BitsPerInt;
                }
                bitsToWrite = Native.BitsPerInt;
                //we decode int's as unsigned, so we need to create a mask
                bitMask = (unchecked ((uint)~0) << (bitCount - 1));
                break;
            }

            case GorillaEncodingType.Short:
            {
                if (bitCount == 0)
                {
                    bitCount = Native.BitsPerShort;
                }
                bitsToWrite = Native.BitsPerShort;
                //shorts are decoded as unsigned values, no mask required
                bitMask = 0;
                break;
            }

            case GorillaEncodingType.Byte:
            {
                if (bitCount == 0)
                {
                    bitCount = Native.BitsPerByte;
                }
                bitsToWrite = Native.BitsPerByte;
                //bytes are decoded as unsigned values, no mask required
                bitMask = 0;
                break;
            }

            default:
            {
                throw new ArgumentException(StrokeCollectionSerializer.ISFDebugMessage("bogus GorillaEncodingType passed to Uncompress"));
            }
            }
            List <byte>     output  = new List <byte>((bitsToWrite / 8) * unitsToDecode);
            BitStreamWriter writer  = new BitStreamWriter(output);
            uint            bitData = 0;

            while (!reader.EndOfStream && unitsToDecode > 0)
            {
                //we're going to cast to an uint anyway, just read as one
                bitData = reader.ReadUInt32(bitCount);
                // Construct the item
                bitData = ((bitData & bitMask) != 0) ? bitMask | bitData : bitData;
                writer.WriteReverse(bitData, bitsToWrite);
                unitsToDecode--;
            }

            return(output.ToArray());
        }
Example #9
0
        /// <summary>
        /// Uncompress - uncompress a byte[] into an int[] of point data (x,x,x,x,x)
        /// </summary>
        /// <param name="bitCount">The number of bits each element uses in input</param>
        /// <param name="input">compressed data</param>
        /// <param name="inputIndex">index to begin decoding at</param>
        /// <param name="dtxf">data xf, can be null</param>
        /// <param name="outputBuffer">output buffer that is prealloc'd to write to</param>
        /// <param name="outputBufferIndex">the index of the output buffer to write to</param>
        internal uint Uncompress(int bitCount, byte[] input, int inputIndex, DeltaDelta dtxf, int[] outputBuffer, int outputBufferIndex)
        {
            if (null == input)
            {
                throw new ArgumentNullException("input");
            }
            if (inputIndex >= input.Length)
            {
                throw new ArgumentOutOfRangeException("inputIndex");
            }
            if (null == outputBuffer)
            {
                throw new ArgumentNullException("outputBuffer");
            }
            if (outputBufferIndex >= outputBuffer.Length)
            {
                throw new ArgumentOutOfRangeException("outputBufferIndex");
            }

            if (bitCount < 0)
            {
                throw new ArgumentOutOfRangeException("bitCount");
            }

            // Adjust bit count if 0 passed in
            if (bitCount == 0)
            {
                //adjust if the bitcount is 0
                //(this makes bitCount 32)
                bitCount = (int)(Native.SizeOfInt << 3);
            }

            // Test whether the items are signed. For unsigned number, we don't need mask
            // If we are trying to compress signed long values with bit count = 5
            // The mask will be 1111 1111 1111 0000. The way it is done is, if the 5th
            // bit is 1, the number is negative numbe, othrwise it's positive. Testing
            // will be non-zero, ONLY if the 5th bit is 1, in which case we OR with the mask
            // otherwise we leave the number as it is.
            uint            bitMask = (unchecked ((uint)~0) << (bitCount - 1));
            uint            bitData = 0;
            BitStreamReader reader  = new BitStreamReader(input, inputIndex);

            if (dtxf != null)
            {
                while (!reader.EndOfStream)
                {
                    bitData = reader.ReadUInt32(bitCount);
                    // Construct the item
                    bitData = ((bitData & bitMask) != 0) ? bitMask | bitData : bitData;
                    int result = dtxf.InverseTransform((int)bitData, 0);
                    Debug.Assert(outputBufferIndex < outputBuffer.Length);
                    outputBuffer[outputBufferIndex++] = result;
                    if (outputBufferIndex == outputBuffer.Length)
                    {
                        //only write as much as the outputbuffer can hold
                        //this is assumed by calling code
                        break;
                    }
                }
            }
            else
            {
                while (!reader.EndOfStream)
                {
                    bitData = reader.ReadUInt32(bitCount);
                    // Construct the item
                    bitData = ((bitData & bitMask) != 0) ? bitMask | bitData : bitData;
                    Debug.Assert(outputBufferIndex < outputBuffer.Length);
                    outputBuffer[outputBufferIndex++] = (int)bitData;
                    if (outputBufferIndex == outputBuffer.Length)
                    {
                        //only write as much as the outputbuffer can hold
                        //this is assumed by calling code
                        break;
                    }
                }
            }

            // Calculate how many bytes were read from input buffer
            return((uint)((outputBuffer.Length * bitCount + 7) >> 3));
        }
        static void Main(string[] args)
        {
            if (!System.IO.File.Exists(fileName))
            {
                throw new System.IO.FileNotFoundException();
            }

            int record_count = 0;

            using (var wdb_stream = new BinaryReader(File.OpenRead(fileName)))
            {
                var signature = wdb_stream.ReadBytes(4);
                var build     = wdb_stream.ReadUInt32();
                var locale    = Encoding.UTF8.GetString(wdb_stream.ReadBytes(4).Reverse().ToArray());
                var unk_h1    = wdb_stream.ReadInt32();
                var unk_h2    = wdb_stream.ReadInt32();
                var version   = wdb_stream.ReadInt32();

                Console.WriteLine(fileName);
                Console.WriteLine("Locale: " + locale);
                Console.WriteLine("Build: " + build);

                using (var writer = File.CreateText(fileName + ".sql"))
                {
                    while (wdb_stream.BaseStream.Position != wdb_stream.BaseStream.Length)
                    {
                        var entry = wdb_stream.ReadInt32();
                        var size  = wdb_stream.ReadInt32();

                        if (entry == 0 && size == 0)
                        {
                            break;
                        }

                        ++record_count;

                        #region reader

                        var row_bytes = wdb_stream.ReadBytes(size);
                        var reader    = new BitStreamReader(row_bytes);

                        int titleLen      = (int)reader.ReadUInt32(11);
                        int titleAltLen   = (int)reader.ReadUInt32(11);
                        int cursorNameLen = (int)reader.ReadUInt32(6);

                        var racialLeader = reader.ReadBit() ? 1 : 0;

                        int[]    male_names_len  = new int[4];
                        int[]    female_name_len = new int[4];
                        string[] male_names      = new string[4];
                        string[] female_names    = new string[4];

                        for (int i2 = 0; i2 < 4; ++i2)
                        {
                            male_names_len[i2]  = (int)reader.ReadUInt32(11);
                            female_name_len[i2] = (int)reader.ReadUInt32(11);
                        }

                        for (int i2 = 0; i2 < 4; ++i2)
                        {
                            male_names[i2]   = reader.ReadEsqapedSqlString2(male_names_len[i2]);
                            female_names[i2] = reader.ReadEsqapedSqlString2(female_name_len[i2]);
                        }

                        var type_flags  = reader.ReadUInt32();
                        var type_flags2 = reader.ReadUInt32();

                        var type   = reader.ReadInt32();
                        var family = reader.ReadInt32();
                        var rank   = reader.ReadInt32();

                        var kill_kredit1 = reader.ReadInt32();
                        var kill_kredit2 = reader.ReadInt32();

                        var modelid1 = reader.ReadInt32();
                        var modelid2 = reader.ReadInt32();
                        var modelid3 = reader.ReadInt32();
                        var modelid4 = reader.ReadInt32();

                        var HealthModifier = reader.ReadFloat();
                        var ManaModifier   = reader.ReadFloat();

                        var quest_item_count = reader.ReadInt32();
                        var movement_id      = reader.ReadInt32();
                        var unk543           = reader.ReadInt32();    // unk EXP

                        var questFlag  = reader.ReadInt32();
                        var vignetteID = reader.ReadInt32();

                        var title    = reader.ReadEsqapedSqlString2(titleLen);
                        var titleAlt = reader.ReadEsqapedSqlString2(titleAltLen);

                        var cursorName = reader.ReadEsqapedSqlString2(cursorNameLen);

                        int[] QuestItem = new int[6];
                        for (int i = 0; i < quest_item_count; ++i)
                        {
                            QuestItem[i] = reader.ReadInt32();
                        }

                        if (reader.Buffer.Length != reader.Index)
                        {
                            Console.WriteLine(reader.Buffer.Length - reader.Index);
                        }

                        #endregion

                        #region SQL
                        writer.WriteLine("REPLACE INTO `creaturecache` VALUES (\'" + locale + "\', {0}, {1}, {2}, {3}, {4}, {5}, {6}, {7}, {8}, {9}, {10}, {11}, {12}, {13}, {14}, {15}, {16}, {17}, {18}, {19}, {20}, {21}, {22}, {23}, {24}, {25}, {26}, {27}, {28}, {29}, {30}, {31}, {32}, {33}, {34}, {35}, {36}, {37}, {38}, {39}, {40}, {41}, {42}, {43}, {44}, {45}, {46}, {47});",
                                         entry,
                                         titleLen,
                                         titleAltLen,
                                         cursorNameLen,
                                         racialLeader,

                                         male_names_len[0], female_name_len[0],
                                         male_names_len[1], female_name_len[1],
                                         male_names_len[2], female_name_len[2],
                                         male_names_len[3], female_name_len[3],

                                         male_names[0],
                                         female_names[0],

                                         male_names[1],
                                         female_names[1],

                                         male_names[2],
                                         female_names[2],

                                         male_names[3],
                                         female_names[3],

                                         type_flags, type_flags2,
                                         type, family, rank,
                                         kill_kredit1, kill_kredit2,
                                         modelid1, modelid2, modelid3, modelid4,

                                         HealthModifier.ToString(CultureInfo.InvariantCulture),
                                         ManaModifier.ToString(CultureInfo.InvariantCulture),

                                         quest_item_count,
                                         movement_id,
                                         unk543,
                                         questFlag,
                                         vignetteID,

                                         title,
                                         titleAlt,
                                         cursorName,

                                         QuestItem[0],
                                         QuestItem[1],
                                         QuestItem[2],
                                         QuestItem[3],
                                         QuestItem[4],
                                         QuestItem[5]
                                         );
                        #endregion
                    }
                    writer.Flush();
                }
            }
            Console.WriteLine("Reading {0} records", record_count);
            Console.WriteLine("Done!");
            Console.ReadLine();
        }
 public static UInt32 Deserialize(BitStreamReader reader) => reader.ReadUInt32();
 public static void Deserialize(ref UInt32 value, BitStreamReader reader) => value = reader.ReadUInt32();