Libraryless. Click here for Pure Java version (13644L/77K).
1 | // We use big-endian as DataOutputStream does |
2 | sclass ByteHead /*is DataOutput*/ is AutoCloseable { |
3 | settable bool readMode; |
4 | settable bool writeMode; |
5 | gettable InputStream inputStream; |
6 | gettable OutputStream outputStream; |
7 | settable long byteCounter; |
8 | gettable bool eof; |
9 | |
10 | *() {} |
11 | *(InputStream inputStream) { inputStream(inputStream); } |
12 | *(OutputStream outputStream) { outputStream(outputStream); } |
13 | |
14 | selfType inputStream(InputStream inputStream) { this.inputStream = inputStream; readMode(true); this; } |
15 | selfType outputStream(OutputStream outputStream) { this.outputStream = outputStream; writeMode(true); this; } |
16 | |
17 | void write(byte[] data) ctex { |
18 | ensureWriteMode(); |
19 | outputStream?.write(data); |
20 | byteCounter += data.length; |
21 | } |
22 | |
23 | void writeFloat(float f) { |
24 | writeInt(Float.floatToIntBits(f)); |
25 | } |
26 | |
27 | void writeLong(long l) { |
28 | writeInt((int) (l >> 32)); |
29 | writeInt((int) l); |
30 | } |
31 | |
32 | void writeInt(int i) { |
33 | write(i >> 24); |
34 | write(i >> 16); |
35 | write(i >> 8); |
36 | write(i); |
37 | } |
38 | |
39 | void writeShort(int i) { |
40 | write(i >> 8); |
41 | write(i); |
42 | } |
43 | |
44 | void writeByte aka write(int i) ctex { |
45 | ensureWriteMode(); |
46 | outputStream?.write(i); |
47 | byteCounter++; |
48 | } |
49 | |
50 | void writeASCII(char c) { |
51 | write(toASCII(c)); |
52 | } |
53 | |
54 | void writeASCII(S s) { |
55 | write(toASCII(s)); |
56 | } |
57 | |
58 | // write/verify constant ASCII text |
59 | void exchangeASCII(S s) { |
60 | exchangeConstantBytes(toASCII(s)); |
61 | } |
62 | |
63 | void exchangeConstantBytes(byte[] data) { |
64 | for i over data: |
65 | exchangeByte(data[i]); |
66 | } |
67 | |
68 | long readLong() { |
69 | long i = ((long) readInt()) << 32; |
70 | ret i | (readInt() & 0xFFFFFFFFL); |
71 | } |
72 | |
73 | float readFloat() { |
74 | ret Float.intBitsToFloat(readInt()); |
75 | } |
76 | |
77 | int readInt() { |
78 | int i = read() << 24; |
79 | i |= read() << 16; |
80 | i |= read() << 8; |
81 | ret i | read(); |
82 | } |
83 | |
84 | short readShort() { |
85 | int i = read() << 8; |
86 | ret (short) (i | read()); |
87 | } |
88 | |
89 | byte[] readBytes(int n) { |
90 | byte[] data = new[n]; |
91 | for i to n: { |
92 | int b = read(); |
93 | if (b < 0) |
94 | fail("EOF"); |
95 | data[i] = (byte) b; |
96 | } |
97 | ret data; |
98 | } |
99 | |
100 | S readString() { |
101 | int n = readInt(); |
102 | if (eof()) null; |
103 | ret fromUtf8(readBytes(n)); |
104 | } |
105 | |
106 | // null is written as empty string |
107 | // writes UTF8 length (4 bytes) plus string as UTF8 |
108 | void writeString(S s) { |
109 | byte[] utf8 = toUtf8(unnull(s)); |
110 | writeInt(l(utf8)); |
111 | write(utf8); |
112 | } |
113 | |
114 | // -1 for EOF |
115 | int readByte aka read() ctex { |
116 | ensureReadMode(); |
117 | ++byteCounter; |
118 | int b = inputStream.read(); |
119 | if (b < 0) eof = true; |
120 | ret b; |
121 | } |
122 | |
123 | void ensureReadMode { |
124 | if (!readMode) fail("Not in read mode"); |
125 | } |
126 | |
127 | void ensureWriteMode { |
128 | if (!writeMode) fail("Not in write mode"); |
129 | } |
130 | |
131 | // exchange = read or write depending on mode |
132 | |
133 | void exchangeByte(byte getter, IVF1<Byte> setter) { |
134 | exchangeByte(-> getter, setter); |
135 | } |
136 | |
137 | void exchangeByte(IF0<Byte> getter, IVF1<Byte> setter) { |
138 | if (writeMode()) |
139 | writeByte(getter!); |
140 | |
141 | if (readMode()) |
142 | setter.get(toUByte(readByte())); |
143 | } |
144 | |
145 | void exchangeShort(IF0<Short> getter, IVF1<Short> setter) { |
146 | if (writeMode()) |
147 | writeShort(getter!); |
148 | |
149 | if (readMode()) |
150 | setter.get(readShort()); |
151 | } |
152 | |
153 | void exchangeLong(IVar<Long> var) { |
154 | exchangeLong(var.getter(), var.setter()); |
155 | } |
156 | |
157 | void exchangeLong(IF0<Long> getter, IVF1<Long> setter) { |
158 | if (writeMode()) |
159 | writeLong(getter!); |
160 | |
161 | if (readMode()) |
162 | setter.get(readLong()); |
163 | } |
164 | |
165 | void exchangeByte(byte i) { |
166 | exchangeByte(-> i, j -> assertEquals(i, j)); |
167 | } |
168 | |
169 | void exchangeInt(int i) { |
170 | exchangeInt(-> i, j -> assertEquals(i, j)); |
171 | } |
172 | |
173 | void exchangeInt(IF0<Int> getter, IVF1<Int> setter) { |
174 | if (writeMode()) |
175 | writeInt(getter!); |
176 | |
177 | if (readMode()) |
178 | setter.get(readInt()); |
179 | } |
180 | |
181 | void exchange(ByteIO writable) { |
182 | if (writable != null) writable.readWrite(this); |
183 | } |
184 | |
185 | void exchangeAll(Iterable<? extends ByteIO> writables) { |
186 | if (writables != null) |
187 | for (writable : writables) |
188 | exchange(writable); |
189 | } |
190 | |
191 | // write size in bytes of element first (as int), |
192 | // then the element itself. |
193 | // upon reading, size is actually ignored. |
194 | void exchangeWithSize(ByteIO writable) { |
195 | if (writeMode()) { |
196 | byte[] data = writable.saveToByteArray(); |
197 | writeInt(l(data)); |
198 | write(data); |
199 | } |
200 | |
201 | if (readMode()) { |
202 | int n = readInt(); |
203 | writable.readWrite(this); |
204 | } |
205 | } |
206 | |
207 | void finish {} |
208 | |
209 | public void close() { |
210 | main close(inputStream); |
211 | main close(outputStream); |
212 | finish(); |
213 | } |
214 | } |
download show line numbers debug dex old transpilations
Travelled to 2 computer(s): elmgxqgtpvxh, mqqgnosmbjvj
No comments. add comment
Snippet ID: | #1035632 |
Snippet name: | ByteHead - byte I/O class (can read and write) |
Eternal ID of this version: | #1035632/40 |
Text MD5: | cdf7caa8ba7ab823327638f1ce76786e |
Transpilation MD5: | 0bfe76444768cd46018eb82c3eadae23 |
Author: | stefan |
Category: | javax / io |
Type: | JavaX fragment (include) |
Public (visible to everyone): | Yes |
Archived (hidden from active list): | No |
Created/modified: | 2022-11-08 16:11:29 |
Source code size: | 4780 bytes / 214 lines |
Pitched / IR pitched: | No / No |
Views / Downloads: | 279 / 531 |
Version history: | 39 change(s) |
Referenced in: | [show references] |