You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sis.apache.org by de...@apache.org on 2014/04/28 12:12:30 UTC
svn commit: r1590585 - in /sis/branches/JDK8/storage/sis-storage/src:
main/java/org/apache/sis/internal/storage/
test/java/org/apache/sis/internal/storage/
Author: desruisseaux
Date: Mon Apr 28 10:12:30 2014
New Revision: 1590585
URL: http://svn.apache.org/r1590585
Log:
More tests when seeking ahead in the output stream.
Modified:
sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/ChannelDataInput.java
sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/ChannelDataOutput.java
sis/branches/JDK8/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/ByteArrayChannel.java
sis/branches/JDK8/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/ChannelDataOutputTest.java
Modified: sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/ChannelDataInput.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/ChannelDataInput.java?rev=1590585&r1=1590584&r2=1590585&view=diff
==============================================================================
--- sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/ChannelDataInput.java [UTF-8] (original)
+++ sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/ChannelDataInput.java [UTF-8] Mon Apr 28 10:12:30 2014
@@ -560,7 +560,7 @@ public class ChannelDataInput extends Ch
while ((length -= n) != 0) {
offset += n;
ensureBufferContains(dataSize); // Actually read as much data as possible.
- view.position(0).limit(buffer.remaining() / dataSize);
+ view.rewind().limit(buffer.remaining() / dataSize);
transfer(offset, n = Math.min(view.remaining(), length));
skipInBuffer(n * dataSize);
}
Modified: sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/ChannelDataOutput.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/ChannelDataOutput.java?rev=1590585&r1=1590584&r2=1590585&view=diff
==============================================================================
--- sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/ChannelDataOutput.java [UTF-8] (original)
+++ sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/ChannelDataOutput.java [UTF-8] Mon Apr 28 10:12:30 2014
@@ -16,6 +16,7 @@
*/
package org.apache.sis.internal.storage;
+import java.util.Arrays;
import java.io.Flushable;
import java.io.IOException;
import java.nio.Buffer;
@@ -105,7 +106,7 @@ public class ChannelDataOutput extends C
if (after > buffer.limit()) {
/*
* We will increase the limit for every new 'put' operation in order to maintain the number
- * of valid bytes in the buffer. In the new limit would exceed the buffer capacity, then we
+ * of valid bytes in the buffer. If the new limit would exceed the buffer capacity, then we
* need to write some bytes now.
*/
if (after > capacity) {
@@ -479,7 +480,7 @@ public class ChannelDataOutput extends C
while ((length -= n) != 0) {
offset += n;
ensureBufferAccepts(Math.min(length, view.capacity()) * dataSize);
- view.position(0).limit(buffer.remaining() / dataSize);
+ view.rewind().limit(buffer.remaining() / dataSize);
transfer(offset, n = view.remaining());
skipInBuffer(n * dataSize);
}
@@ -583,7 +584,25 @@ public class ChannelDataOutput extends C
}
/**
+ * Fills the buffer with the zero values from its position up to the limit.
+ * After this method call, the position is undetermined and shall be set to
+ * a new value by the caller.
+ */
+ private void clear() {
+ if (buffer.hasArray()) {
+ final int offset = buffer.arrayOffset();
+ Arrays.fill(buffer.array(), offset + buffer.position(), offset + buffer.limit(), (byte) 0);
+ } else {
+ while (buffer.hasRemaining()) {
+ buffer.put((byte) 0);
+ }
+ }
+ }
+
+ /**
* Moves to the given position in the stream, relative to the stream position at construction time.
+ * If the given position is greater than the stream length, then the values of bytes between the
+ * previous stream length and the given position are unspecified. The limit is unchanged.
*
* @param position The position where to move.
* @throws IOException If the stream can not be moved to the given position.
@@ -591,10 +610,15 @@ public class ChannelDataOutput extends C
@Override
public final void seek(final long position) throws IOException {
long p = position - bufferOffset;
- if (p >= 0 && p <= buffer.limit()) {
+ if (p >= 0 && p <= buffer.capacity()) {
/*
- * Requested position is inside the current limits of the buffer.
+ * Requested position is inside the current capacity of the buffer.
+ * If the position is greater than the limit, we will set the new bytes to 0.
*/
+ if (p > buffer.limit()) {
+ buffer.position(buffer.limit()).limit((int) p);
+ clear();
+ }
buffer.position((int) p);
clearBitOffset();
} else if (channel instanceof SeekableByteChannel) {
@@ -605,6 +629,30 @@ public class ChannelDataOutput extends C
flush();
((SeekableByteChannel) channel).position(channelOffset + position);
bufferOffset = position;
+ } else if (p >= 0) {
+ /*
+ * Requested position is after the current buffer capacity and
+ * we can not seek, so we have to pad with some zero values.
+ */
+ p -= buffer.limit();
+ flush(); // Also set the position to 0.
+ if (p <= buffer.capacity()) {
+ buffer.limit((int) p);
+ clear();
+ buffer.position((int) p);
+ } else {
+ buffer.clear();
+ clear();
+ do {
+ if (channel.write(buffer) == 0) {
+ onEmptyTransfer();
+ }
+ bufferOffset += buffer.position();
+ p -= buffer.position();
+ buffer.rewind();
+ } while (p > buffer.capacity());
+ buffer.limit((int) p).position((int) p);
+ }
} else {
// We can not move position beyond the buffered part.
throw new IOException(Errors.format(Errors.Keys.StreamIsForwardOnly_1, filename));
@@ -619,7 +667,7 @@ public class ChannelDataOutput extends C
*/
@Override
public final void flush() throws IOException {
- buffer.position(0);
+ buffer.rewind();
writeFully();
buffer.limit(0);
clearBitOffset();
@@ -633,7 +681,7 @@ public class ChannelDataOutput extends C
@Override
final void flushAndSetPosition(final int position) throws IOException {
final int limit = buffer.limit();
- buffer.position(0).limit(position);
+ buffer.rewind().limit(position);
writeFully();
buffer.limit(limit);
}
Modified: sis/branches/JDK8/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/ByteArrayChannel.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/ByteArrayChannel.java?rev=1590585&r1=1590584&r2=1590585&view=diff
==============================================================================
--- sis/branches/JDK8/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/ByteArrayChannel.java [UTF-8] (original)
+++ sis/branches/JDK8/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/ByteArrayChannel.java [UTF-8] Mon Apr 28 10:12:30 2014
@@ -111,7 +111,7 @@ final strictfp class ByteArrayChannel im
@Override
public SeekableByteChannel position(final long newPosition) throws IOException {
ensureOpen();
- ArgumentChecks.ensureBetween("position", 0, limit, newPosition);
+ ArgumentChecks.ensureBetween("position", 0, data.length, newPosition);
position = (int) newPosition;
return this;
}
Modified: sis/branches/JDK8/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/ChannelDataOutputTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/ChannelDataOutputTest.java?rev=1590585&r1=1590584&r2=1590585&view=diff
==============================================================================
--- sis/branches/JDK8/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/ChannelDataOutputTest.java [UTF-8] (original)
+++ sis/branches/JDK8/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/ChannelDataOutputTest.java [UTF-8] Mon Apr 28 10:12:30 2014
@@ -136,6 +136,30 @@ public strictfp class ChannelDataOutputT
}
/**
+ * Tests seek ahead of buffer capacity.
+ *
+ * @throws IOException Should never happen.
+ */
+ @Test
+ @DependsOnMethod("testWriteAndSeek")
+ public void testSeekAhead() throws IOException {
+ initialize("testArgumentChecks", 48, 10);
+ for (int i=0; i<3; i++) {
+ final long v = random.nextLong();
+ referenceStream.writeLong(v);
+ testedStream.writeLong(v);
+ }
+ assertEquals("getStreamPosition()", 24, testedStream.getStreamPosition());
+ testedStream.seek(40); // Move 2 long ahead. Space shall be filled by 0.
+ referenceStream.writeLong(0);
+ referenceStream.writeLong(0);
+ final long v = random.nextLong();
+ referenceStream.writeLong(v);
+ testedStream.writeLong(v);
+ assertStreamContentEquals();
+ }
+
+ /**
* Tests the argument checks performed by various methods. For example this method
* tests {@link ChannelDataOutput#seek(long)} with an invalid seek position.
*
@@ -152,13 +176,6 @@ public strictfp class ChannelDataOutputT
assertTrue(message, message.contains("bitOffset"));
}
try {
- testedStream.seek(1);
- fail("Shall not seek further than stream length.");
- } catch (IllegalArgumentException e) {
- final String message = e.getMessage();
- assertTrue(message, message.contains("position"));
- }
- try {
testedStream.reset();
fail("Shall not accept reset without mark.");
} catch (InvalidMarkException e) {