/// <summary>Flush the cache to <see cref="BaseStream"/> with <see cref="kWordByteCount"/> or fewer bytes bytes</summary> void FlushCache() { #if !CONTRACTS_FULL_SHIM // can't do this with our shim! ValueAtReturn sets out param to default ON ENTRY Contract.Ensures(Contract.ValueAtReturn(out mCache) == 0); Contract.Ensures(Contract.ValueAtReturn(out mCacheBitIndex) == 0); #endif if (mCacheBitIndex == 0) // no bits to flush! { Contract.Assert(mCache == 0, "Why is there data in the cache?"); return; } mCacheBitsStreamedCount = 0; int byte_count = (mCacheBitIndex - 1) >> Bits.kByteBitShift; // number of bytes to try and write int shift = kWordBitCount - Bits.kByteBitCount; // start shifting from the MSB while ( /*!IsEndOfStream &&*/ byte_count >= 0) { mIoBuffer[0] = (byte)(mCache >> shift); BaseStream.Write(mIoBuffer, 0, sizeof(byte)); --byte_count; shift -= Bits.kByteBitCount; mCacheBitsStreamedCount += Bits.kByteBitCount; } if (byte_count != -1 && ThrowOnOverflow.CanWrite()) { throw new System.IO.EndOfStreamException("Tried to write more bits than the stream has/can see"); } mCache = 0; mCacheBitIndex = 0; }
// #REVIEW: change mIoBuffer to be kWordByteCount and do an entire Read/Write() instead of looping? // #REVIEW: maybe change the ReadWord implementation to not automatically populate the next word... #region Cache operations /// <summary>Fill the cache with <see cref="kWordByteCount"/> or fewer bytes bytes</summary> void FillCache() { mCache = 0; mCacheBitIndex = 0; mCacheBitsStreamedCount = 0; int byte_count = kWordByteCount - 1; // number of bytes to try and read int shift = kWordBitCount - Bits.kByteBitCount; // start shifting to the MSB while (!IsEndOfStream && byte_count >= 0 && BaseStream.Read(mIoBuffer, 0, sizeof(byte)) != 0) { mCache |= ((TWord)mIoBuffer[0]) << shift; --byte_count; shift -= Bits.kByteBitCount; mCacheBitsStreamedCount += Bits.kByteBitCount; } if (byte_count != -1 && ThrowOnOverflow.CanRead()) { throw new System.IO.EndOfStreamException("Tried to read more bits than the stream has/can see"); } }