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); }
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]); }
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]); }
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); }
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); }
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); } }
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()); }
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); } }
/** * 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; } }
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); }
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); } }
/// <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); } } }
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()); }
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); }
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); }
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); }
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); }
/// <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()); }
/// <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); }