Code:
/ 4.0 / 4.0 / untmp / 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.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- HtmlInputHidden.cs
- WindowsSlider.cs
- PasswordRecovery.cs
- TypeConverter.cs
- TextMarkerSource.cs
- MenuItemCollection.cs
- TemplateContent.cs
- LogFlushAsyncResult.cs
- X509IssuerSerialKeyIdentifierClause.cs
- CodeExporter.cs
- BaseCAMarshaler.cs
- CodeSnippetStatement.cs
- DoubleConverter.cs
- WinFormsSpinner.cs
- Currency.cs
- XMLSchema.cs
- PropertyValueChangedEvent.cs
- LoginCancelEventArgs.cs
- DESCryptoServiceProvider.cs
- SecurityDescriptor.cs
- GridItemCollection.cs
- StrongName.cs
- InstanceOwner.cs
- QilBinary.cs
- ManualResetEvent.cs
- Bidi.cs
- XmlnsCompatibleWithAttribute.cs
- SmtpReplyReaderFactory.cs
- ColorTransformHelper.cs
- TextRangeEditTables.cs
- BoundPropertyEntry.cs
- XmlValidatingReader.cs
- __Error.cs
- AccessViolationException.cs
- TypefaceMap.cs
- Substitution.cs
- MenuItemBinding.cs
- AddInIpcChannel.cs
- PeerNameRegistration.cs
- CodeTypeDeclarationCollection.cs
- SamlDelegatingWriter.cs
- ClientConfigPaths.cs
- GridToolTip.cs
- StylusShape.cs
- BitmapDecoder.cs
- WebPageTraceListener.cs
- ImageUrlEditor.cs
- VirtualizingPanel.cs
- RectKeyFrameCollection.cs
- SurrogateEncoder.cs
- UserControl.cs
- AssemblyNameProxy.cs
- XamlInt32CollectionSerializer.cs
- HWStack.cs
- NullableDoubleMinMaxAggregationOperator.cs
- NumberFormatter.cs
- SparseMemoryStream.cs
- METAHEADER.cs
- SamlSecurityToken.cs
- Typeface.cs
- BridgeDataRecord.cs
- ToolStripItemDataObject.cs
- DispatchWrapper.cs
- ValueExpressions.cs
- LinqDataSourceInsertEventArgs.cs
- HtmlLink.cs
- Deserializer.cs
- StylusSystemGestureEventArgs.cs
- EastAsianLunisolarCalendar.cs
- StackSpiller.Temps.cs
- SendReply.cs
- NegatedCellConstant.cs
- ThrowHelper.cs
- MimeParameterWriter.cs
- ExpressionVisitor.cs
- WinFormsSecurity.cs
- fixedPageContentExtractor.cs
- ExternalException.cs
- XPathDocumentIterator.cs
- DataServiceQueryException.cs
- ReliabilityContractAttribute.cs
- base64Transforms.cs
- Win32Native.cs
- FormViewInsertedEventArgs.cs
- Empty.cs
- UserControlBuildProvider.cs
- OutOfMemoryException.cs
- ImageAnimator.cs
- TokenBasedSetEnumerator.cs
- StructuralCache.cs
- PropertyRef.cs
- XPathNavigatorKeyComparer.cs
- IssuedTokensHeader.cs
- Site.cs
- FormatConvertedBitmap.cs
- ComponentEditorForm.cs
- MsmqReceiveParameters.cs
- ResumeStoryboard.cs
- PrimitiveOperationFormatter.cs
- TreeNodeCollection.cs