1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package io.netty5.handler.codec.compression;
17
18 import io.netty5.buffer.api.Buffer;
19
20
21
22
23
24
25 class Bzip2BitReader {
26
27
28
29 private static final int MAX_COUNT_OF_READABLE_BYTES = Integer.MAX_VALUE >>> 3;
30
31
32
33
34 private Buffer in;
35
36
37
38
39 private long bitBuffer;
40
41
42
43
44 private int bitCount;
45
46
47
48
49 void setBuffer(Buffer in) {
50 this.in = in;
51 }
52
53
54
55
56
57
58 int readBits(final int count) {
59 if (count < 0 || count > 32) {
60 throw new IllegalArgumentException("count: " + count + " (expected: 0-32 )");
61 }
62 int bitCount = this.bitCount;
63 long bitBuffer = this.bitBuffer;
64
65 if (bitCount < count) {
66 long readData;
67 int offset;
68 switch (in.readableBytes()) {
69 case 1: {
70 readData = in.readUnsignedByte();
71 offset = 8;
72 break;
73 }
74 case 2: {
75 readData = in.readUnsignedShort();
76 offset = 16;
77 break;
78 }
79 case 3: {
80 readData = in.readUnsignedMedium();
81 offset = 24;
82 break;
83 }
84 default: {
85 readData = in.readUnsignedInt();
86 offset = 32;
87 break;
88 }
89 }
90
91 bitBuffer = bitBuffer << offset | readData;
92 bitCount += offset;
93 this.bitBuffer = bitBuffer;
94 }
95
96 this.bitCount = bitCount -= count;
97 return (int) (bitBuffer >>> bitCount & (count != 32 ? (1 << count) - 1 : 0xFFFFFFFFL));
98 }
99
100
101
102
103
104 boolean readBoolean() {
105 return readBits(1) != 0;
106 }
107
108
109
110
111
112 int readInt() {
113 return readBits(32);
114 }
115
116
117
118
119 void refill() {
120 int readData = in.readUnsignedByte();
121 bitBuffer = bitBuffer << 8 | readData;
122 bitCount += 8;
123 }
124
125
126
127
128
129 boolean isReadable() {
130 return bitCount > 0 || in.readableBytes() > 0;
131 }
132
133
134
135
136
137
138 boolean hasReadableBits(int count) {
139 if (count < 0) {
140 throw new IllegalArgumentException("count: " + count + " (expected value greater than 0)");
141 }
142 return bitCount >= count || (in.readableBytes() << 3 & Integer.MAX_VALUE) >= count - bitCount;
143 }
144
145
146
147
148
149
150 boolean hasReadableBytes(int count) {
151 if (count < 0 || count > MAX_COUNT_OF_READABLE_BYTES) {
152 throw new IllegalArgumentException("count: " + count
153 + " (expected: 0-" + MAX_COUNT_OF_READABLE_BYTES + ')');
154 }
155 return hasReadableBits(count << 3);
156 }
157 }