Search in sources :

Example 6 with ChannelDataInput

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;
}
Also used : ChannelImageInputStream(org.apache.sis.internal.storage.io.ChannelImageInputStream) ImageInputStream(javax.imageio.stream.ImageInputStream) IOException(java.io.IOException) ByteBuffer(java.nio.ByteBuffer) ChannelDataInput(org.apache.sis.internal.storage.io.ChannelDataInput)

Example 7 with ChannelDataInput

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);
}
Also used : DataInput(java.io.DataInput) ChannelDataInput(org.apache.sis.internal.storage.io.ChannelDataInput) ChannelImageInputStream(org.apache.sis.internal.storage.io.ChannelImageInputStream) ChannelDataInput(org.apache.sis.internal.storage.io.ChannelDataInput) Test(org.junit.Test)

Aggregations

ChannelDataInput (org.apache.sis.internal.storage.io.ChannelDataInput)7 ChannelImageInputStream (org.apache.sis.internal.storage.io.ChannelImageInputStream)5 ByteBuffer (java.nio.ByteBuffer)3 ImageInputStream (javax.imageio.stream.ImageInputStream)3 DataInput (java.io.DataInput)2 InputStream (java.io.InputStream)2 BufferedInputStream (java.io.BufferedInputStream)1 IOException (java.io.IOException)1 ReadableByteChannel (java.nio.channels.ReadableByteChannel)1 Decoder (org.apache.sis.internal.netcdf.Decoder)1 ChannelDecoder (org.apache.sis.internal.netcdf.impl.ChannelDecoder)1 ChannelFactory (org.apache.sis.internal.storage.io.ChannelFactory)1 GeometryLibrary (org.apache.sis.setup.GeometryLibrary)1 DataStoreException (org.apache.sis.storage.DataStoreException)1 Test (org.junit.Test)1