Code:
/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / wpf / src / Shared / MS / Internal / Ink / BitStream.cs / 1305600 / BitStream.cs
using MS.Utility; using System; using System.IO; using System.Collections; using System.Collections.Generic; using System.Windows; using System.Diagnostics; using SR=MS.Internal.PresentationCore.SR; using SRID=MS.Internal.PresentationCore.SRID; namespace MS.Internal.Ink { ////// A stream-style reader for retrieving packed bits from a byte array /// ///This bits should packed into the leftmost position in each byte. /// For compatibility purposes with the v1 ISF encoder and decoder, the order of the /// packing must not be changed. This code is a from-scratch rewrite of the BitStream /// natice C++ class in the v1 Ink code, but still maintaining the same packing /// behavior. internal class BitStreamReader { ////// Create a new BitStreamReader to unpack the bits in a buffer of bytes /// /// Buffer of bytes internal BitStreamReader(byte[] buffer) { Debug.Assert(buffer != null); _byteArray = buffer; _bufferLengthInBits = (uint)buffer.Length * (uint)Native.BitsPerByte; } ////// Create a new BitStreamReader to unpack the bits in a buffer of bytes /// /// Buffer of bytes /// The index to start reading at internal BitStreamReader(byte[] buffer, int startIndex) { Debug.Assert(buffer != null); if (startIndex < 0 || startIndex >= buffer.Length) { throw new ArgumentOutOfRangeException("startIndex"); } _byteArray = buffer; _byteArrayIndex = startIndex; _bufferLengthInBits = (uint)(buffer.Length - startIndex) * (uint)Native.BitsPerByte; } ////// Create a new BitStreamReader to unpack the bits in a buffer of bytes /// and enforce a maximum buffer read length /// /// Buffer of bytes /// Maximum number of bytes to read from the buffer internal BitStreamReader(byte[] buffer, uint bufferLengthInBits) : this(buffer) { if (bufferLengthInBits > (buffer.Length * Native.BitsPerByte)) { throw new ArgumentOutOfRangeException("bufferLengthInBits", SR.Get(SRID.InvalidBufferLength)); } _bufferLengthInBits = bufferLengthInBits; } ////// Read a specified number of bits from the stream into a long /// internal long ReadUInt64(int countOfBits) { // we only support 1-64 bits currently, not multiple bytes, and not 0 bits if (countOfBits > Native.BitsPerLong || countOfBits <= 0) { throw new ArgumentOutOfRangeException("countOfBits", countOfBits, SR.Get(SRID.CountOfBitsOutOfRange)); } long retVal = 0; while (countOfBits > 0) { int countToRead = (int)Native.BitsPerByte; if (countOfBits < 8) { countToRead = countOfBits; } //make room retVal <<= countToRead; byte b = ReadByte(countToRead); retVal |= (long)b; countOfBits -= countToRead; } return retVal; } ////// Read a single UInt16 from the byte[] /// /// ///internal ushort ReadUInt16(int countOfBits) { // we only support 1-16 bits currently, not multiple bytes, and not 0 bits if (countOfBits > Native.BitsPerShort || countOfBits <= 0) { throw new ArgumentOutOfRangeException("countOfBits", countOfBits, SR.Get(SRID.CountOfBitsOutOfRange)); } ushort retVal = 0; while (countOfBits > 0) { int countToRead = (int)Native.BitsPerByte; if (countOfBits < 8) { countToRead = countOfBits; } //make room retVal <<= countToRead; byte b = ReadByte(countToRead); retVal |= (ushort)b; countOfBits -= countToRead; } return retVal; } /// /// Read a specified number of bits from the stream in reverse byte order /// internal uint ReadUInt16Reverse(int countOfBits) { // we only support 1-8 bits currently, not multiple bytes, and not 0 bits if (countOfBits > Native.BitsPerShort|| countOfBits <= 0) { throw new ArgumentOutOfRangeException("countOfBits", countOfBits, SR.Get(SRID.CountOfBitsOutOfRange)); } ushort retVal = 0; int fullBytesRead = 0; while (countOfBits > 0) { int countToRead = (int)Native.BitsPerByte; if (countOfBits < 8) { countToRead = countOfBits; } //make room ushort b = (ushort)ReadByte(countToRead); b <<= (fullBytesRead * Native.BitsPerByte); retVal |= b; fullBytesRead++; countOfBits -= countToRead; } return retVal; } ////// Read a specified number of bits from the stream into a single byte /// internal uint ReadUInt32(int countOfBits) { // we only support 1-8 bits currently, not multiple bytes, and not 0 bits if (countOfBits > Native.BitsPerInt || countOfBits <= 0) { throw new ArgumentOutOfRangeException("countOfBits", countOfBits, SR.Get(SRID.CountOfBitsOutOfRange)); } uint retVal = 0; while (countOfBits > 0) { int countToRead = (int)Native.BitsPerByte; if (countOfBits < 8) { countToRead = countOfBits; } //make room retVal <<= countToRead; byte b = ReadByte(countToRead); retVal |= (uint)b; countOfBits -= countToRead; } return retVal; } ////// Read a specified number of bits from the stream in reverse byte order /// internal uint ReadUInt32Reverse(int countOfBits) { // we only support 1-8 bits currently, not multiple bytes, and not 0 bits if (countOfBits > Native.BitsPerInt || countOfBits <= 0) { throw new ArgumentOutOfRangeException("countOfBits", countOfBits, SR.Get(SRID.CountOfBitsOutOfRange)); } uint retVal = 0; int fullBytesRead = 0; while (countOfBits > 0) { int countToRead = (int)Native.BitsPerByte; if (countOfBits < 8) { countToRead = countOfBits; } //make room uint b = (uint)ReadByte(countToRead); b <<= (fullBytesRead * Native.BitsPerByte); retVal |= b; fullBytesRead++; countOfBits -= countToRead; } return retVal; } ////// Reads a single bit from the buffer /// ///internal bool ReadBit() { byte b = ReadByte(1); return ((b & 1) == 1); } /// /// Read a specified number of bits from the stream into a single byte /// /// The number of bits to unpack ///A single byte that contains up to 8 packed bits ///For example, if 2 bits are read from the stream, then a full byte /// will be created with the least significant bits set to the 2 unpacked bits /// from the stream internal byte ReadByte(int countOfBits) { // if the end of the stream has been reached, then throw an exception if (EndOfStream) { throw new System.IO.EndOfStreamException(SR.Get(SRID.EndOfStreamReached)); } // we only support 1-8 bits currently, not multiple bytes, and not 0 bits if (countOfBits > Native.BitsPerByte || countOfBits <= 0) { throw new ArgumentOutOfRangeException("countOfBits", countOfBits, SR.Get(SRID.CountOfBitsOutOfRange)); } if (countOfBits > _bufferLengthInBits) { throw new ArgumentOutOfRangeException("countOfBits", countOfBits, SR.Get(SRID.CountOfBitsGreatThanRemainingBits)); } _bufferLengthInBits -= (uint)countOfBits; // initialize return byte to 0 before reading from the cache byte returnByte = 0; // if the partial bit cache contains more bits than requested, then read the // cache only if (_cbitsInPartialByte >= countOfBits) { // retrieve the requested count of most significant bits from the cache // and store them in the least significant positions in the return byte int rightShiftPartialByteBy = Native.BitsPerByte - countOfBits; returnByte = (byte)(_partialByte >> rightShiftPartialByteBy); // reposition any unused portion of the cache in the most significant part of the bit cache unchecked // disable overflow checking since we are intentionally throwing away // the significant bits { _partialByte <<= countOfBits; } // update the bit count in the cache _cbitsInPartialByte -= countOfBits; } // otherwise, we need to retrieve more full bytes from the stream else { // retrieve the next full byte from the stream byte nextByte = _byteArray[_byteArrayIndex]; _byteArrayIndex++; //right shift partial byte to get it ready to or with the partial next byte int rightShiftPartialByteBy = Native.BitsPerByte - countOfBits; returnByte = (byte)(_partialByte >> rightShiftPartialByteBy); // now copy the remaining chunk of the newly retrieved full byte int rightShiftNextByteBy = Math.Abs((countOfBits - _cbitsInPartialByte) - Native.BitsPerByte); returnByte |= (byte)(nextByte >> rightShiftNextByteBy); // update the partial bit cache with the remainder of the newly retrieved full byte unchecked // disable overflow checking since we are intentionally throwing away // the significant bits { _partialByte = (byte)(nextByte << (countOfBits - _cbitsInPartialByte)); } _cbitsInPartialByte = Native.BitsPerByte - (countOfBits - _cbitsInPartialByte); } return returnByte; } ////// Since the return value of Read cannot distinguish between valid and invalid /// data (e.g. 8 bits set), the EndOfStream property detects when there is no more /// data to read. /// ///True if stream end has been reached internal bool EndOfStream { get { return 0 == _bufferLengthInBits; } } ////// The current read index in the array /// internal int CurrentIndex { get { //_byteArrayIndex is always advanced to the next index // so we always decrement before returning return _byteArrayIndex - 1; } } // Privates // reference to the source byte buffer to read from private byte[] _byteArray = null; // maximum length of buffer to read in bits private uint _bufferLengthInBits = 0; // the index in the source buffer for the next byte to be read private int _byteArrayIndex = 0; // since the bits from multiple inputs can be packed into a single byte // (e.g. 2 bits per input fits 4 per byte), we use this field as a cache // of the remaining partial bits. private byte _partialByte = 0; // the number of bits (partial byte) left to read in the overlapped byte field private int _cbitsInPartialByte = 0; } ////// A stream-like writer for packing bits into a byte buffer /// ///This class is to be used with the BitStreamReader for reading /// and writing bytes. Note that the bytes should be read in the same order /// and lengths as they were written to retrieve the same values. /// See remarks in BitStreamReader regarding compatibility with the native C++ /// BitStream class. internal class BitStreamWriter { ////// Create a new bit writer that writes to the target buffer /// /// internal BitStreamWriter(ListbufferToWriteTo) { if (bufferToWriteTo == null) { throw new ArgumentNullException("bufferToWriteTo"); } _targetBuffer = bufferToWriteTo; } /// /// Writes the count of bits from the int to the left packed buffer /// /// /// internal void Write(uint bits, int countOfBits) { // validate that a subset of the bits in a single byte are being written if (countOfBits <= 0 || countOfBits > Native.BitsPerInt) throw new ArgumentOutOfRangeException("countOfBits", countOfBits, SR.Get(SRID.CountOfBitsOutOfRange)); // calculate the number of full bytes // Example: 10 bits would require 1 full byte int fullBytes = countOfBits / Native.BitsPerByte; // calculate the number of bits that spill beyond the full byte boundary // Example: 10 buttons would require 2 extra bits (8 fit in a full byte) int bitsToWrite = countOfBits % Native.BitsPerByte; for (; fullBytes >= 0; fullBytes--) { byte byteOfData = (byte)(bits >> (fullBytes * Native.BitsPerByte)); // // write 8 or less bytes to the bitwriter // checking for 0 handles the case where we're writing 8, 16 or 24 bytes // and bitsToWrite is initialize to zero // if (bitsToWrite > 0) { Write(byteOfData, bitsToWrite); } if (fullBytes > 0) { bitsToWrite = Native.BitsPerByte; } } } ////// Writes the count of bits from the int to the buffer in reverse order /// /// /// internal void WriteReverse(uint bits, int countOfBits) { // validate that a subset of the bits in a single byte are being written if (countOfBits <= 0 || countOfBits > Native.BitsPerInt) throw new ArgumentOutOfRangeException("countOfBits", countOfBits, SR.Get(SRID.CountOfBitsOutOfRange)); // calculate the number of full bytes // Example: 10 bits would require 1 full byte int fullBytes = countOfBits / Native.BitsPerByte; // calculate the number of bits that spill beyond the full byte boundary // Example: 10 buttons would require 2 extra bits (8 fit in a full byte) int bitsToWrite = countOfBits % Native.BitsPerByte; if (bitsToWrite > 0) { fullBytes++; } for (int x = 0; x < fullBytes; x++) { byte byteOfData = (byte)(bits >> (x * Native.BitsPerByte)); Write(byteOfData, Native.BitsPerByte); } } ////// Write a specific number of bits from byte input into the stream /// /// The byte to read the bits from /// The number of bits to read internal void Write(byte bits, int countOfBits) { // validate that a subset of the bits in a single byte are being written if (countOfBits <= 0 || countOfBits > Native.BitsPerByte) throw new ArgumentOutOfRangeException("countOfBits", countOfBits, SR.Get(SRID.CountOfBitsOutOfRange)); byte buffer; // if there is remaining bits in the last byte in the stream // then use those first if (_remaining > 0) { // retrieve the last byte from the stream, update it, and then replace it buffer = _targetBuffer[_targetBuffer.Count - 1]; // if the remaining bits aren't enough then just copy the significant bits // of the input into the remainder if (countOfBits > _remaining) { buffer |= (byte)((bits & (0xFF >> (Native.BitsPerByte - countOfBits))) >> (countOfBits - _remaining)); } // otherwise, copy the entire set of input bits into the remainder else { buffer |= (byte)((bits & (0xFF >> (Native.BitsPerByte - countOfBits))) << (_remaining - countOfBits)); } _targetBuffer[_targetBuffer.Count - 1] = buffer; } // if the remainder wasn't large enough to hold the entire input set if (countOfBits > _remaining) { // then copy the uncontained portion of the input set into a temporary byte _remaining = Native.BitsPerByte - (countOfBits - _remaining); unchecked // disable overflow checking since we are intentionally throwing away // the significant bits { buffer = (byte)(bits << _remaining); } // and add it to the target buffer _targetBuffer.Add(buffer); } else { // otherwise, simply update the amount of remaining bits we have to spare _remaining -= countOfBits; } } // the buffer that the bits are written into private List_targetBuffer = null; // number of free bits remaining in the last byte added to the target buffer private int _remaining = 0; } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved. using MS.Utility; using System; using System.IO; using System.Collections; using System.Collections.Generic; using System.Windows; using System.Diagnostics; using SR=MS.Internal.PresentationCore.SR; using SRID=MS.Internal.PresentationCore.SRID; namespace MS.Internal.Ink { /// /// A stream-style reader for retrieving packed bits from a byte array /// ///This bits should packed into the leftmost position in each byte. /// For compatibility purposes with the v1 ISF encoder and decoder, the order of the /// packing must not be changed. This code is a from-scratch rewrite of the BitStream /// natice C++ class in the v1 Ink code, but still maintaining the same packing /// behavior. internal class BitStreamReader { ////// Create a new BitStreamReader to unpack the bits in a buffer of bytes /// /// Buffer of bytes internal BitStreamReader(byte[] buffer) { Debug.Assert(buffer != null); _byteArray = buffer; _bufferLengthInBits = (uint)buffer.Length * (uint)Native.BitsPerByte; } ////// Create a new BitStreamReader to unpack the bits in a buffer of bytes /// /// Buffer of bytes /// The index to start reading at internal BitStreamReader(byte[] buffer, int startIndex) { Debug.Assert(buffer != null); if (startIndex < 0 || startIndex >= buffer.Length) { throw new ArgumentOutOfRangeException("startIndex"); } _byteArray = buffer; _byteArrayIndex = startIndex; _bufferLengthInBits = (uint)(buffer.Length - startIndex) * (uint)Native.BitsPerByte; } ////// Create a new BitStreamReader to unpack the bits in a buffer of bytes /// and enforce a maximum buffer read length /// /// Buffer of bytes /// Maximum number of bytes to read from the buffer internal BitStreamReader(byte[] buffer, uint bufferLengthInBits) : this(buffer) { if (bufferLengthInBits > (buffer.Length * Native.BitsPerByte)) { throw new ArgumentOutOfRangeException("bufferLengthInBits", SR.Get(SRID.InvalidBufferLength)); } _bufferLengthInBits = bufferLengthInBits; } ////// Read a specified number of bits from the stream into a long /// internal long ReadUInt64(int countOfBits) { // we only support 1-64 bits currently, not multiple bytes, and not 0 bits if (countOfBits > Native.BitsPerLong || countOfBits <= 0) { throw new ArgumentOutOfRangeException("countOfBits", countOfBits, SR.Get(SRID.CountOfBitsOutOfRange)); } long retVal = 0; while (countOfBits > 0) { int countToRead = (int)Native.BitsPerByte; if (countOfBits < 8) { countToRead = countOfBits; } //make room retVal <<= countToRead; byte b = ReadByte(countToRead); retVal |= (long)b; countOfBits -= countToRead; } return retVal; } ////// Read a single UInt16 from the byte[] /// /// ///internal ushort ReadUInt16(int countOfBits) { // we only support 1-16 bits currently, not multiple bytes, and not 0 bits if (countOfBits > Native.BitsPerShort || countOfBits <= 0) { throw new ArgumentOutOfRangeException("countOfBits", countOfBits, SR.Get(SRID.CountOfBitsOutOfRange)); } ushort retVal = 0; while (countOfBits > 0) { int countToRead = (int)Native.BitsPerByte; if (countOfBits < 8) { countToRead = countOfBits; } //make room retVal <<= countToRead; byte b = ReadByte(countToRead); retVal |= (ushort)b; countOfBits -= countToRead; } return retVal; } /// /// Read a specified number of bits from the stream in reverse byte order /// internal uint ReadUInt16Reverse(int countOfBits) { // we only support 1-8 bits currently, not multiple bytes, and not 0 bits if (countOfBits > Native.BitsPerShort|| countOfBits <= 0) { throw new ArgumentOutOfRangeException("countOfBits", countOfBits, SR.Get(SRID.CountOfBitsOutOfRange)); } ushort retVal = 0; int fullBytesRead = 0; while (countOfBits > 0) { int countToRead = (int)Native.BitsPerByte; if (countOfBits < 8) { countToRead = countOfBits; } //make room ushort b = (ushort)ReadByte(countToRead); b <<= (fullBytesRead * Native.BitsPerByte); retVal |= b; fullBytesRead++; countOfBits -= countToRead; } return retVal; } ////// Read a specified number of bits from the stream into a single byte /// internal uint ReadUInt32(int countOfBits) { // we only support 1-8 bits currently, not multiple bytes, and not 0 bits if (countOfBits > Native.BitsPerInt || countOfBits <= 0) { throw new ArgumentOutOfRangeException("countOfBits", countOfBits, SR.Get(SRID.CountOfBitsOutOfRange)); } uint retVal = 0; while (countOfBits > 0) { int countToRead = (int)Native.BitsPerByte; if (countOfBits < 8) { countToRead = countOfBits; } //make room retVal <<= countToRead; byte b = ReadByte(countToRead); retVal |= (uint)b; countOfBits -= countToRead; } return retVal; } ////// Read a specified number of bits from the stream in reverse byte order /// internal uint ReadUInt32Reverse(int countOfBits) { // we only support 1-8 bits currently, not multiple bytes, and not 0 bits if (countOfBits > Native.BitsPerInt || countOfBits <= 0) { throw new ArgumentOutOfRangeException("countOfBits", countOfBits, SR.Get(SRID.CountOfBitsOutOfRange)); } uint retVal = 0; int fullBytesRead = 0; while (countOfBits > 0) { int countToRead = (int)Native.BitsPerByte; if (countOfBits < 8) { countToRead = countOfBits; } //make room uint b = (uint)ReadByte(countToRead); b <<= (fullBytesRead * Native.BitsPerByte); retVal |= b; fullBytesRead++; countOfBits -= countToRead; } return retVal; } ////// Reads a single bit from the buffer /// ///internal bool ReadBit() { byte b = ReadByte(1); return ((b & 1) == 1); } /// /// Read a specified number of bits from the stream into a single byte /// /// The number of bits to unpack ///A single byte that contains up to 8 packed bits ///For example, if 2 bits are read from the stream, then a full byte /// will be created with the least significant bits set to the 2 unpacked bits /// from the stream internal byte ReadByte(int countOfBits) { // if the end of the stream has been reached, then throw an exception if (EndOfStream) { throw new System.IO.EndOfStreamException(SR.Get(SRID.EndOfStreamReached)); } // we only support 1-8 bits currently, not multiple bytes, and not 0 bits if (countOfBits > Native.BitsPerByte || countOfBits <= 0) { throw new ArgumentOutOfRangeException("countOfBits", countOfBits, SR.Get(SRID.CountOfBitsOutOfRange)); } if (countOfBits > _bufferLengthInBits) { throw new ArgumentOutOfRangeException("countOfBits", countOfBits, SR.Get(SRID.CountOfBitsGreatThanRemainingBits)); } _bufferLengthInBits -= (uint)countOfBits; // initialize return byte to 0 before reading from the cache byte returnByte = 0; // if the partial bit cache contains more bits than requested, then read the // cache only if (_cbitsInPartialByte >= countOfBits) { // retrieve the requested count of most significant bits from the cache // and store them in the least significant positions in the return byte int rightShiftPartialByteBy = Native.BitsPerByte - countOfBits; returnByte = (byte)(_partialByte >> rightShiftPartialByteBy); // reposition any unused portion of the cache in the most significant part of the bit cache unchecked // disable overflow checking since we are intentionally throwing away // the significant bits { _partialByte <<= countOfBits; } // update the bit count in the cache _cbitsInPartialByte -= countOfBits; } // otherwise, we need to retrieve more full bytes from the stream else { // retrieve the next full byte from the stream byte nextByte = _byteArray[_byteArrayIndex]; _byteArrayIndex++; //right shift partial byte to get it ready to or with the partial next byte int rightShiftPartialByteBy = Native.BitsPerByte - countOfBits; returnByte = (byte)(_partialByte >> rightShiftPartialByteBy); // now copy the remaining chunk of the newly retrieved full byte int rightShiftNextByteBy = Math.Abs((countOfBits - _cbitsInPartialByte) - Native.BitsPerByte); returnByte |= (byte)(nextByte >> rightShiftNextByteBy); // update the partial bit cache with the remainder of the newly retrieved full byte unchecked // disable overflow checking since we are intentionally throwing away // the significant bits { _partialByte = (byte)(nextByte << (countOfBits - _cbitsInPartialByte)); } _cbitsInPartialByte = Native.BitsPerByte - (countOfBits - _cbitsInPartialByte); } return returnByte; } ////// Since the return value of Read cannot distinguish between valid and invalid /// data (e.g. 8 bits set), the EndOfStream property detects when there is no more /// data to read. /// ///True if stream end has been reached internal bool EndOfStream { get { return 0 == _bufferLengthInBits; } } ////// The current read index in the array /// internal int CurrentIndex { get { //_byteArrayIndex is always advanced to the next index // so we always decrement before returning return _byteArrayIndex - 1; } } // Privates // reference to the source byte buffer to read from private byte[] _byteArray = null; // maximum length of buffer to read in bits private uint _bufferLengthInBits = 0; // the index in the source buffer for the next byte to be read private int _byteArrayIndex = 0; // since the bits from multiple inputs can be packed into a single byte // (e.g. 2 bits per input fits 4 per byte), we use this field as a cache // of the remaining partial bits. private byte _partialByte = 0; // the number of bits (partial byte) left to read in the overlapped byte field private int _cbitsInPartialByte = 0; } ////// A stream-like writer for packing bits into a byte buffer /// ///This class is to be used with the BitStreamReader for reading /// and writing bytes. Note that the bytes should be read in the same order /// and lengths as they were written to retrieve the same values. /// See remarks in BitStreamReader regarding compatibility with the native C++ /// BitStream class. internal class BitStreamWriter { ////// Create a new bit writer that writes to the target buffer /// /// internal BitStreamWriter(ListbufferToWriteTo) { if (bufferToWriteTo == null) { throw new ArgumentNullException("bufferToWriteTo"); } _targetBuffer = bufferToWriteTo; } /// /// Writes the count of bits from the int to the left packed buffer /// /// /// internal void Write(uint bits, int countOfBits) { // validate that a subset of the bits in a single byte are being written if (countOfBits <= 0 || countOfBits > Native.BitsPerInt) throw new ArgumentOutOfRangeException("countOfBits", countOfBits, SR.Get(SRID.CountOfBitsOutOfRange)); // calculate the number of full bytes // Example: 10 bits would require 1 full byte int fullBytes = countOfBits / Native.BitsPerByte; // calculate the number of bits that spill beyond the full byte boundary // Example: 10 buttons would require 2 extra bits (8 fit in a full byte) int bitsToWrite = countOfBits % Native.BitsPerByte; for (; fullBytes >= 0; fullBytes--) { byte byteOfData = (byte)(bits >> (fullBytes * Native.BitsPerByte)); // // write 8 or less bytes to the bitwriter // checking for 0 handles the case where we're writing 8, 16 or 24 bytes // and bitsToWrite is initialize to zero // if (bitsToWrite > 0) { Write(byteOfData, bitsToWrite); } if (fullBytes > 0) { bitsToWrite = Native.BitsPerByte; } } } ////// Writes the count of bits from the int to the buffer in reverse order /// /// /// internal void WriteReverse(uint bits, int countOfBits) { // validate that a subset of the bits in a single byte are being written if (countOfBits <= 0 || countOfBits > Native.BitsPerInt) throw new ArgumentOutOfRangeException("countOfBits", countOfBits, SR.Get(SRID.CountOfBitsOutOfRange)); // calculate the number of full bytes // Example: 10 bits would require 1 full byte int fullBytes = countOfBits / Native.BitsPerByte; // calculate the number of bits that spill beyond the full byte boundary // Example: 10 buttons would require 2 extra bits (8 fit in a full byte) int bitsToWrite = countOfBits % Native.BitsPerByte; if (bitsToWrite > 0) { fullBytes++; } for (int x = 0; x < fullBytes; x++) { byte byteOfData = (byte)(bits >> (x * Native.BitsPerByte)); Write(byteOfData, Native.BitsPerByte); } } ////// Write a specific number of bits from byte input into the stream /// /// The byte to read the bits from /// The number of bits to read internal void Write(byte bits, int countOfBits) { // validate that a subset of the bits in a single byte are being written if (countOfBits <= 0 || countOfBits > Native.BitsPerByte) throw new ArgumentOutOfRangeException("countOfBits", countOfBits, SR.Get(SRID.CountOfBitsOutOfRange)); byte buffer; // if there is remaining bits in the last byte in the stream // then use those first if (_remaining > 0) { // retrieve the last byte from the stream, update it, and then replace it buffer = _targetBuffer[_targetBuffer.Count - 1]; // if the remaining bits aren't enough then just copy the significant bits // of the input into the remainder if (countOfBits > _remaining) { buffer |= (byte)((bits & (0xFF >> (Native.BitsPerByte - countOfBits))) >> (countOfBits - _remaining)); } // otherwise, copy the entire set of input bits into the remainder else { buffer |= (byte)((bits & (0xFF >> (Native.BitsPerByte - countOfBits))) << (_remaining - countOfBits)); } _targetBuffer[_targetBuffer.Count - 1] = buffer; } // if the remainder wasn't large enough to hold the entire input set if (countOfBits > _remaining) { // then copy the uncontained portion of the input set into a temporary byte _remaining = Native.BitsPerByte - (countOfBits - _remaining); unchecked // disable overflow checking since we are intentionally throwing away // the significant bits { buffer = (byte)(bits << _remaining); } // and add it to the target buffer _targetBuffer.Add(buffer); } else { // otherwise, simply update the amount of remaining bits we have to spare _remaining -= countOfBits; } } // the buffer that the bits are written into private List_targetBuffer = null; // number of free bits remaining in the last byte added to the target buffer private int _remaining = 0; } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- Listen.cs
- ListViewHitTestInfo.cs
- MetadataUtil.cs
- GrammarBuilderWildcard.cs
- ExpressionEditorSheet.cs
- XPathNodeIterator.cs
- RegionIterator.cs
- FieldBuilder.cs
- ConfigurationManagerInternal.cs
- ApplicationInterop.cs
- LayoutEvent.cs
- DeflateStream.cs
- DataControlLinkButton.cs
- DBParameter.cs
- DbConnectionPoolCounters.cs
- JavaScriptObjectDeserializer.cs
- PropertyGrid.cs
- DataGridViewCell.cs
- StrokeNodeData.cs
- followingquery.cs
- AssociativeAggregationOperator.cs
- HostingEnvironmentSection.cs
- StoreItemCollection.cs
- HttpWriter.cs
- CloudCollection.cs
- HttpCachePolicy.cs
- DebugView.cs
- SplitContainer.cs
- ProfileSettingsCollection.cs
- WebPartCloseVerb.cs
- XmlCustomFormatter.cs
- DiagnosticsConfigurationHandler.cs
- WebResourceAttribute.cs
- Closure.cs
- CngUIPolicy.cs
- NameScope.cs
- KeyManager.cs
- HtmlControlPersistable.cs
- EventLogEntry.cs
- DataPager.cs
- DataBinder.cs
- SQLMembershipProvider.cs
- XXXInfos.cs
- GridViewItemAutomationPeer.cs
- PagePropertiesChangingEventArgs.cs
- UnsafeNativeMethodsPenimc.cs
- InkCollectionBehavior.cs
- WindowsGraphicsCacheManager.cs
- ServiceHttpHandlerFactory.cs
- ExpressionBindingCollection.cs
- SqlDataSourceConfigureSelectPanel.cs
- CopyNodeSetAction.cs
- SubMenuStyleCollection.cs
- Clause.cs
- StateBag.cs
- DataControlFieldTypeEditor.cs
- TokenBasedSetEnumerator.cs
- invalidudtexception.cs
- Avt.cs
- ButtonBase.cs
- ManagedIStream.cs
- QuaternionValueSerializer.cs
- NavigationEventArgs.cs
- URI.cs
- DataGridViewColumnHeaderCell.cs
- XmlQueryRuntime.cs
- BadImageFormatException.cs
- XamlClipboardData.cs
- DataControlCommands.cs
- DataContext.cs
- FramingChannels.cs
- glyphs.cs
- _AcceptOverlappedAsyncResult.cs
- ProcessManager.cs
- DoubleStorage.cs
- shaperfactoryquerycachekey.cs
- Utils.cs
- NegationPusher.cs
- DataGridViewUtilities.cs
- Duration.cs
- ElementAtQueryOperator.cs
- BrowserCapabilitiesCodeGenerator.cs
- TriggerAction.cs
- _SingleItemRequestCache.cs
- ProcessInfo.cs
- securitycriticaldata.cs
- TdsRecordBufferSetter.cs
- ImageMetadata.cs
- Send.cs
- ProxyAttribute.cs
- CommandBinding.cs
- Action.cs
- PartialCachingControl.cs
- IISUnsafeMethods.cs
- NameTable.cs
- ListBox.cs
- UnsafeNativeMethods.cs
- AsyncOperation.cs
- AppDomainEvidenceFactory.cs
- BaseServiceProvider.cs