public void VerifyEncoding_largecorpus()
        {
            string input  = TestResources.RFC5_Text;
            int    len    = input.Length;
            var    data   = new MemoryStream();
            var    writer = new BitBinaryWriter(data);
            var    reader = new BitBinaryReader(data);

            var compressor = new DynamicHuffman <char>(OriginalNYT);

            for (int i = 0; i < len; ++i)
            {
                compressor.WriteCode(input[i], writer.Write, writer.Write);
            }
            writer.Flush();
            data.Position = 0;

            var decompressor = new DynamicHuffman <char>(OriginalNYT);

            for (int i = 0; i < len; ++i)
            {
                Assert.AreEqual(input[i], decompressor.GetSymbol(reader.ReadBoolean, reader.ReadChar));
            }
            Assert.AreEqual(data.Position, data.Length);
        }
        public void BaseStream_NotBitStream()
        {
            var data   = new byte[] { 0x23, 0x72, 0x64, 0xe3, 0x11, 0xd1, 0x4a, 0x9c, 0xb6, 0x02 };
            var stream = new MemoryStream(data);
            var writer = new BitBinaryWriter(stream);

            Assert.AreNotSame(stream, writer.BaseStream);
        }
        private static bool WriteDouble(BitBinaryWriter writer, double value, DoubleValueState previousValue, out DoubleValueState newValue)
        {
            newValue       = previousValue;
            newValue.Value = value;

            var xor = BitConverter.DoubleToInt64Bits(value) ^ BitConverter.DoubleToInt64Bits(previousValue.Value);

            if (xor == 0)
            {
                writer.WriteBit(false);
            }
            else
            {
                writer.WriteBit(true);

                var leadingZeros  = (sbyte)BitAggregateMagic.CountLeadingZeros(xor);
                var trailingZeros = (sbyte)BitAggregateMagic.CountTrailingZeros(xor);

                if (leadingZeros > MaxLeadingZerosLength)
                {
                    leadingZeros = MaxLeadingZerosLength;
                }

                int blockSize    = 64 - leadingZeros - trailingZeros;
                int expectedSize = NumBitsToEncodeNumLeadingZeros + NumBitsToEncodeNumMeaningfulBits + blockSize;
                int previousBlockInformationSize = 64 - previousValue.TrailingZeros - previousValue.LeadingZeros;

                // The block position is set by the first non-zero XOR value. previousValue.LeadingZeros was initialized to -1s to start with.
                if (previousValue.LeadingZeros > 0 && leadingZeros >= previousValue.LeadingZeros && trailingZeros >= previousValue.TrailingZeros && previousBlockInformationSize < expectedSize)
                {
                    writer.WriteBit(false);

                    // there are at least as many leading zeros and as many trailing zeros as with the previous value, reuse the block position.
                    var numMeaningfulBits = BitAggregateMagic.NumBitsInLongInteger - previousValue.LeadingZeros - previousValue.TrailingZeros;

                    writer.WriteBits(xor, numMeaningfulBits, previousValue.TrailingZeros);
                }
                else
                {
                    // start a new block position
                    writer.WriteBit(true);

                    writer.WriteBits(leadingZeros, NumBitsToEncodeNumLeadingZeros, 0);

                    newValue.LeadingZeros = leadingZeros;

                    var numMeaningfulBits = BitAggregateMagic.NumBitsInLongInteger - leadingZeros - trailingZeros;
                    writer.WriteBits(numMeaningfulBits, NumBitsToEncodeNumMeaningfulBits, 0);

                    newValue.TrailingZeros = trailingZeros;

                    writer.WriteBits(xor, numMeaningfulBits, trailingZeros);
                }
            }

            return(true);
        }
        public void BitBinaryWriterCompatible()
        {
            var stream = new MemoryStream();
            var writer = new BitBinaryWriter(stream);
            var reader = new BitBinaryReader(stream);

            foreach (TestValue value in _testValuesWithBits)
            {
                value.Write(writer);
            }

            writer.Flush();
            stream.Position = 0;

            foreach (TestValue value in _testValuesWithBits)
            {
                value.Read(reader);
            }
        }
        public static unsafe void Serialize(BinaryWriter writer, double *values, int count)
        {
            // Reserve one byte for future versioning.
            writer.Write((byte)1);
            SerializationUtils.WriteUInt32AsBase128(writer, (uint)count);
            if (count > 0)
            {
                BitBinaryWriter bitWriter     = new BitBinaryWriter(writer);
                var             previousState = new DoubleValueState(0, -1, -1);

                for (int i = 0; i < count; ++i)
                {
                    DoubleValueState newState;
                    WriteDouble(bitWriter, values[i], previousState, out newState);
                    previousState = newState;
                }

                bitWriter.Flush();
            }
        }
        public void VerifyEncoding_astrachan_()
        {
            string input  = "astrachan_";
            var    data   = new MemoryStream();
            var    writer = new BitBinaryWriter(data);
            var    reader = new BitBinaryReader(data);

            var compressor = new DynamicHuffman <char>(OriginalNYT);

            for (int i = 0; i < input.Length; ++i)
            {
                compressor.WriteCode(input[i], writer.Write, writer.Write);
            }
            writer.Flush();
            data.Position = 0;

            var decompressor = new DynamicHuffman <char>(OriginalNYT);

            for (int i = 0; i < input.Length; ++i)
            {
                Assert.AreEqual(input[i], decompressor.GetSymbol(reader.ReadBoolean, reader.ReadChar));
            }
            Assert.AreEqual(data.Position, data.Length);
        }