jaulib v1.3.0
Jau Support Library (C++, Java, ..)
ByteInStream_Feed.java
Go to the documentation of this file.
1/**
2 * Author: Sven Gothel <sgothel@jausoft.com>
3 * Copyright (c) 2022-2023 Gothel Software e.K.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining
6 * a copy of this software and associated documentation files (the
7 * "Software"), to deal in the Software without restriction, including
8 * without limitation the rights to use, copy, modify, merge, publish,
9 * distribute, sublicense, and/or sell copies of the Software, and to
10 * permit persons to whom the Software is furnished to do so, subject to
11 * the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be
14 * included in all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 */
24package org.jau.io;
25
26import java.nio.ByteBuffer;
27
28/**
29 * Ringbuffer-Based byte input stream with an externally provisioned data feed.
30 *
31 * Instance uses the native C++ object `jau::io::ByteInStream_Feed`.
32 */
33public final class ByteInStream_Feed implements ByteInStream {
34 private volatile long nativeInstance;
35 /* pp */ long getNativeInstance() { return nativeInstance; }
36
37 /**
38 * Construct a ringbuffer backed externally provisioned byte input stream
39 * @param id_name arbitrary identifier for this instance
40 * @param timeoutMS maximum duration in milliseconds to wait @ check_available() and write(), zero waits infinitely
41 */
42 public ByteInStream_Feed(final String id_name, final long timeoutMS) {
43 try {
44 nativeInstance = ctorImpl(id_name, timeoutMS);
45 } catch (final Throwable t) {
46 System.err.println("ByteInStream_Feed.ctor: native ctor failed: "+t.getMessage());
47 throw t;
48 }
49 }
50 private native long ctorImpl(final String id_name, final long timeoutMS);
51
52 @Override
53 public native void closeStream();
54
55 @Override
56 public void close() {
57 final long handle;
58 synchronized( this ) {
59 handle = nativeInstance;
60 nativeInstance = 0;
61 }
62 if( 0 != handle ) {
63 dtorImpl(handle);
64 }
65 }
66 private static native void dtorImpl(final long nativeInstance);
67
68 @Override
69 public void finalize() {
70 close();
71 }
72
73 @Override
74 public native boolean is_open();
75
76 @Override
77 public void clear(final IOState state) {
78 clearImpl( state.mask );
79 }
80 private native void clearImpl(int s);
81
82 @Override
83 public IOState rdState() {
84 return new IOState( rdStateImpl() );
85 }
86 private native int rdStateImpl();
87
88 @Override
89 public void setState(final IOState state) {
90 setStateImpl( state.mask );
91 }
92 private native void setStateImpl(int s);
93
94 @Override
95 public native boolean good();
96
97 @Override
98 public native boolean eof();
99
100 @Override
101 public native boolean fail();
102
103 @Override
104 public native boolean bad();
105
106 @Override
107 public native boolean timeout();
108
109 @Override
110 public native boolean available(final long n);
111
112 @Override
113 public native int read(final byte[] out, final int offset, final int length);
114
115 @Override
116 public int read(final ByteBuffer out) {
117 if( !Buffers.isDirect(out) ) {
118 throw new IllegalArgumentException("out buffer not direct");
119 }
120 final int res = read2Impl(out, (int)Buffers.getDirectBufferByteOffset(out));
121 out.limit(out.position() + res);
122 return res;
123 }
124 private native int read2Impl(Object out, int out_offset);
125
126 @Override
127 public native int peek(byte[] out, final int offset, final int length, final long peek_offset);
128
129 @Override
130 public native String id();
131
132 @Override
133 public native long discard_next(long N);
134
135 @Override
136 public native long tellg();
137
138 @Override
139 public native boolean has_content_size();
140
141 @Override
142 public native long content_size();
143
144 /**
145 * Interrupt a potentially blocked reader.
146 *
147 * Call this method if intended to abort streaming and to interrupt the reader thread's potentially blocked check_available() call,
148 * i.e. done at set_eof()
149 *
150 * @see set_eof()
151 */
152 public native void interruptReader();
153
154 /**
155 * Write given bytes to the async ringbuffer using explicit given timeout.
156 *
157 * Wait up to explicit given timeout duration until ringbuffer space is available, where fractions_i64::zero waits infinitely.
158 *
159 * This method is blocking.
160 *
161 * @param n byte count to wait for
162 * @param in the byte array to transfer to the async ringbuffer
163 * @param length the length of the byte array in
164 * @param timeout explicit given timeout for async ringbuffer put operation
165 * @return true if successful, otherwise false on timeout or stopped feeder and subsequent calls to good() will return false.
166 */
167 public boolean write(final byte[] in, final int offset, final int length, final long timeoutMS) {
168 return write0Impl(in, offset, length, timeoutMS);
169 }
170 private native boolean write0Impl(final byte[] in, final int offset, final int length, final long timeoutMS);
171
172 /**
173 * Write given bytes to the async ringbuffer.
174 *
175 * Wait up to timeout duration set in constructor until ringbuffer space is available, where fractions_i64::zero waits infinitely.
176 *
177 * This method is blocking.
178 *
179 * @param in the byte array to transfer to the async ringbuffer
180 * @param offset offset to in byte array to write
181 * @param length number of in bytes to write starting at offset
182 * @return true if successful, otherwise false on timeout or stopped feeder and subsequent calls to good() will return false.
183 */
184 public boolean write(final byte[] in, final int offset, final int length) {
185 return write1Impl(in, offset, length);
186 }
187 private native boolean write1Impl(final byte[] in, final int offset, final int length);
188
189 /**
190 * Write given bytes to the async ringbuffer.
191 *
192 * Wait up to timeout duration set in constructor until ringbuffer space is available, where fractions_i64::zero waits infinitely.
193 *
194 * This method is blocking.
195 *
196 * @param in the direct {@link ByteBuffer} to transfer to the async ringbuffer starting at its {@link ByteBuffer#position() position} up to its {@link ByteBuffer#limit() limit}.
197 * {@link ByteBuffer#limit() Limit} will be reset to {@link ByteBuffer#position() position}.
198 * @return true if successful, otherwise false on timeout or stopped feeder and subsequent calls to good() will return false.
199 */
200 public boolean write(final ByteBuffer in) {
201 if( !Buffers.isDirect(in) ) {
202 throw new IllegalArgumentException("out buffer not direct");
203 }
204 if( write2Impl(in, (int)Buffers.getDirectBufferByteOffset(in), in.limit()) ) {
205 in.limit(in.position());
206 return true;
207 } else {
208 return false;
209 }
210 }
211 private native boolean write2Impl(ByteBuffer out, int out_offset, int out_limit);
212
213 /**
214 * Set known content size, informal only.
215 * @param content_length the content size in bytes
216 */
217 public native void set_content_size(final long size);
218
219 /**
220 * Set end-of-data (EOS), i.e. when feeder completed provisioning bytes.
221 *
222 * Implementation issues interruptReader() to unblock a potentially blocked reader thread.
223 *
224 * @param result should be either -1 for FAILED or 1 for SUCCESS.
225 *
226 * @see interruptReader()
227 */
228 public native void set_eof(final int result);
229
230 @Override
231 public native String toString();
232}
Utility methods allowing easy java.nio.Buffer manipulations.
Definition: Buffers.java:43
static boolean isDirect(final Object buf)
Helper routine to tell whether a buffer is direct or not.
Definition: Buffers.java:78
static long getDirectBufferByteOffset(final Object buf)
Helper routine to get the Buffer byte offset by taking into account the Buffer position and the under...
Definition: Buffers.java:96
Ringbuffer-Based byte input stream with an externally provisioned data feed.
native void interruptReader()
Interrupt a potentially blocked reader.
native boolean eof()
Checks if end-of-file has been reached.
native long content_size()
Returns the content_size if known.
void setState(final IOState state)
Sets state flags, by keeping its previous bits.
native boolean has_content_size()
Returns true if implementation is aware of content_size(), otherwise false.
native boolean bad()
Checks if a non-recoverable error has occurred.
native void set_eof(final int result)
Set end-of-data (EOS), i.e.
native boolean is_open()
Checks if the stream has an associated file.
native boolean good()
Checks if no error nor eof() has occurred i.e.
boolean write(final ByteBuffer in)
Write given bytes to the async ringbuffer.
boolean write(final byte[] in, final int offset, final int length, final long timeoutMS)
Write given bytes to the async ringbuffer using explicit given timeout.
boolean write(final byte[] in, final int offset, final int length)
Write given bytes to the async ringbuffer.
void clear(final IOState state)
Clears state flags by assignment to the given value.
int read(final ByteBuffer out)
Read from the source.
void close()
Close the stream if supported by the underlying mechanism and dispose the native instance.
native int peek(byte[] out, final int offset, final int length, final long peek_offset)
Read from the source but do not modify the internal offset.
IOState rdState()
Returns the current state flags.
native int read(final byte[] out, final int offset, final int length)
Read from the source.
native long discard_next(long N)
Discard the next N bytes of the data.
native boolean fail()
Checks if an error has occurred.
native void set_content_size(final long size)
Set known content size, informal only.
native void closeStream()
Close the stream if supported by the underlying mechanism.
native long tellg()
Returns the input position indicator, similar to std::basic_istream.
native String id()
return the id of this data source
native boolean timeout()
Checks if a timeout (non-recoverable) has occurred.
ByteInStream_Feed(final String id_name, final long timeoutMS)
Construct a ringbuffer backed externally provisioned byte input stream.
native boolean available(final long n)
Return whether n bytes are available in the input stream, if has_content_size() or using an asynchron...
Mimic std::ios_base::iostate for state functionality, see iostate_func.
Definition: IOState.java:33
Abstract byte input stream object.