diff --git a/java-manta-client-unshaded/src/main/java/com/joyent/manta/client/MantaSeekableByteChannel.java b/java-manta-client-unshaded/src/main/java/com/joyent/manta/client/MantaSeekableByteChannel.java index 5f5a1849..aa9ddd51 100644 --- a/java-manta-client-unshaded/src/main/java/com/joyent/manta/client/MantaSeekableByteChannel.java +++ b/java-manta-client-unshaded/src/main/java/com/joyent/manta/client/MantaSeekableByteChannel.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2017, Joyent, Inc. All rights reserved. + * Copyright (c) 2016-2019, Joyent, Inc. All rights reserved. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this @@ -30,7 +30,8 @@ * Manta. Connection opening to the remote server happens lazily upon the * first read() or size() method invoked. * - * @author Elijah Zupancic + * @author Elijah Zupancic + * @author Ashwin A Nair */ public class MantaSeekableByteChannel extends InputStream implements SeekableByteChannel { @@ -186,7 +187,7 @@ protected MantaSeekableByteChannel(final AtomicReference request } @Override - public int read(final ByteBuffer dst) throws IOException { + public int read(final ByteBuffer dst) throws IOException, UnsupportedOperationException { if (!open) { throw new ClosedChannelException(); } @@ -198,12 +199,28 @@ public int read(final ByteBuffer dst) throws IOException { return EOF; } - final byte[] buff = dst.array(); - final int bytesRead = stream.read(buff); + if (dst.isReadOnly()) { + throw new MantaClientException("Read-only buffer", new IllegalArgumentException()); + } + + if (!dst.hasArray()) { + throw new MantaClientException("Buffer read not backed by an accessible\n" + + "byte array", new UnsupportedOperationException()); + } else { + + final byte[] buff = new byte[dst.remaining()]; + ByteBuffer dstCopy = dst.get(buff); + dst.position(dstCopy.position() - buff.length); // Restores the buffer position - position.addAndGet(bytesRead); + final int startIndex = dstCopy.arrayOffset(); + final int endIndex = startIndex + dstCopy.position() + dstCopy.remaining(); + final int buffLength = endIndex - startIndex; + final int bytesRead = stream.read(buff, startIndex, buffLength); - return bytesRead; + this.position.addAndGet(bytesRead); + + return bytesRead; + } } /**