Beispiel #1
0
        public void WriteArray()
        {
            var data     = new byte[] { 0x3c, 0x4b, 0x1a, 0x54, 0x22, 0x10, 0xaf, 0x89, 0x97, 0x65 };
            var expected = new byte[] { 0x9e, 0x25, 0x8d, 0x2a, 0x11, 0x08, 0x57, 0xc4, 0xcb, 0xb2, 0x80 };

            var result = new byte[expected.Length];

            var stream = new MemoryStream();

            using (var writer = new BitStreamWriter(stream, true))
            {
                Assert.AreEqual(false, writer.CanRead);
                Assert.AreEqual(true, writer.CanWrite);
                Assert.AreEqual(true, writer.CanSeek);

                Assert.AreEqual(0, writer.Length);
                Assert.AreEqual(0, writer.BitLength);
                Assert.AreEqual(0, writer.BitPosition);
                Assert.AreEqual(0, writer.Position);

                writer.Write(true);
                writer.Write(data, 0, data.Length);

                Assert.AreEqual(11, writer.Length);
                Assert.AreEqual(81, writer.BitLength);
                Assert.AreEqual(81, writer.BitPosition);
                Assert.AreEqual(10, writer.Position);
            }

            Array.Copy(stream.GetBuffer(), 0, result, 0, expected.Length);
            CollectionAssert.AreEqual(expected, result);
        }
Beispiel #2
0
        public void SetLength_SetPosition()
        {
            var stream = new MemoryStream();

            using (var writer = new BitStreamWriter(stream, true))
            {
                Assert.AreEqual(false, writer.CanRead);
                Assert.AreEqual(true, writer.CanWrite);
                Assert.AreEqual(true, writer.CanSeek);

                Assert.AreEqual(0, writer.Length);
                Assert.AreEqual(0, writer.BitLength);
                Assert.AreEqual(0, writer.BitPosition);
                Assert.AreEqual(0, writer.Position);

                writer.SetLength(10);
                writer.Write(true);
                writer.Position = 5;
                writer.Write(true);

                Assert.AreEqual(10, writer.Length);
                Assert.AreEqual(80, writer.BitLength);
                Assert.AreEqual(41, writer.BitPosition);
                Assert.AreEqual(5, writer.Position);
            }

            Assert.AreEqual(10, stream.Length);
            Assert.AreEqual(6, stream.Position);
            Assert.AreEqual(0x80, stream.GetBuffer()[0]);
            Assert.AreEqual(0x80, stream.GetBuffer()[5]);
        }
Beispiel #3
0
        public void WriteBit_Seek_WriteBit()
        {
            var stream = new MemoryStream();

            using (var writer = new BitStreamWriter(stream, true))
            {
                Assert.AreEqual(false, writer.CanRead);
                Assert.AreEqual(true, writer.CanWrite);
                Assert.AreEqual(true, writer.CanSeek);

                Assert.AreEqual(0, writer.Length);
                Assert.AreEqual(0, writer.BitLength);
                Assert.AreEqual(0, writer.BitPosition);
                Assert.AreEqual(0, writer.Position);

                writer.Write(true);

                Assert.AreEqual(1, writer.Length);
                Assert.AreEqual(1, writer.BitLength);
                Assert.AreEqual(1, writer.BitPosition);
                Assert.AreEqual(0, writer.Position);

                writer.Seek(0, SeekOrigin.Begin);

                Assert.AreEqual(1, stream.Length);
                Assert.AreEqual(0, stream.Position);
                Assert.AreEqual(0x80, stream.GetBuffer()[0]);

                writer.Write(false);
            }
            Assert.AreEqual(1, stream.Length);
            Assert.AreEqual(1, stream.Position);
            Assert.AreEqual(0, stream.GetBuffer()[0]);
        }
Beispiel #4
0
            public void Serialize(BlubSerializer serializer, BinaryWriter writer, DamageInfoMessage value)
            {
                writer.Write(value.Target);
                writer.WriteEnum(value.AttackAttribute);
                writer.Write(value.GameTime);
                writer.Write(value.Source);
                writer.Write(value.Unk5);
                writer.WriteRotation(value.Rotation);
                writer.WriteCompressed(value.Position);
                writer.WriteCompressed(value.Unk6);
                writer.WriteCompressed(value.Damage);
                writer.Write(value.Unk8);
                writer.Write(value.Unk9);

                var ls = new List <byte>();
                var bw = new BitStreamWriter(ls);

                bw.Write(value.Flag1, 3);
                bw.Write(value.Flag2, 2);
                bw.Write(value.Flag3, 1);
                bw.Write(value.Flag4, 1);
                bw.Write(value.Flag5, 1);

                bw.Write(value.Flag6, 1);
                bw.Write(value.Flag7, 7);

                bw.Write(value.IsCritical, 4);
                bw.Write(value.Flag9, 4);

                writer.Write(ls);
            }
Beispiel #5
0
        public void BitwiseNumbers()
        {
            /*
             * Unsigned, BE, 12bit "A B C" -> 0x0ABC ->  2748
             * Signed  , BE, 12bit "A B C" -> 0xFABC -> -1348
             * Unsigned, LE, 12bit "B C A" -> 0x0ABC ->  2748
             * Signed  , LE, 12bit "B C A" -> 0xFABC -> -1348
             */

            var w = new BitStreamWriter <BigEndian>();

            w.Write(0, 32);
            w.Write(0x00, 1);
            w.Write(0x01, 1);
            w.Write(0x00, 1);
            w.Write(-1, 5);
            w.Write(0x0f, 4);
            w.Write(0x123456789A, 40);

            Assert.AreEqual(84, w.LengthBits);
            Assert.AreEqual(11, w.Stream.Length);
            byte[] exp1 = new byte[] { 0x0, 0x0, 0x0, 0x0, 0x5f, 0xf1, 0x23, 0x45, 0x67, 0x89, 0xa0 };
            byte[] act1 = new byte[11];
            Buffer.BlockCopy(w.Stream.GetBuffer(), 0, act1, 0, 11);
            Assert.AreEqual(exp1, act1);

            var w1 = new BitStreamWriter <LittleEndian>();

            w1.Write(0x12345678, 32);
            w1.Write(0xabc, 12);

            Assert.AreEqual(44, w1.LengthBits);
            Assert.AreEqual(6, w1.Stream.Length);
            byte[] exp2 = new byte[] { 0x78, 0x56, 0x34, 0x12, 0xbc, 0xa0 };
            byte[] act2 = new byte[6];
            Buffer.BlockCopy(w1.Stream.GetBuffer(), 0, act2, 0, 6);
            Assert.AreEqual(exp2, act2);

            var w2 = new BitStreamWriter <LittleEndian>();

            w2.Write(1, 1);
            w2.Write(0, 1);
            w2.Write(0xffff, 6);

            Assert.AreEqual(8, w2.LengthBits);
            Assert.AreEqual(1, w2.Stream.Length);
            byte[] exp3 = new byte[] { 0xbf };
            byte[] act3 = new byte[1];
            Buffer.BlockCopy(w2.Stream.GetBuffer(), 0, act3, 0, 1);
            Assert.AreEqual(exp3, act3);
        }
Beispiel #6
0
        void WriteAlignment(BitStreamWriter writer, VoidDsdlType t)
        {
            var amount = t.MaxBitlen;

            while (amount > 8)
            {
                writer.Write(0, 8);
                amount -= 8;
            }

            if (amount > 0)
            {
                writer.Write(0, amount);
            }
        }
Beispiel #7
0
        public void BitwiseNumbers()
        {
            /*
             * Unsigned, BE, 12bit "A B C" -> 0x0ABC ->  2748
             * Signed  , BE, 12bit "A B C" -> 0xFABC -> -1348
             * Unsigned, LE, 12bit "B C A" -> 0x0ABC ->  2748
             * Signed  , LE, 12bit "B C A" -> 0xFABC -> -1348
             */

            var w = new BitStreamWriter(Endian.Big);

            w.Write(0, 32);
            w.Write(0x00, 1);
            w.Write(0x01, 1);
            w.Write(0x00, 1);
            w.Write(-1, 5);
            w.Write(0x0f, 4);
            w.Write(0x123456789A, 40);

            Assert.AreEqual(84, w.Stream.LengthBits);
            Assert.AreEqual(10, w.Stream.Length);
            Assert.AreEqual(11, w.Stream.BaseStream.Length);
            byte[] exp1 = new byte[] { 0x0, 0x0, 0x0, 0x0, 0x5f, 0xf1, 0x23, 0x45, 0x67, 0x89, 0xa0 };
            Assert.AreEqual(exp1, w.Stream.ToArray());

            var w1 = new BitStreamWriter(Endian.Little);

            w1.Write(0x12345678, 32);
            w1.Write(0xabc, 12);

            Assert.AreEqual(44, w1.Stream.LengthBits);
            Assert.AreEqual(5, w1.Stream.Length);
            Assert.AreEqual(6, w1.Stream.BaseStream.Length);
            byte[] exp2 = new byte[] { 0x78, 0x56, 0x34, 0x12, 0xbc, 0xa0 };
            Assert.AreEqual(exp2, w1.Stream.ToArray());

            var w2 = new BitStreamWriter(Endian.Little);

            w2.Write(1, 1);
            w2.Write(0, 1);
            w2.Write(0xffff, 6);

            Assert.AreEqual(8, w2.Stream.LengthBits);
            Assert.AreEqual(1, w2.Stream.Length);
            Assert.AreEqual(1, w2.Stream.BaseStream.Length);
            byte[] exp3 = new byte[] { 0xbf };
            Assert.AreEqual(exp3, w2.Stream.ToArray());
        }
Beispiel #8
0
        public void WriteSevenBits()
        {
            int bitCount = 7;
            var stream   = new MemoryStream();

            using (var writer = new BitStreamWriter(stream, true))
            {
                Assert.AreEqual(false, writer.CanRead);
                Assert.AreEqual(true, writer.CanWrite);
                Assert.AreEqual(true, writer.CanSeek);

                Assert.AreEqual(0, writer.Length);
                Assert.AreEqual(0, writer.BitLength);
                Assert.AreEqual(0, writer.BitPosition);
                Assert.AreEqual(0, writer.Position);


                for (int i = 0; i < bitCount; ++i)
                {
                    writer.Write(true);
                }

                Assert.AreEqual((bitCount + 7) >> 3, writer.Length);
                Assert.AreEqual(bitCount, writer.BitLength);
                Assert.AreEqual(bitCount, writer.BitPosition);
                Assert.AreEqual(bitCount >> 3, writer.Position);
            }
        }
Beispiel #9
0
        /**
         * This function can be used to encode values for later transmission in a UAVCAN transfer. It encodes a scalar value -
         * boolean, integer, character, or floating point - and puts it to the specified bit position in the specified
         * contiguous buffer.
         * Simple single-frame transfers can also be encoded manually.
         *
         * Caveat:  This function works correctly only on platforms that use two's complement signed integer representation.
         *          I am not aware of any modern microarchitecture that uses anything else than two's complement, so it should
         *          not affect portability in any way.
         *
         * The type of value pointed to by 'value' is defined as follows:
         *
         *  | bit_length | value points to                       |
         *  |------------|---------------------------------------|
         *  | 1          | bool (may be incompatible with byte!) |
         *  | [2, 8]     | byte, byte, or char                   |
         *  | [9, 16]    | ushort, short                         |
         *  | [17, 32]   | uint, int, or 32-bit float            |
         *  | [33, 64]   | ulong, long, or 64-bit float          |
         */
        static void Write(BitStreamWriter destination,
                          byte[] source,
                          int sourceOffset,
                          int bitLength)
        {
            if (destination == null)
            {
                throw new ArgumentNullException(nameof(destination));
            }
            if (source == null)
            {
                throw new ArgumentNullException(nameof(source));
            }
            if (bitLength < 1 || bitLength > 64)
            {
                throw new ArgumentOutOfRangeException(nameof(bitLength));
            }

            while (bitLength > 0)
            {
                var currentBitLen = bitLength;
                if (currentBitLen > 8)
                {
                    currentBitLen = 8;
                }
                destination.Write(source[sourceOffset++], currentBitLen);
                bitLength -= currentBitLen;
            }
        }
Beispiel #10
0
            public void Serialize(BinaryWriter writer, DamageRemoteInfoMessage value)
            {
                writer.Write(value.Target);
                writer.WriteEnum(value.AttackAttribute);
                writer.Write(value.GameTime);
                writer.Write(value.Source);
                writer.WriteRotation(value.Rotation);
                writer.WriteCompressed(value.Position);
                writer.WriteCompressed(value.Unk);
                writer.WriteCompressed(value.Damage);

                var ls = new List <byte>();
                var bw = new BitStreamWriter(ls);

                bw.Write(value.Flag1, 2);
                bw.Write(value.Flag2, 1);
                bw.Write(value.Flag3, 1);
                bw.Write(value.Flag4, 1);
                bw.Write(value.Flag5, 3);

                bw.Write(value.Flag6, 4);
                bw.Write(value.Flag7, 4);

                writer.Write(ls);
            }
Beispiel #11
0
        public void leaveOpen_False()
        {
            var stream = new MemoryStream();

            using (var writer = new BitStreamWriter(stream, false))
            {
                Assert.AreEqual(false, writer.CanRead);
                Assert.AreEqual(true, writer.CanWrite);
                Assert.AreEqual(true, writer.CanSeek);

                Assert.AreEqual(0, writer.Length);
                Assert.AreEqual(0, writer.BitLength);
                Assert.AreEqual(0, writer.BitPosition);
                Assert.AreEqual(0, writer.Position);

                writer.Write(true);

                Assert.AreEqual(1, writer.Length);
                Assert.AreEqual(1, writer.BitLength);
                Assert.AreEqual(1, writer.BitPosition);
                Assert.AreEqual(0, writer.Position);

                writer.Seek(0, SeekOrigin.Begin);

                Assert.AreEqual(1, stream.Length);
                Assert.AreEqual(0, stream.Position);
                Assert.AreEqual(0x80, stream.GetBuffer()[0]);

                writer.Write(false);
            }
            Assert.AreEqual(1, stream.Length);
            Assert.AreEqual(1, stream.Position);
            Assert.AreEqual(0, stream.GetBuffer()[0]);

            using (var writer = new BitStreamWriter(stream, false))
            {
                var data = new byte[] { 0x3c, 0x4b, 0x1a, 0x54, 0x22, 0x10, 0xaf, 0x89, 0x97, 0x65 };
                writer.Write(data, 0, data.Length);
                writer.Flush();

                Assert.AreEqual(11, stream.Length);
                Assert.AreEqual(11, stream.Position);
            }
        }
Beispiel #12
0
        /// <summary>
        /// Compress - compresses the byte[] being read by the BitStreamReader into compressed data
        /// </summary>
        /// <param name="bitCount">the number of bits to use for each element</param>
        /// <param name="reader">a reader over the byte[] to compress</param>
        /// <param name="encodingType">int, short or byte?</param>
        /// <param name="unitsToEncode">number of logical units to encoded</param>
        /// <param name="compressedData">output write buffer</param>
        internal void Compress(int bitCount, BitStreamReader reader, GorillaEncodingType encodingType, int unitsToEncode, List <byte> compressedData)
        {
            if (null == reader || null == compressedData)
            {
                throw new ArgumentNullException(StrokeCollectionSerializer.ISFDebugMessage("reader or compressedData was null in compress"));
            }
            if (bitCount < 0)
            {
                throw new ArgumentOutOfRangeException("bitCount");
            }
            if (unitsToEncode < 0)
            {
                throw new ArgumentOutOfRangeException("unitsToEncode");
            }

            if (bitCount == 0)
            {
                //adjust if the bitcount is 0
                //(this makes bitCount 32)
                switch (encodingType)
                {
                case GorillaEncodingType.Int:
                {
                    bitCount = Native.BitsPerInt;
                    break;
                }

                case GorillaEncodingType.Short:
                {
                    bitCount = Native.BitsPerShort;
                    break;
                }

                case GorillaEncodingType.Byte:
                {
                    bitCount = Native.BitsPerByte;
                    break;
                }

                default:
                {
                    throw new ArgumentException(StrokeCollectionSerializer.ISFDebugMessage("bogus GorillaEncodingType passed to compress"));
                }
                }
            }

            //have the writer adapt to the List<byte> passed in and write to it
            BitStreamWriter writer = new BitStreamWriter(compressedData);

            while (!reader.EndOfStream && unitsToEncode > 0)
            {
                int data = GetDataFromReader(reader, encodingType);
                writer.Write((uint)data, bitCount);
                unitsToEncode--;
            }
        }
Beispiel #13
0
        /// <summary>
        /// Compress - compress the input[] into compressedData
        /// </summary>
        /// <param name="bitCount">The count of bits needed for all elements</param>
        /// <param name="input">input buffer</param>
        /// <param name="startInputIndex">offset into the input buffer</param>
        /// <param name="dtxf">data transform.  can be null</param>
        /// <param name="compressedData">The list of bytes to write the compressed input to</param>
        internal void Compress(int bitCount, int[] input, int startInputIndex, DeltaDelta dtxf, List <byte> compressedData)
        {
            if (null == input || null == compressedData)
            {
                throw new ArgumentNullException(StrokeCollectionSerializer.ISFDebugMessage("input or compressed data was null in Compress"));
            }
            if (bitCount < 0)
            {
                throw new ArgumentOutOfRangeException("bitCount");
            }

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

            //have the writer adapt to the List<byte> passed in and write to it
            BitStreamWriter writer = new BitStreamWriter(compressedData);

            if (null != dtxf)
            {
                int xfData  = 0;
                int xfExtra = 0;
                for (int i = startInputIndex; i < input.Length; i++)
                {
                    dtxf.Transform(input[i], ref xfData, ref xfExtra);
                    if (xfExtra != 0)
                    {
                        throw new InvalidOperationException(StrokeCollectionSerializer.ISFDebugMessage("Transform returned unexpected results"));
                    }
                    writer.Write((uint)xfData, bitCount);
                }
            }
            else
            {
                for (int i = startInputIndex; i < input.Length; i++)
                {
                    writer.Write((uint)input[i], bitCount);
                }
            }
        }
Beispiel #14
0
        public void Should_WriteInt64()
        {
            var stream = new BitStream();
            var writer = new BitStreamWriter(stream);
            var val    = 12355222L;

            writer.Write(val);
            Assert.AreEqual(sizeof(long), stream.Length);
            Assert.AreEqual(BitConverter.GetBytes(val), stream.ToArray());
        }
Beispiel #15
0
        public void ShouldNot_WriteBitsAndBytes()
        {
            var stream = new BitStream();

            stream.AllowUnalignedOperations = false;
            var writer = new BitStreamWriter(stream);
            var val    = new byte[] { 0xFF, 0x01, 0xCC, 0xAA };

            writer.WriteBit(0);
            writer.WriteBit(1);
            Assert.Throws <StreamUnalignedException>(() => writer.Write(val));
        }
        public void Test_ReadInt64()
        {
            BitStreamWriter writer = new BitStreamWriter(stream);
            BitStreamReader reader = new BitStreamReader(stream);

            writer.Write(872, 10);
            long result = reader.ReadInt64(_fixture.index, 10);

            _fixture.index += 10;

            Assert.Equal(872, result);
        }
        public void Test_ReadUInt16()
        {
            BitStreamWriter writer = new BitStreamWriter(stream);
            BitStreamReader reader = new BitStreamReader(stream);

            writer.Write(5, 3);
            ushort result = reader.ReadUInt16(_fixture.index, 3);

            _fixture.index += 3;

            Assert.Equal((ushort)5, result);
        }
        public void Test_ReadInt32()
        {
            BitStreamWriter writer = new BitStreamWriter(stream);
            BitStreamReader reader = new BitStreamReader(stream);

            writer.Write(36, 6);
            int result = reader.ReadInt32(_fixture.index, 6);

            _fixture.index += 6;

            Assert.Equal(36, result);
        }
        public void Test_ReadByte()
        {
            BitStreamWriter writer = new BitStreamWriter(stream);
            BitStreamReader reader = new BitStreamReader(stream);

            writer.Write(125, 7);
            byte result = reader.ReadByte(_fixture.index, 7);

            _fixture.index += 7;

            Assert.Equal(125, result);
        }
        public void Test_ReadChar()
        {
            BitStreamWriter writer = new BitStreamWriter(stream);
            BitStreamReader reader = new BitStreamReader(stream);

            writer.Write('x');
            char result = reader.ReadChar(_fixture.index);

            _fixture.index += 8;

            Assert.Equal('x', result);
        }
        public void Test_ByteArray()
        {
            BitStreamWriter writer = new BitStreamWriter(stream);
            BitStreamReader reader = new BitStreamReader(stream);

            byte[] array = new byte[] { 255, 254, 251, 250 };
            writer.Write(array);
            byte[] result = reader.ReadBytes(_fixture.index, array.Length);
            _fixture.index += array.Length * 8;

            Assert.Equal(array, result);
        }
        public void Test_ReadBoolean()
        {
            BitStreamWriter writer = new BitStreamWriter(stream);
            BitStreamReader reader = new BitStreamReader(stream);

            writer.Write(true);
            bool result = reader.ReadBoolean(_fixture.index);

            _fixture.index++;


            Assert.True(result);
        }
        public void Test_ReadString()
        {
            BitStreamWriter writer = new BitStreamWriter(stream);
            BitStreamReader reader = new BitStreamReader(stream);
            string          str    = "Hello World!";

            writer.Write(str);
            string result = reader.ReadString(_fixture.index, str.Length);

            _fixture.index += str.Length * 8;

            Assert.Equal(str, result);
        }
Beispiel #24
0
        public void Should_WriteBytes()
        {
            var stream = new BitStream();
            var writer = new BitStreamWriter(stream);
            var val    = new byte[] { 0xFF, 0x01, 0xCC, 0xAA };

            writer.Write(val);
            Assert.AreEqual(val.Length, stream.Length);
            var bytes = stream.ToArray();

            // we wrote 01 binary, which is 2
            CollectionAssert.AreEqual(val, bytes);
        }
Beispiel #25
0
        public void Should_WriteInt48()
        {
            var stream = new BitStream();
            var writer = new BitStreamWriter(stream);
            var val    = Int48.MaxValue;

            writer.Write(val);
            writer.Flush();
            Assert.AreEqual(6, stream.Length);
            var bytes    = stream.ToArray();
            var valBits  = val.GetBits();
            var byteBits = bytes.GetBits(Int48.BitSize);

            CollectionAssert.AreEqual(valBits, byteBits);
        }
Beispiel #26
0
        public void Should_WriteBitsAndBytes()
        {
            var stream = new BitStream();

            stream.AllowUnalignedOperations = true;
            var writer = new BitStreamWriter(stream);
            var val    = new byte[] { 0xFF, 0x01, 0xCC, 0xAA };

            writer.WriteBit(0);
            writer.WriteBit(1);
            writer.Write(val);
            writer.Flush();
            Assert.AreEqual(val.Length + 1, stream.Length);
            var bytes = stream.ToArray();

            CollectionAssert.AreNotEqual(val, bytes);
            CollectionAssert.AreEqual(new byte[] { 254, 7, 48, 171, 2 }, bytes);
        }
Beispiel #27
0
        /// <summary>
        /// Uncompress
        /// </summary>
        /// <param name="input"></param>
        /// <param name="inputIndex"></param>
        /// <returns></returns>
        internal byte[] Uncompress(byte[] input, int inputIndex)
        {
            //first things first
            Debug.Assert(input != null);
            Debug.Assert(input.Length > 1);
            Debug.Assert(inputIndex < input.Length);
            Debug.Assert(inputIndex >= 0);

            List <byte>     output = new List <byte>();
            BitStreamWriter writer = new BitStreamWriter(output);
            BitStreamReader reader = new BitStreamReader(input, inputIndex);

            //decode
            int  index = 0, countBytes = 0, start = 0;
            byte byte1 = 0, byte2 = 0;

            _maxMatchLength = FirstMaxMatchLength;

            // initialize the ring buffer
            for (index = 0; index < RingBufferLength - _maxMatchLength; index++)
            {
                _ringBuffer[index] = 0;
            }

            //initialize decoding globals
            _flags = 0;
            _currentRingBufferPosition = RingBufferLength - _maxMatchLength;
            while (!reader.EndOfStream)
            {
                byte1 = reader.ReadByte(Native.BitsPerByte);

                // High order byte counts the number of bits used in the low order
                // byte.
                if (((_flags >>= 1) & 0x100) == 0)
                {
                    // Set bit mask describing the next 8 bytes.
                    _flags = (((int)byte1) | 0xff00);

                    byte1 = reader.ReadByte(Native.BitsPerByte);
                }

                if ((_flags & 1) != 0)
                {
                    // Just store the literal byte in the buffer.
                    writer.Write(byte1, Native.BitsPerByte);

                    _ringBuffer[_currentRingBufferPosition++] = byte1;
                    _currentRingBufferPosition &= RingBufferLength - 1;
                }
                else
                {
                    // Extract the offset and count to copy from the ring buffer.
                    byte2 = reader.ReadByte(Native.BitsPerByte);

                    countBytes = (int)byte2;
                    start      = (countBytes & 0xf0) << 4 | (int)byte1;
                    countBytes = (countBytes & 0x0f) + MaxLiteralLength;

                    for (index = 0; index <= countBytes; index++)
                    {
                        byte1 = _ringBuffer[(start + index) & (RingBufferLength - 1)];
                        writer.Write(byte1, Native.BitsPerByte);

                        _ringBuffer[_currentRingBufferPosition++] = byte1;
                        _currentRingBufferPosition &= RingBufferLength - 1;
                    }
                }
            }

            return(output.ToArray());
        }
Beispiel #28
0
        /// <summary>
        /// Encode
        /// </summary>
        /// <param name="data"></param>
        /// <param name="extra"></param>
        /// <param name="writer"></param>
        /// <returns>number of bits encoded, 0 for failure</returns>
        internal byte Encode(int data, int extra, BitStreamWriter writer)
        {
            if (writer == null)
            {
                throw new ArgumentNullException("writer");
            }
            if (data == 0)
            {
                writer.Write((byte)0, 1); //more efficent
                return((byte)1);
            }

            // First, encode extra if non-ZERO
            uint bitSize = _huffBits.GetSize();

            if (0 != extra)
            {
                // Prefix lenght is 1 more than table size
                byte extraPrefixLength = (byte)(bitSize + 1);
                int  extraPrefix       = ((1 << extraPrefixLength) - 2);

                writer.Write((uint)extraPrefix, (int)extraPrefixLength);

                // Encode the extra data first
                byte extraCodeLength = Encode(extra, 0, writer);
                // Encode the actual data next
                byte dataCodeLength = Encode(data, 0, writer);
                // Return the total code lenght
                return((byte)((int)extraPrefixLength + (int)extraCodeLength + (int)dataCodeLength));
            }
            // Find the absolute value of the data
            // IMPORTANT : It is extremely important that nData is uint, and NOT int
            // If it is int, the LONG_MIN will be encoded erroneaouly
            uint nData = (uint)MathHelper.AbsNoThrow(data);
            // Find the prefix lenght
            byte nPrefLen = 1;

            for (; (nPrefLen < bitSize) && (nData >= _mins[nPrefLen]); ++nPrefLen)
            {
                ;
            }
            // Get the data length
            uint nDataLen = _huffBits.GetBitsAtIndex((uint)nPrefLen - 1);

            // Find the prefix
            int nPrefix = ((1 << nPrefLen) - 2);

            // Append the prefix to the bit stream
            writer.Write((uint)nPrefix, (int)nPrefLen);
            // Find the data offset by lower bound
            // and append sign bit at LSB
            Debug.Assert(nDataLen > 0 && nDataLen - 1 <= Int32.MaxValue);
            int dataLenMinusOne = (int)(nDataLen - 1); //can't left shift by a uint, we need to thunk to an int

            nData = ((((nData - _mins[nPrefLen - 1]) & (uint)((1 << dataLenMinusOne) - 1)) << 1) | (uint)((data < 0) ? 1 : 0));
            // Append data into the bit streamdataLenMinusOne
            Debug.Assert(nDataLen <= Int32.MaxValue);
            writer.Write(nData, (int)nDataLen);

            return((byte)((uint)nPrefLen + nDataLen));
        }
        /// <summary>
        /// Compress - compresses the byte[] being read by the BitStreamReader into compressed data
        /// </summary>
        /// <param name="bitCount">the number of bits to use for each element</param>
        /// <param name="reader">a reader over the byte[] to compress</param>
        /// <param name="encodingType">int, short or byte?</param>
        /// <param name="unitsToEncode">number of logical units to encoded</param>
        /// <param name="compressedData">output write buffer</param>
        internal void Compress(int bitCount, BitStreamReader reader, GorillaEncodingType encodingType, int unitsToEncode, List<byte> compressedData)
        {
            if (null == reader || null == compressedData)
            {
                throw new ArgumentNullException(StrokeCollectionSerializer.ISFDebugMessage("reader or compressedData was null in compress"));
            }
            if (bitCount < 0)
            {
                throw new ArgumentOutOfRangeException("bitCount");
            }
            if (unitsToEncode < 0)
            {
                throw new ArgumentOutOfRangeException("unitsToEncode");
            }

            if (bitCount == 0)
            {
                //adjust if the bitcount is 0
                //(this makes bitCount 32)
                switch (encodingType)
                {
                    case GorillaEncodingType.Int:
                        {
                            bitCount = Native.BitsPerInt;
                            break;
                        }
                    case GorillaEncodingType.Short:
                        {
                            bitCount = Native.BitsPerShort;
                            break;
                        }
                    case GorillaEncodingType.Byte:
                        {
                            bitCount = Native.BitsPerByte;
                            break;
                        }
                    default:
                        {
                            throw new ArgumentException(StrokeCollectionSerializer.ISFDebugMessage("bogus GorillaEncodingType passed to compress"));
                        }
                }
            }

            //have the writer adapt to the List<byte> passed in and write to it
            BitStreamWriter writer = new BitStreamWriter(compressedData);
            while (!reader.EndOfStream && unitsToEncode > 0)
            {
                int data = GetDataFromReader(reader, encodingType);
                writer.Write((uint)data, bitCount);
                unitsToEncode--;
            }
        }
        /// <summary>
        /// Compress - compress the input[] into compressedData
        /// </summary>
        /// <param name="bitCount">The count of bits needed for all elements</param>
        /// <param name="input">input buffer</param>
        /// <param name="startInputIndex">offset into the input buffer</param>
        /// <param name="dtxf">data transform.  can be null</param>
        /// <param name="compressedData">The list of bytes to write the compressed input to</param>
        internal void Compress(int bitCount, int[] input, int startInputIndex, DeltaDelta dtxf, List<byte> compressedData)
        {
            if (null == input || null == compressedData)
            {
                throw new ArgumentNullException(StrokeCollectionSerializer.ISFDebugMessage("input or compressed data was null in Compress"));
            }
            if (bitCount < 0)
            {
                throw new ArgumentOutOfRangeException("bitCount");
            }

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

            //have the writer adapt to the List<byte> passed in and write to it
            BitStreamWriter writer = new BitStreamWriter(compressedData);
            if (null != dtxf)
            {
                int xfData = 0;
                int xfExtra = 0;
                for (int i = startInputIndex; i < input.Length; i++)
                {
                    dtxf.Transform(input[i], ref xfData, ref xfExtra);
                    if (xfExtra != 0)
                    {
                        throw new InvalidOperationException(StrokeCollectionSerializer.ISFDebugMessage("Transform returned unexpected results"));
                    }
                    writer.Write((uint)xfData, bitCount);
                }
            }
            else
            {
                for (int i = startInputIndex; i < input.Length; i++)
                {
                    writer.Write((uint)input[i], bitCount);
                }
            }
        }
        /// <summary>
        /// Encode
        /// </summary>
        /// <param name="data"></param>
        /// <param name="extra"></param>
        /// <param name="writer"></param>
        /// <returns>number of bits encoded, 0 for failure</returns>
        internal byte Encode(int data, int extra, BitStreamWriter writer)
        {
            if (writer == null)
            {
                throw new ArgumentNullException("writer");
            }
            if (data == 0)
            {
                writer.Write((byte)0, 1); //more efficent
                return (byte)1;
            }
            
            // First, encode extra if non-ZERO
            uint bitSize = _huffBits.GetSize();
            if (0 != extra)
            {
                // Prefix lenght is 1 more than table size
                byte extraPrefixLength = (byte)(bitSize + 1);
                int extraPrefix = ((1 << extraPrefixLength) - 2);

                writer.Write((uint)extraPrefix, (int)extraPrefixLength);

                // Encode the extra data first
                byte extraCodeLength = Encode(extra, 0, writer);
                // Encode the actual data next
                byte dataCodeLength = Encode(data, 0, writer);
                // Return the total code lenght
                return (byte)((int)extraPrefixLength + (int)extraCodeLength + (int)dataCodeLength);
            }
            // Find the absolute value of the data
            // IMPORTANT : It is extremely important that nData is uint, and NOT int
            // If it is int, the LONG_MIN will be encoded erroneaouly
            uint nData = (uint)MathHelper.AbsNoThrow(data);
            // Find the prefix lenght
            byte nPrefLen = 1;
            for (; (nPrefLen < bitSize) && (nData >= _mins[nPrefLen]); ++nPrefLen) ;
            // Get the data length
            uint nDataLen = _huffBits.GetBitsAtIndex((uint)nPrefLen - 1);

            // Find the prefix
            int nPrefix = ((1 << nPrefLen) - 2);
            // Append the prefix to the bit stream
            writer.Write((uint)nPrefix, (int)nPrefLen);
            // Find the data offset by lower bound
            // and append sign bit at LSB
            Debug.Assert(nDataLen > 0 && nDataLen - 1 <= Int32.MaxValue);
            int dataLenMinusOne = (int)(nDataLen - 1); //can't left shift by a uint, we need to thunk to an int
            nData = ((((nData - _mins[nPrefLen - 1]) & (uint)((1 << dataLenMinusOne) - 1)) << 1) | (uint)((data < 0) ? 1 : 0));
            // Append data into the bit streamdataLenMinusOne
            Debug.Assert(nDataLen <= Int32.MaxValue);
            writer.Write(nData, (int)nDataLen);

            return (byte)((uint)nPrefLen + nDataLen);
        }