diff --git a/src/com/amazon/ion/impl/IonCursorBinary.java b/src/com/amazon/ion/impl/IonCursorBinary.java index 5308dffc7e..ed1d9defe7 100644 --- a/src/com/amazon/ion/impl/IonCursorBinary.java +++ b/src/com/amazon/ion/impl/IonCursorBinary.java @@ -9,6 +9,7 @@ import com.amazon.ion.IonCursor; import com.amazon.ion.IonType; import com.amazon.ion.IvmNotificationConsumer; +import com.amazon.ion.SystemSymbols; import java.io.ByteArrayInputStream; import java.io.EOFException; @@ -1786,8 +1787,9 @@ Marker getValueMarker() { * can be used to seek the reader to a "span" of bytes that represent a value in the stream. * @param offset the offset at which the slice will begin. * @param limit the slice's limit. + * @param ionVersionId the Ion version ID for the slice, e.g. $ion_1_0 for Ion 1.0. */ - void slice(long offset, long limit) { + void slice(long offset, long limit, String ionVersionId) { peekIndex = offset; this.limit = limit; setCheckpointBeforeUnannotatedTypeId(); @@ -1795,6 +1797,14 @@ void slice(long offset, long limit) { event = Event.NEEDS_DATA; valueTid = null; containerIndex = -1; // Slices are treated as if they were at the top level. + if (SystemSymbols.ION_1_0.equals(ionVersionId)) { + typeIds = IonTypeID.TYPE_IDS_1_0; + majorVersion = 1; + minorVersion = 0; + } else { + // TODO changes are needed here to support Ion 1.1. + throw new IonException(String.format("Attempted to seek using an unsupported Ion version %s.", ionVersionId)); + } } /** diff --git a/src/com/amazon/ion/impl/IonReaderContinuableTopLevelBinary.java b/src/com/amazon/ion/impl/IonReaderContinuableTopLevelBinary.java index 8e06fafe14..25a9383f8e 100644 --- a/src/com/amazon/ion/impl/IonReaderContinuableTopLevelBinary.java +++ b/src/com/amazon/ion/impl/IonReaderContinuableTopLevelBinary.java @@ -308,8 +308,8 @@ public void hoist(Span span) { // of the value to be the end of the stream, in order to comply with the SeekableReader contract. From // an implementation perspective, this is not necessary; if we leave the buffer's limit unchanged, the // reader can continue after processing the hoisted value. - slice(binarySpan.bufferOffset, binarySpan.bufferLimit); restoreSymbolTable(binarySpan.symbolTable); + slice(binarySpan.bufferOffset, binarySpan.bufferLimit, binarySpan.symbolTable.getIonVersionId()); type = null; } } diff --git a/test/com/amazon/ion/streaming/SeekableReaderTest.java b/test/com/amazon/ion/streaming/SeekableReaderTest.java index 5510068edc..066249d386 100644 --- a/test/com/amazon/ion/streaming/SeekableReaderTest.java +++ b/test/com/amazon/ion/streaming/SeekableReaderTest.java @@ -19,6 +19,7 @@ import com.amazon.ion.IonType; import com.amazon.ion.IonWriter; import com.amazon.ion.ReaderMaker; +import com.amazon.ion.SeekableReader; import com.amazon.ion.Span; import com.amazon.ion.TestUtils; import com.amazon.ion.impl._Private_Utils; @@ -327,6 +328,22 @@ public void testHoistingAcrossSymbolTableBoundary() expectTopEof(); } + @Test + public void testHoistingFromSpanCreatedByDifferentReaderBeforeNext() + { + read("foo bar"); + in.next(); + in.next(); + Span barSpan = sr.currentSpan(); + + read("foo bar"); // Creates a new reader + initFacets(); + + hoist(barSpan); + assertSame(IonType.SYMBOL, in.next()); + assertEquals("bar", in.stringValue()); + } + //======================================================================== // Failure cases