use of org.apache.sis.internal.storage.io.ChannelDataInput in project sis by apache.
the class StorageConnector method prefetch.
/**
* Transfers more bytes from the {@link DataInput} to the {@link ByteBuffer}, if possible.
* This method returns {@code true} on success, or {@code false} if input is not a readable
* channel or stream, we have reached the end of stream, or the buffer is full.
*
* <p>This method is invoked when the amount of bytes in the buffer appears to be insufficient
* for {@link DataStoreProvider#probeContent(StorageConnector)} purpose.</p>
*
* @return {@code true} on success.
* @throws DataStoreException if an error occurred while reading more bytes.
*/
final boolean prefetch() throws DataStoreException {
try {
/*
* In most Apache SIS data store implementations, we use ChannelDataInput. If the object wrapped
* by ChannelDataInput has not been used directly, then Coupled.isValid should be true. In such
* case, reset(c) does nothing and ChannelDataInput.prefetch() will read new bytes from current
* channel position. Otherwise, a new read operation from the beginning will be required and we
* can only hope that it will read more bytes than last time.
*/
Coupled c = getView(ChannelDataInput.class);
if (c != null) {
// Does nothing is c.isValid is true.
reset(c);
return c.isValid && ((ChannelDataInput) c.view).prefetch() > 0;
}
/*
* The above code is the usual case. The code below this point is the fallback used when only
* an ImageInputStream was available. In such case, the ByteBuffer can only be the one created
* by the above createByteBuffer() method, which is known to be backed by a writable array.
*/
c = getView(ImageInputStream.class);
if (reset(c)) {
final ImageInputStream input = (ImageInputStream) c.view;
c = getView(ByteBuffer.class);
if (reset(c)) {
// reset(c) as a matter of principle, but (c != null) would have worked.
final ByteBuffer buffer = (ByteBuffer) c.view;
final int p = buffer.limit();
final long mark = input.getStreamPosition();
input.seek(Math.addExact(mark, p));
final int n = input.read(buffer.array(), p, buffer.capacity() - p);
input.seek(mark);
if (n > 0) {
buffer.limit(p + n);
return true;
}
}
}
} catch (IOException e) {
throw new DataStoreException(Errors.format(Errors.Keys.CanNotRead_1, getStorageName()), e);
}
return false;
}
use of org.apache.sis.internal.storage.io.ChannelDataInput in project sis by apache.
the class StorageConnectorTest method testGetAsChannelDataInput.
/**
* Tests the {@link StorageConnector#getStorageAs(Class)} method for the {@link ChannelDataInput} type.
* The initial value should not be an instance of {@link ChannelImageInputStream} in order to avoid initializing
* the Image I/O classes. However after a call to {@code getStorageAt(ChannelImageInputStream.class)}, the type
* should have been promoted.
*
* @throws DataStoreException if an error occurred while using the storage connector.
* @throws IOException if an error occurred while reading the test file.
*/
@Test
public void testGetAsChannelDataInput() throws DataStoreException, IOException {
final StorageConnector connection = create(true);
final ChannelDataInput input = connection.getStorageAs(ChannelDataInput.class);
assertFalse(input instanceof ChannelImageInputStream);
assertEquals(MAGIC_NUMBER, input.buffer.getInt());
/*
* Get as an image input stream and ensure that the cached value has been replaced.
*/
final DataInput stream = connection.getStorageAs(DataInput.class);
assertInstanceOf("Needs the SIS implementation", ChannelImageInputStream.class, stream);
assertNotSame("Expected a new instance.", input, stream);
assertSame("Shall share the channel.", input.channel, ((ChannelDataInput) stream).channel);
assertSame("Shall share the buffer.", input.buffer, ((ChannelDataInput) stream).buffer);
assertSame("Cached valud shall have been replaced.", stream, connection.getStorageAs(ChannelDataInput.class));
connection.closeAllExcept(null);
}
Aggregations