Tue, 06 Jan 2015 21:39:09 +0100
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.
1 // Compress/RangeCoder/RangeCoder.h
3 #ifndef __COMPRESS_RANGECODER_H
4 #define __COMPRESS_RANGECODER_H
6 #include "../../Common/InBuffer.h"
7 #include "../../Common/OutBuffer.h"
9 namespace NCompress {
10 namespace NRangeCoder {
12 const int kNumTopBits = 24;
13 const UInt32 kTopValue = (1 << kNumTopBits);
15 class CEncoder
16 {
17 UInt32 _cacheSize;
18 Byte _cache;
19 public:
20 UInt64 Low;
21 UInt32 Range;
22 COutBuffer Stream;
23 bool Create(UInt32 bufferSize) { return Stream.Create(bufferSize); }
25 void SetStream(ISequentialOutStream *stream) { Stream.SetStream(stream); }
26 void Init()
27 {
28 Stream.Init();
29 Low = 0;
30 Range = 0xFFFFFFFF;
31 _cacheSize = 1;
32 _cache = 0;
33 }
35 void FlushData()
36 {
37 // Low += 1;
38 for(int i = 0; i < 5; i++)
39 ShiftLow();
40 }
42 HRESULT FlushStream() { return Stream.Flush(); }
44 void ReleaseStream() { Stream.ReleaseStream(); }
46 void Encode(UInt32 start, UInt32 size, UInt32 total)
47 {
48 Low += start * (Range /= total);
49 Range *= size;
50 while (Range < kTopValue)
51 {
52 Range <<= 8;
53 ShiftLow();
54 }
55 }
57 void ShiftLow()
58 {
59 if ((UInt32)Low < (UInt32)0xFF000000 || (int)(Low >> 32) != 0)
60 {
61 Byte temp = _cache;
62 do
63 {
64 Stream.WriteByte((Byte)(temp + (Byte)(Low >> 32)));
65 temp = 0xFF;
66 }
67 while(--_cacheSize != 0);
68 _cache = (Byte)((UInt32)Low >> 24);
69 }
70 _cacheSize++;
71 Low = (UInt32)Low << 8;
72 }
74 void EncodeDirectBits(UInt32 value, int numTotalBits)
75 {
76 for (int i = numTotalBits - 1; i >= 0; i--)
77 {
78 Range >>= 1;
79 if (((value >> i) & 1) == 1)
80 Low += Range;
81 if (Range < kTopValue)
82 {
83 Range <<= 8;
84 ShiftLow();
85 }
86 }
87 }
89 void EncodeBit(UInt32 size0, UInt32 numTotalBits, UInt32 symbol)
90 {
91 UInt32 newBound = (Range >> numTotalBits) * size0;
92 if (symbol == 0)
93 Range = newBound;
94 else
95 {
96 Low += newBound;
97 Range -= newBound;
98 }
99 while (Range < kTopValue)
100 {
101 Range <<= 8;
102 ShiftLow();
103 }
104 }
106 UInt64 GetProcessedSize() { return Stream.GetProcessedSize() + _cacheSize + 4; }
107 };
109 class CDecoder
110 {
111 public:
112 CInBuffer Stream;
113 UInt32 Range;
114 UInt32 Code;
115 bool Create(UInt32 bufferSize) { return Stream.Create(bufferSize); }
117 void Normalize()
118 {
119 while (Range < kTopValue)
120 {
121 Code = (Code << 8) | Stream.ReadByte();
122 Range <<= 8;
123 }
124 }
126 void SetStream(ISequentialInStream *stream) { Stream.SetStream(stream); }
127 void Init()
128 {
129 Stream.Init();
130 Code = 0;
131 Range = 0xFFFFFFFF;
132 for(int i = 0; i < 5; i++)
133 Code = (Code << 8) | Stream.ReadByte();
134 }
136 void ReleaseStream() { Stream.ReleaseStream(); }
138 UInt32 GetThreshold(UInt32 total)
139 {
140 return (Code) / ( Range /= total);
141 }
143 void Decode(UInt32 start, UInt32 size)
144 {
145 Code -= start * Range;
146 Range *= size;
147 Normalize();
148 }
150 UInt32 DecodeDirectBits(int numTotalBits)
151 {
152 UInt32 range = Range;
153 UInt32 code = Code;
154 UInt32 result = 0;
155 for (int i = numTotalBits; i != 0; i--)
156 {
157 range >>= 1;
158 /*
159 result <<= 1;
160 if (code >= range)
161 {
162 code -= range;
163 result |= 1;
164 }
165 */
166 UInt32 t = (code - range) >> 31;
167 code -= range & (t - 1);
168 result = (result << 1) | (1 - t);
170 if (range < kTopValue)
171 {
172 code = (code << 8) | Stream.ReadByte();
173 range <<= 8;
174 }
175 }
176 Range = range;
177 Code = code;
178 return result;
179 }
181 UInt32 DecodeBit(UInt32 size0, UInt32 numTotalBits)
182 {
183 UInt32 newBound = (Range >> numTotalBits) * size0;
184 UInt32 symbol;
185 if (Code < newBound)
186 {
187 symbol = 0;
188 Range = newBound;
189 }
190 else
191 {
192 symbol = 1;
193 Code -= newBound;
194 Range -= newBound;
195 }
196 Normalize();
197 return symbol;
198 }
200 UInt64 GetProcessedSize() {return Stream.GetProcessedSize(); }
201 };
203 }}
205 #endif