1 | sclass BitHead > ByteHead { |
2 | gettable int align = 8; |
3 | gettable int currentByte; |
4 | int eofBits; |
5 | int nextByte; |
6 | |
7 | replace SomethingIO with BitIO. |
8 | |
9 | *() {} |
10 | *(InputStream inputStream) { super(inputStream); } |
11 | *(OutputStream outputStream) { super(outputStream); } |
12 | |
13 | // choose fast or slow version depending on alignment |
14 | void write(byte[] data) { |
15 | if (align == 0) |
16 | super.write(data); |
17 | else |
18 | for (b : data) write(b); |
19 | } |
20 | |
21 | void writeByte(int i) { |
22 | if (align == 0) |
23 | super.writeByte(i); |
24 | else { |
25 | currentByte |= i << align; |
26 | super.writeByte(currentByte); |
27 | currentByte = i >> (8-align); |
28 | } |
29 | } |
30 | |
31 | void writeBit(int i) { |
32 | writeBit((i & 1) != 0); |
33 | } |
34 | |
35 | void writeBit(bool b) { |
36 | if (b) currentByte |= 1 << align; |
37 | if (align == 7) { |
38 | super.writeByte(currentByte); |
39 | currentByte = align = 0; |
40 | } else |
41 | ++align; |
42 | } |
43 | |
44 | bool readBit() { |
45 | bool bitSet = peekBit(); |
46 | advanceBit(); |
47 | ret bitSet; |
48 | } |
49 | |
50 | bool peekBit() { |
51 | if (currentByte < 0) |
52 | fail("eof"); |
53 | |
54 | if (align == 8) |
55 | bufferNextByte(); |
56 | ret (currentByte & (1 << align)) != 0; |
57 | } |
58 | |
59 | void bufferNextByte { |
60 | if (align == 8) { |
61 | // first read ever |
62 | currentByte = read(); |
63 | align = 0; |
64 | if (currentByte < 0) ret; // EOF |
65 | nextByte = read(); |
66 | } else { |
67 | currentByte = nextByte; |
68 | if (currentByte >= 0) |
69 | nextByte = read(); |
70 | } |
71 | } |
72 | |
73 | bool isEOF() { |
74 | } |
75 | |
76 | void advanceBit { |
77 | if (currentByte < 0) ret; |
78 | if (align == 7) |
79 | bufferNextByte(); |
80 | else |
81 | ++align; |
82 | } |
83 | |
84 | bool byteAligned() { |
85 | ret align == 0; |
86 | } |
87 | |
88 | void completeByte aka flushBits aka finish(bool padWithOnes default false) { |
89 | if (byteAligned()) ret; |
90 | if (padWithOnes) currentByte |= 0xFF << align; |
91 | super.writeByte(currentByte); |
92 | currentByte = align = 0; |
93 | } |
94 | |
95 | // TODO: switch to more compact version saving 5 bits on average |
96 | void writeTrailingBitCount aka trailingBitCount(bool padWithOnes default false) { |
97 | if (!writeMode()) ret; |
98 | |
99 | int bitCount = modRange_incl(align(), 1, 8); |
100 | completeByte(padWithOnes); |
101 | writeByte(bitCount); |
102 | } |
103 | |
104 | void exchange(SomethingIO writable) { |
105 | if (writable != null) writable.readWrite(this); |
106 | } |
107 | |
108 | void exchangeBit(IF0<Bool> getter, IVF1<Bool> setter) { |
109 | if (writeMode()) |
110 | writeBit(getter!); |
111 | |
112 | if (readMode()) |
113 | setter.get(readBit()); |
114 | } |
115 | |
116 | void exchangeBit(int i) { exchangeBit(odd(i)); } |
117 | void exchangeBit(bool i) { |
118 | exchangeBit(-> i, j -> assertEquals(i, j)); |
119 | } |
120 | |
121 | void exchange(BitIO getter, Runnable setter) { |
122 | if (writeMode()) |
123 | setter.run(); |
124 | |
125 | if (readMode()) |
126 | getter.readWrite(this); |
127 | } |
128 | } |
Began life as a copy of #1035655
download show line numbers debug dex old transpilations
Travelled to 1 computer(s): mqqgnosmbjvj
No comments. add comment
Snippet ID: | #1035675 |
Snippet name: | BitHead - ByteHead extended with bit operations (extension with trailing bit count handling, dev.) |
Eternal ID of this version: | #1035675/1 |
Text MD5: | 181c7e9c784294d7adbc369e458b91ba |
Author: | stefan |
Category: | javax / io |
Type: | JavaX fragment (include) |
Public (visible to everyone): | Yes |
Archived (hidden from active list): | No |
Created/modified: | 2022-07-03 02:42:47 |
Source code size: | 2833 bytes / 128 lines |
Pitched / IR pitched: | No / No |
Views / Downloads: | 118 / 125 |
Referenced in: | [show references] |