Libraryless. Click here for Pure Java version (4967L/28K).
1 | // We effectively turn the stream into a non-blocking stream. |
2 | // There is the addition isEOF() to check whether an actual |
3 | // stream end has been reached (true) or whether we are just |
4 | // waiting for more data (false). |
5 | |
6 | sclass ByteArraysPartialInputStream extends InputStreamPlusReadFully { |
7 | sclass State { |
8 | long absolutePosition; |
9 | int ofs; |
10 | MinimalChain<byte[]> chain; |
11 | |
12 | *(long *absolutePosition, int *ofs, MinimalChain<byte[]> *chain) {} |
13 | |
14 | byte[] data() { ret chain!; } |
15 | int nBytes() { ret l(data()); } |
16 | bool exhausted() { ret ofs >= nBytes(); } |
17 | |
18 | toString { |
19 | ret withIdentity(this, "State" + bracketed( |
20 | renderVars(+ofs, +nBytes(), next := chain.next))); } |
21 | } |
22 | |
23 | bool debug, eof; |
24 | MinimalChain<byte[]> last = new MinimalChain(null); |
25 | State state = new(0, 0, last); |
26 | long remaining; |
27 | State mark; |
28 | |
29 | @Override public synchronized void readFully(byte[] buf, int off, int n) throws IOException { |
30 | if (debug) printFunctionCall readFully(buf, off, n); |
31 | if (n == 0) ret; |
32 | if (n > available()) |
33 | throw new EOFException(); |
34 | assertEquals(n, read(buf, off, n)); |
35 | } |
36 | |
37 | @Override public synchronized int read(byte[] buf, int off, int len) throws IOException { |
38 | if (debug) printFunctionCall read(buf, off, len); |
39 | len = min(len, available()); |
40 | if (len == 0) ret -1; |
41 | int n = 0; |
42 | |
43 | while (state.chain != last) { |
44 | int nChunk = state.nBytes(); |
45 | int inChunk = min(len, nChunk-state.ofs); |
46 | int copiedFrom = state.ofs, nBytes = state.nBytes(); |
47 | arraycopy(state.data(), copiedFrom, buf, off, inChunk); |
48 | n += inChunk; |
49 | off += inChunk; |
50 | len -= inChunk; |
51 | state.ofs += inChunk; |
52 | state.absolutePosition += inChunk; |
53 | remaining -= inChunk; |
54 | if (debug) printVars(nBytes := state.nBytes(), +copiedFrom, +nChunk, +inChunk, +n, +off, +len); |
55 | if (state.exhausted()) |
56 | state = new State(state.absolutePosition, 0, state.chain.next); |
57 | else |
58 | break; |
59 | } |
60 | |
61 | ret n; |
62 | } |
63 | |
64 | @Override public synchronized int available() { ret clampToInt(remaining); } |
65 | |
66 | @Override public synchronized int read() throws IOException { |
67 | if (debug) printFunctionCall read(); |
68 | while ping (true) { |
69 | if (state.ofs < l(state.chain!)) { |
70 | ++state.absolutePosition; |
71 | --remaining; |
72 | ret ubyteToInt(state.chain![state.ofs++]); |
73 | } |
74 | |
75 | if (state.chain.next == null) |
76 | ret noElement(); |
77 | |
78 | state = new State(0, 0, state.chain.next); |
79 | } |
80 | } |
81 | |
82 | static int noElement() { ret -1; } |
83 | |
84 | public synchronized void add aka write(byte[] buffer) { |
85 | if (empty(buffer)) ret; |
86 | remaining += l(buffer); |
87 | last.setNext(new MinimalChain(null)); |
88 | last.setElement(buffer); |
89 | last = last.next; |
90 | } |
91 | |
92 | public synchronized void addEOF() { |
93 | eof = true; |
94 | } |
95 | |
96 | public synchronized bool isEOF() { |
97 | ret state.chain == last && eof; |
98 | } |
99 | |
100 | @Override public synchronized bool markSupported() { true; } |
101 | |
102 | @Override public synchronized void mark(int readLimit) { |
103 | if (debug) printFunctionCall mark(readLimit); |
104 | // clone state |
105 | mark = new State(state.absolutePosition, state.ofs, state.chain); |
106 | ifdef ByteArraysPartialInputStream_debug |
107 | printVars(+mark); |
108 | endifdef |
109 | } |
110 | |
111 | @Override public synchronized void reset() throws IOException { |
112 | if (debug) printFunctionCall reset(); |
113 | if (mark == null) fail("Reset without mark"); |
114 | remaining += state.absolutePosition-mark.absolutePosition; |
115 | state = mark; |
116 | mark = null; |
117 | } |
118 | |
119 | synchronized S stats() { ret toStringWithFields(this); } |
120 | } |
Began life as a copy of #1032907
download show line numbers debug dex old transpilations
Travelled to 3 computer(s): bhatertpkbcr, mowyntqkapby, mqqgnosmbjvj
No comments. add comment
Snippet ID: | #1032911 |
Snippet name: | ByteArraysPartialInputStream |
Eternal ID of this version: | #1032911/46 |
Text MD5: | 4449de983a987993c9868beb10728096 |
Transpilation MD5: | 1238b60920df9613f08fd2835893ae4a |
Author: | stefan |
Category: | javax |
Type: | JavaX fragment (include) |
Public (visible to everyone): | Yes |
Archived (hidden from active list): | No |
Created/modified: | 2021-10-11 11:58:40 |
Source code size: | 3701 bytes / 120 lines |
Pitched / IR pitched: | No / No |
Views / Downloads: | 218 / 418 |
Version history: | 45 change(s) |
Referenced in: | [show references] |