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) {