db-derby-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From krist...@apache.org
Subject svn commit: r677521 - in /db/derby/code/branches/10.3/java: engine/org/apache/derby/impl/jdbc/PositionedStoreStream.java testing/org/apache/derbyTesting/functionTests/tests/store/PositionedStoreStreamTest.java
Date Thu, 17 Jul 2008 07:26:03 GMT
Author: kristwaa
Date: Thu Jul 17 00:26:02 2008
New Revision: 677521

URL: http://svn.apache.org/viewvc?rev=677521&view=rev
Log:
DERBY-3781: PositionedStoreStream.reposition(pos) with pos greater than length leaves the
stream object in an inconsistent state.
Merged revisions 677172 (derby-3781-1a-fix_and_test.diff) and 677281 (derby-3781-2b-remove_convenience_link.diff)
from trunk.

Modified:
    db/derby/code/branches/10.3/java/engine/org/apache/derby/impl/jdbc/PositionedStoreStream.java
    db/derby/code/branches/10.3/java/testing/org/apache/derbyTesting/functionTests/tests/store/PositionedStoreStreamTest.java

Modified: db/derby/code/branches/10.3/java/engine/org/apache/derby/impl/jdbc/PositionedStoreStream.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.3/java/engine/org/apache/derby/impl/jdbc/PositionedStoreStream.java?rev=677521&r1=677520&r2=677521&view=diff
==============================================================================
--- db/derby/code/branches/10.3/java/engine/org/apache/derby/impl/jdbc/PositionedStoreStream.java
(original)
+++ db/derby/code/branches/10.3/java/engine/org/apache/derby/impl/jdbc/PositionedStoreStream.java
Thu Jul 17 00:26:02 2008
@@ -60,9 +60,6 @@
     /** Underlying store stream serving bytes. */
     //@GuardedBy("EmbedConnection.getConnectionSynchronization()")
     private final InputStream stream;
-    /** Convenience reference to the stream as a resettable stream. */
-    //@GuardedBy("EmbedConnection.getConnectionSynchronization()")
-    private final Resetable resettable;
     /**
      * Position of the underlying store stream.
      * Note that the position is maintained by this class, not the underlying
@@ -78,12 +75,9 @@
      * stream.
      *
      * @param in a {@link Resetable}-stream
-     * @throws ClassCastException if the inputstream does not implement
-     *      {@link Resetable}
      */
     public PositionedStoreStream(InputStream in) {
         this.stream = in;
-        this.resettable = (Resetable)in;
     }
 
     /**
@@ -153,7 +147,7 @@
      */
     public void resetStream()
             throws IOException, StandardException {
-        this.resettable.resetStream();
+        ((Resetable)this.stream).resetStream();
         this.pos = 0L;
     }
 
@@ -165,7 +159,7 @@
      */
     public void initStream()
             throws StandardException {
-        this.resettable.initStream();
+        ((Resetable)this.stream).initStream();
         this.pos = 0L;
     }
 
@@ -175,7 +169,7 @@
      * @see Resetable#closeStream
      */
     public void closeStream() {
-        this.resettable.closeStream();
+        ((Resetable)this.stream).closeStream();
     }
 
     /**
@@ -185,22 +179,34 @@
      * stream, which changes the position of it. If a class is dependent on the
      * underlying stream not changing its position, it must call reposition with
      * the position it expects before using the stream again.
+     * <p>
+     * If the repositioning fails because the stream is exhausted, most likely
+     * because of an invalid position specified by the user, the stream is
+     * reset to position zero and the {@code EOFException} is rethrown.
      *
+     * @throws EOFException if the stream is exhausted before the requested
+     *      position is reached
      * @throws IOException if reading from the store stream fails
      * @throws StandardException if resetting the store in stream fails, or
      *      some other exception happens in store
      * @see #getPosition
      */
-    public void reposition(long requestedPos)
+    public void reposition(final long requestedPos)
             throws IOException, StandardException {
+        if (this.pos > requestedPos) {
+            // Reset stream to reposition from start.
+            resetStream();
+        }
         if (this.pos < requestedPos) {
-            // Reposition from current position.
-            skipFully(requestedPos - this.pos);
-            this.pos = requestedPos;
-        } else if (this.pos > requestedPos) {
-            // Reposition from start.
-            this.resettable.resetStream();
-            skipFully(requestedPos);
+            try {
+                skipFully(requestedPos - this.pos);
+            } catch (EOFException eofe) {
+                // A position after the end of the stream was requested.
+                // To recover, and for consistency, reset to position zero.
+                resetStream();
+                throw eofe;
+            }
+            // Operation successful, update position.
             this.pos = requestedPos;
         }
     }

Modified: db/derby/code/branches/10.3/java/testing/org/apache/derbyTesting/functionTests/tests/store/PositionedStoreStreamTest.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.3/java/testing/org/apache/derbyTesting/functionTests/tests/store/PositionedStoreStreamTest.java?rev=677521&r1=677520&r2=677521&view=diff
==============================================================================
--- db/derby/code/branches/10.3/java/testing/org/apache/derbyTesting/functionTests/tests/store/PositionedStoreStreamTest.java
(original)
+++ db/derby/code/branches/10.3/java/testing/org/apache/derbyTesting/functionTests/tests/store/PositionedStoreStreamTest.java
Thu Jul 17 00:26:02 2008
@@ -22,6 +22,7 @@
  */
 package org.apache.derbyTesting.functionTests.tests.store;
 
+import java.io.EOFException;
 import java.io.IOException;
 import java.io.InputStream;
 
@@ -199,6 +200,45 @@
         pss.reposition(0);
     }
 
+    /**
+     * Tests that trying to move past the end of the stream leaves the stream
+     * object in a consistent state, and can be repositioned again after the
+     * failed reposition attempt.
+     * <p>
+     * Issue logged in Jira as DERBY-3781
+     *
+     * @throws IOException if reading the stream fails unexpectedly
+     * @throws StandardException will never happen
+     */
+    public void testDerby3781()
+            throws IOException, StandardException {
+        final long size = 10;
+        InputStream in = new LoopingAlphabetStream(size);
+        PositionedStoreStream pss = new PositionedStoreStream(in);
+        assertEquals("Invalid initial position", 0L, pss.getPosition());
+        pss.reposition(size -1); // Goto end.
+        assertEquals(size -1, pss.getPosition());
+        assertEquals('j', pss.read());
+        assertEquals(size, pss.getPosition());
+        assertEquals(-1, pss.read());
+        // This step is crucial, position must be different than zero when the
+        // first exception below is thrown.
+        pss.reposition(size / 2); // Goto middle.
+        assertEquals(size / 2, pss.getPosition());
+        try {
+            pss.reposition(size *2); // Try to go past end.
+            fail("Should have failed with EOFException");
+        } catch (EOFException eofe) {
+            // Ignore this exception
+        }
+        // Failed here before, because internal state was inconsistent.
+        // Assumed: pos = 5, underlying stream at pos 5, skipped (size -1 - pos)
+        // Actual: pos = 5, underlying stream at pos (size -1)
+        pss.reposition(size -1); // Goto end.
+        assertEquals(size -1, pss.getPosition());
+        assertEquals('j', pss.read());
+    }
+
     public static Test suite() {
         return new TestSuite(
                 PositionedStoreStreamTest.class, "PositionedStoreStreamTest");



Mime
View raw message