1
- package software .coley .lljzip .format .compression ;
2
-
3
- import java .io .IOException ;
4
- import java .io .InputStream ;
5
- import java .io .OutputStream ;
6
- import java .lang .foreign .MemorySegment ;
7
- import java .lang .foreign .ValueLayout ;
8
-
9
- final class MemorySegmentInputStream extends InputStream {
10
- private final MemorySegment data ;
11
- private long read ;
12
- private long markedOffset = -1 ;
13
- private long markedLimit ;
14
- private volatile boolean closed ;
15
-
16
- MemorySegmentInputStream (MemorySegment data ) {
17
- this .data = data ;
18
- }
19
-
20
- private void checkMarkLimit () {
21
- if (markedOffset > -1 ) {
22
- // Discard if we passed the read limit for our mark
23
- long diff = read - markedOffset ;
24
- if (diff > markedLimit ) {
25
- markedOffset = -1 ;
26
- }
27
- }
28
- }
29
-
30
- @ Override
31
- public boolean markSupported () {
32
- return true ;
33
- }
34
-
35
- @ Override
36
- public synchronized void mark (int limit ) {
37
- // Record current position and read-limit
38
- markedOffset = read ;
39
- markedLimit = limit ;
40
- }
41
-
42
- @ Override
43
- public synchronized void reset () {
44
- // Revert read to marked position.
45
- read = markedOffset ;
46
- }
47
-
48
- @ Override
49
- public int read () throws IOException {
50
- ensureOpen ();
51
- MemorySegment data = this .data ;
52
- if (read >= data .byteSize ()) {
53
- return -1 ;
54
- }
55
- byte b = data .get (ValueLayout .JAVA_BYTE , read ++);
56
- checkMarkLimit ();
57
- return b & 0xff ;
58
- }
59
-
60
- @ Override
61
- public int read (byte [] b , int off , int len ) throws IOException {
62
- ensureOpen ();
63
- MemorySegment data = this .data ;
64
- long read = this .read ;
65
- long length = data .byteSize ();
66
- if (read >= length ) {
67
- return -1 ;
68
- }
69
- long remaining = length - read ;
70
- len = (int ) Math .min (remaining , len );
71
- MemorySegment .copy (data , read , MemorySegment .ofArray (b ), off , len );
72
- this .read += len ;
73
- checkMarkLimit ();
74
- return len ;
75
- }
76
-
77
- @ Override
78
- public byte [] readNBytes (int len ) throws IOException {
79
- ensureOpen ();
80
- MemorySegment data = this .data ;
81
- long read = this .read ;
82
- long length = data .byteSize ();
83
- if (read >= length ) {
84
- return new byte [0 ];
85
- }
86
- long remaining = length - read ;
87
- len = (int ) Math .min (remaining , len );
88
- byte [] buf = new byte [len ];
89
- MemorySegment .copy (data , read , MemorySegment .ofArray (buf ), 0 , len );
90
- this .read += len ;
91
- checkMarkLimit ();
92
- return buf ;
93
- }
94
-
95
- @ Override
96
- public long skip (long n ) throws IOException {
97
- ensureOpen ();
98
- MemorySegment data = this .data ;
99
- long read = this .read ;
100
- long length = data .byteSize ();
101
- if (read >= length ) {
102
- return 0 ;
103
- }
104
- n = Math .min (n , length - read );
105
- this .read += n ;
106
- checkMarkLimit ();
107
- return n ;
108
- }
109
-
110
- @ Override
111
- public int available () throws IOException {
112
- ensureOpen ();
113
- MemorySegment data = this .data ;
114
- long length = data .byteSize ();
115
- long read = this .read ;
116
- if (read >= length ) {
117
- return 0 ;
118
- }
119
- long remaining = length - read ;
120
- if (remaining > Integer .MAX_VALUE )
121
- return Integer .MAX_VALUE ;
122
- return (int ) remaining ;
123
- }
124
-
125
- @ Override
126
- public void close () throws IOException {
127
- closed = true ;
128
- }
129
-
130
- @ Override
131
- public long transferTo (OutputStream out ) throws IOException {
132
- ensureOpen ();
133
- MemorySegment data = this .data ;
134
- long length = data .byteSize ();
135
- long read = this .read ;
136
- if (read >= length ) {
137
- return 0L ;
138
- }
139
- long remaining = length - read ;
140
- byte [] buffer = new byte [(int ) Math .min (16384 , remaining )];
141
- MemorySegment bufferSegment = MemorySegment .ofArray (buffer );
142
- while (read < length ) {
143
- int copyable = (int ) Math .min (buffer .length , length - read );
144
- MemorySegment .copy (data , read , bufferSegment , 0 , copyable );
145
- out .write (buffer , 0 , copyable );
146
- read += copyable ;
147
- }
148
- this .read = length ;
149
- checkMarkLimit ();
150
- return remaining ;
151
- }
152
-
153
- private void ensureOpen () throws IOException {
154
- if (closed )
155
- throw new IOException ("Stream closed" );
156
- }
1
+ package software .coley .lljzip .util ;
2
+
3
+ import javax .annotation .Nonnull ;
4
+ import java .io .IOException ;
5
+ import java .io .InputStream ;
6
+ import java .io .OutputStream ;
7
+ import java .lang .foreign .MemorySegment ;
8
+ import java .lang .foreign .ValueLayout ;
9
+
10
+ /**
11
+ * Input stream implementation backed by {@link MemorySegment}.
12
+ *
13
+ * @author xDark
14
+ */
15
+ public class MemorySegmentInputStream extends InputStream {
16
+ private final MemorySegment data ;
17
+ private long read ;
18
+ private long markedOffset = -1 ;
19
+ private long markedLimit ;
20
+ private volatile boolean closed ;
21
+
22
+ public MemorySegmentInputStream (@ Nonnull MemorySegment data ) {
23
+ this .data = data ;
24
+ }
25
+
26
+ @ Nonnull
27
+ public MemorySegment getData () {
28
+ return data ;
29
+ }
30
+
31
+ public long getRead () {
32
+ return read ;
33
+ }
34
+
35
+ public long getMarkedOffset () {
36
+ return markedOffset ;
37
+ }
38
+
39
+ public long getMarkedLimit () {
40
+ return markedLimit ;
41
+ }
42
+
43
+ public boolean isClosed () {
44
+ return closed ;
45
+ }
46
+
47
+ private void checkMarkLimit () {
48
+ if (markedOffset > -1 ) {
49
+ // Discard if we passed the read limit for our mark
50
+ long diff = read - markedOffset ;
51
+ if (diff > markedLimit ) {
52
+ markedOffset = -1 ;
53
+ }
54
+ }
55
+ }
56
+
57
+ @ Override
58
+ public boolean markSupported () {
59
+ return true ;
60
+ }
61
+
62
+ @ Override
63
+ public synchronized void mark (int limit ) {
64
+ // Record current position and read-limit
65
+ markedOffset = read ;
66
+ markedLimit = limit ;
67
+ }
68
+
69
+ @ Override
70
+ public synchronized void reset () {
71
+ // Revert read to marked position.
72
+ read = markedOffset ;
73
+ }
74
+
75
+ @ Override
76
+ public int read () throws IOException {
77
+ ensureOpen ();
78
+ MemorySegment data = this .data ;
79
+ if (read >= data .byteSize ()) {
80
+ return -1 ;
81
+ }
82
+ byte b = data .get (ValueLayout .JAVA_BYTE , read ++);
83
+ checkMarkLimit ();
84
+ return b & 0xff ;
85
+ }
86
+
87
+ @ Override
88
+ public int read (@ Nonnull byte [] b , int off , int len ) throws IOException {
89
+ ensureOpen ();
90
+ MemorySegment data = this .data ;
91
+ long read = this .read ;
92
+ long length = data .byteSize ();
93
+ if (read >= length ) {
94
+ return -1 ;
95
+ }
96
+ long remaining = length - read ;
97
+ len = (int ) Math .min (remaining , len );
98
+ MemorySegment .copy (data , read , MemorySegment .ofArray (b ), off , len );
99
+ this .read += len ;
100
+ checkMarkLimit ();
101
+ return len ;
102
+ }
103
+
104
+ @ Override
105
+ public byte [] readNBytes (int len ) throws IOException {
106
+ ensureOpen ();
107
+ MemorySegment data = this .data ;
108
+ long read = this .read ;
109
+ long length = data .byteSize ();
110
+ if (read >= length ) {
111
+ return new byte [0 ];
112
+ }
113
+ long remaining = length - read ;
114
+ len = (int ) Math .min (remaining , len );
115
+ byte [] buf = new byte [len ];
116
+ MemorySegment .copy (data , read , MemorySegment .ofArray (buf ), 0 , len );
117
+ this .read += len ;
118
+ checkMarkLimit ();
119
+ return buf ;
120
+ }
121
+
122
+ @ Override
123
+ public long skip (long n ) throws IOException {
124
+ ensureOpen ();
125
+ MemorySegment data = this .data ;
126
+ long read = this .read ;
127
+ long length = data .byteSize ();
128
+ if (read >= length ) {
129
+ return 0 ;
130
+ }
131
+ n = Math .min (n , length - read );
132
+ this .read += n ;
133
+ checkMarkLimit ();
134
+ return n ;
135
+ }
136
+
137
+ @ Override
138
+ public int available () throws IOException {
139
+ ensureOpen ();
140
+ MemorySegment data = this .data ;
141
+ long length = data .byteSize ();
142
+ long read = this .read ;
143
+ if (read >= length ) {
144
+ return 0 ;
145
+ }
146
+ long remaining = length - read ;
147
+ if (remaining > Integer .MAX_VALUE )
148
+ return Integer .MAX_VALUE ;
149
+ return (int ) remaining ;
150
+ }
151
+
152
+ @ Override
153
+ public void close () {
154
+ closed = true ;
155
+ }
156
+
157
+ @ Override
158
+ public long transferTo (OutputStream out ) throws IOException {
159
+ ensureOpen ();
160
+ MemorySegment data = this .data ;
161
+ long length = data .byteSize ();
162
+ long read = this .read ;
163
+ if (read >= length ) {
164
+ return 0L ;
165
+ }
166
+ long remaining = length - read ;
167
+ byte [] buffer = new byte [(int ) Math .min (16384 , remaining )];
168
+ MemorySegment bufferSegment = MemorySegment .ofArray (buffer );
169
+ while (read < length ) {
170
+ int copyable = (int ) Math .min (buffer .length , length - read );
171
+ MemorySegment .copy (data , read , bufferSegment , 0 , copyable );
172
+ out .write (buffer , 0 , copyable );
173
+ read += copyable ;
174
+ }
175
+ this .read = length ;
176
+ checkMarkLimit ();
177
+ return remaining ;
178
+ }
179
+
180
+ private void ensureOpen () throws IOException {
181
+ if (closed )
182
+ throw new IOException ("Stream closed" );
183
+ }
157
184
}
0 commit comments