other-licenses/7zstub/src/7zip/Common/LSBFDecoder.h

Tue, 06 Jan 2015 21:39:09 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Tue, 06 Jan 2015 21:39:09 +0100
branch
TOR_BUG_9701
changeset 8
97036ab72558
permissions
-rw-r--r--

Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

michael@0 1 // LSBFDecoder.h
michael@0 2
michael@0 3 #ifndef __STREAM_LSBFDECODER_H
michael@0 4 #define __STREAM_LSBFDECODER_H
michael@0 5
michael@0 6 #include "../IStream.h"
michael@0 7
michael@0 8 namespace NStream {
michael@0 9 namespace NLSBF {
michael@0 10
michael@0 11 const int kNumBigValueBits = 8 * 4;
michael@0 12
michael@0 13 const int kNumValueBytes = 3;
michael@0 14 const int kNumValueBits = 8 * kNumValueBytes;
michael@0 15
michael@0 16 const UInt32 kMask = (1 << kNumValueBits) - 1;
michael@0 17
michael@0 18 extern Byte kInvertTable[256];
michael@0 19 // the Least Significant Bit of byte is First
michael@0 20
michael@0 21 template<class TInByte>
michael@0 22 class CBaseDecoder
michael@0 23 {
michael@0 24 protected:
michael@0 25 int m_BitPos;
michael@0 26 UInt32 m_Value;
michael@0 27 TInByte m_Stream;
michael@0 28 public:
michael@0 29 UInt32 NumExtraBytes;
michael@0 30 bool Create(UInt32 bufferSize) { return m_Stream.Create(bufferSize); }
michael@0 31 void SetStream(ISequentialInStream *inStream) { m_Stream.SetStream(inStream); }
michael@0 32 void ReleaseStream() { m_Stream.ReleaseStream(); }
michael@0 33 void Init()
michael@0 34 {
michael@0 35 m_Stream.Init();
michael@0 36 m_BitPos = kNumBigValueBits;
michael@0 37 m_Value = 0;
michael@0 38 NumExtraBytes = 0;
michael@0 39 }
michael@0 40 UInt64 GetProcessedSize() const
michael@0 41 { return m_Stream.GetProcessedSize() - (kNumBigValueBits - m_BitPos) / 8; }
michael@0 42 UInt64 GetProcessedBitsSize() const
michael@0 43 { return (m_Stream.GetProcessedSize() << 3) - (kNumBigValueBits - m_BitPos); }
michael@0 44 int GetBitPosition() const { return (m_BitPos & 7); }
michael@0 45
michael@0 46 void Normalize()
michael@0 47 {
michael@0 48 for (;m_BitPos >= 8; m_BitPos -= 8)
michael@0 49 {
michael@0 50 Byte b;
michael@0 51 if (!m_Stream.ReadByte(b))
michael@0 52 {
michael@0 53 b = 0xFF; // check it
michael@0 54 NumExtraBytes++;
michael@0 55 }
michael@0 56 m_Value = (b << (kNumBigValueBits - m_BitPos)) | m_Value;
michael@0 57 }
michael@0 58 }
michael@0 59
michael@0 60 UInt32 ReadBits(int numBits)
michael@0 61 {
michael@0 62 Normalize();
michael@0 63 UInt32 res = m_Value & ((1 << numBits) - 1);
michael@0 64 m_BitPos += numBits;
michael@0 65 m_Value >>= numBits;
michael@0 66 return res;
michael@0 67 }
michael@0 68
michael@0 69 bool ExtraBitsWereRead() const
michael@0 70 {
michael@0 71 if (NumExtraBytes == 0)
michael@0 72 return false;
michael@0 73 return ((UInt32)(kNumBigValueBits - m_BitPos) < (NumExtraBytes << 3));
michael@0 74 }
michael@0 75 };
michael@0 76
michael@0 77 template<class TInByte>
michael@0 78 class CDecoder: public CBaseDecoder<TInByte>
michael@0 79 {
michael@0 80 UInt32 m_NormalValue;
michael@0 81
michael@0 82 public:
michael@0 83 void Init()
michael@0 84 {
michael@0 85 CBaseDecoder<TInByte>::Init();
michael@0 86 m_NormalValue = 0;
michael@0 87 }
michael@0 88
michael@0 89 void Normalize()
michael@0 90 {
michael@0 91 for (;this->m_BitPos >= 8; this->m_BitPos -= 8)
michael@0 92 {
michael@0 93 Byte b;
michael@0 94 if (!this->m_Stream.ReadByte(b))
michael@0 95 {
michael@0 96 b = 0xFF; // check it
michael@0 97 this->NumExtraBytes++;
michael@0 98 }
michael@0 99 m_NormalValue = (b << (kNumBigValueBits - this->m_BitPos)) | m_NormalValue;
michael@0 100 this->m_Value = (this->m_Value << 8) | kInvertTable[b];
michael@0 101 }
michael@0 102 }
michael@0 103
michael@0 104 UInt32 GetValue(int numBits)
michael@0 105 {
michael@0 106 Normalize();
michael@0 107 return ((this->m_Value >> (8 - this->m_BitPos)) & kMask) >> (kNumValueBits - numBits);
michael@0 108 }
michael@0 109
michael@0 110 void MovePos(int numBits)
michael@0 111 {
michael@0 112 this->m_BitPos += numBits;
michael@0 113 m_NormalValue >>= numBits;
michael@0 114 }
michael@0 115
michael@0 116 UInt32 ReadBits(int numBits)
michael@0 117 {
michael@0 118 Normalize();
michael@0 119 UInt32 res = m_NormalValue & ( (1 << numBits) - 1);
michael@0 120 MovePos(numBits);
michael@0 121 return res;
michael@0 122 }
michael@0 123 };
michael@0 124
michael@0 125 }}
michael@0 126
michael@0 127 #endif

mercurial