1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package io.netty.handler.codec.compression;
17
18 import io.netty.buffer.ByteBuf;
19
20
21
22
23
24
25 final class Bzip2BitWriter {
26
27
28
29 private long bitBuffer;
30
31
32
33
34 private int bitCount;
35
36
37
38
39
40
41 void writeBits(ByteBuf out, final int count, final long value) {
42 if (count < 0 || count > 32) {
43 throw new IllegalArgumentException("count: " + count + " (expected: 0-32)");
44 }
45 int bitCount = this.bitCount;
46 long bitBuffer = this.bitBuffer | value << 64 - count >>> bitCount;
47 bitCount += count;
48
49 if (bitCount >= 32) {
50 out.writeInt((int) (bitBuffer >>> 32));
51 bitBuffer <<= 32;
52 bitCount -= 32;
53 }
54 this.bitBuffer = bitBuffer;
55 this.bitCount = bitCount;
56 }
57
58
59
60
61
62 void writeBoolean(ByteBuf out, final boolean value) {
63 int bitCount = this.bitCount + 1;
64 long bitBuffer = this.bitBuffer | (value ? 1L << 64 - bitCount : 0L);
65
66 if (bitCount == 32) {
67 out.writeInt((int) (bitBuffer >>> 32));
68 bitBuffer = 0;
69 bitCount = 0;
70 }
71 this.bitBuffer = bitBuffer;
72 this.bitCount = bitCount;
73 }
74
75
76
77
78
79
80 void writeUnary(ByteBuf out, int value) {
81 if (value < 0) {
82 throw new IllegalArgumentException("value: " + value + " (expected 0 or more)");
83 }
84 while (value-- > 0) {
85 writeBoolean(out, true);
86 }
87 writeBoolean(out, false);
88 }
89
90
91
92
93
94 void writeInt(ByteBuf out, final int value) {
95 writeBits(out, 32, value);
96 }
97
98
99
100
101
102 void flush(ByteBuf out) {
103 final int bitCount = this.bitCount;
104
105 if (bitCount > 0) {
106 final long bitBuffer = this.bitBuffer;
107 final int shiftToRight = 64 - bitCount;
108
109 if (bitCount <= 8) {
110 out.writeByte((int) (bitBuffer >>> shiftToRight << 8 - bitCount));
111 } else if (bitCount <= 16) {
112 out.writeShort((int) (bitBuffer >>> shiftToRight << 16 - bitCount));
113 } else if (bitCount <= 24) {
114 out.writeMedium((int) (bitBuffer >>> shiftToRight << 24 - bitCount));
115 } else {
116 out.writeInt((int) (bitBuffer >>> shiftToRight << 32 - bitCount));
117 }
118 }
119 }
120 }