Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
87 changes: 87 additions & 0 deletions src/main/java/com/amazon/ion/IonSystem.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,14 @@

package com.amazon.ion;

import com.amazon.ion.impl._Private_ByteBufferUtils;
import com.amazon.ion.system.IonSystemBuilder;
import com.amazon.ion.system.IonTextWriterBuilder;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Reader;
import java.nio.ByteBuffer;
import java.util.Date;
import java.util.Iterator;

Expand Down Expand Up @@ -319,6 +321,36 @@ public SymbolTable newSharedSymbolTable(String name,
@Deprecated
public Iterator<IonValue> iterate(byte[] ionData);

/**
* Creates an iterator over the Ion data in the given {@link ByteBuffer}.
* Values returned by the iterator have no container.
* <p>
* The iterator will automatically consume Ion system IDs and local symbol
* tables; they will not be returned by the iterator.
* <p>
* This method reads the buffer's <em>remaining</em> bytes (from its current
* {@code position} up to its {@code limit}) and will auto-detect and
* uncompress GZIPped Ion data. It works for all kinds of {@link ByteBuffer},
* including array-backed, direct (off-heap), and read-only buffers.
* <p>
* On return, the buffer's {@code position} has been advanced to its
* {@code limit} (its remaining bytes have been consumed); the buffer's
* {@code limit}, {@code capacity}, and contents are otherwise unchanged.
* The returned iterator operates over a private copy of the bytes, so later
* modifications to the buffer do not affect iteration.
*
* @param ionData may be either Ion binary data, or (UTF-8) Ion text, or
* GZIPped Ion data. Must not be null.
*
* @return a new iterator instance.
*
* @throws NullPointerException if {@code ionData} is null.
*/
default Iterator<IonValue> iterate(ByteBuffer ionData)
{
return iterate(_Private_ByteBufferUtils.toByteArrayConsuming(ionData));
}

/**
* <p>
* Creates an iterator over Ion data.
Expand Down Expand Up @@ -394,6 +426,34 @@ public SymbolTable newSharedSymbolTable(String name,
*/
public IonValue singleValue(byte[] ionData, int offset, int len);

/**
* Extracts a single value from the Ion data in the given {@link ByteBuffer}.
* <p>
* This method reads the buffer's <em>remaining</em> bytes (from its current
* {@code position} up to its {@code limit}) and will auto-detect and
* uncompress GZIPped Ion data. It works for all kinds of {@link ByteBuffer},
* including array-backed, direct (off-heap), and read-only buffers.
* <p>
* On return, the buffer's {@code position} has been advanced to its
* {@code limit} (its remaining bytes have been consumed); the buffer's
* {@code limit}, {@code capacity}, and contents are otherwise unchanged.
*
* @param ionData may be either Ion binary data, or (UTF-8) Ion text, or
* GZIPped Ion data. Must not be null.
*
* @return the first (and only) user value in the data; not null.
*
* @throws NullPointerException if {@code ionData} is null.
* @throws UnexpectedEofException if the data doesn't contain any user
* values.
* @throws IonException if the data does not contain exactly one user
* value.
*/
default IonValue singleValue(ByteBuffer ionData)
{
return singleValue(_Private_ByteBufferUtils.toByteArrayConsuming(ionData));
}


//-------------------------------------------------------------------------
// IonReader creation
Expand Down Expand Up @@ -448,6 +508,33 @@ public SymbolTable newSharedSymbolTable(String name,
*/
public IonReader newReader(byte[] ionData, int offset, int len);

/**
* Creates a new {@link IonReader} instance over the Ion data in the given
* {@link ByteBuffer}, detecting whether it's text or binary data.
* <p>
* This method reads the buffer's <em>remaining</em> bytes (from its current
* {@code position} up to its {@code limit}) and will auto-detect and
* uncompress GZIPped Ion data. It works for all kinds of {@link ByteBuffer},
* including array-backed, direct (off-heap), and read-only buffers.
* <p>
* On return, the buffer's {@code position} has been advanced to its
* {@code limit} (its remaining bytes have been consumed); the buffer's
* {@code limit}, {@code capacity}, and contents are otherwise unchanged.
* The returned reader operates over a private copy of the bytes, so later
* modifications to the buffer do not affect reading.
*
* @param ionData may be either Ion binary data, or (UTF-8) Ion text, or
* GZIPped Ion data. Must not be null.
*
* @return a new reader instance.
*
* @throws NullPointerException if {@code ionData} is null.
*/
default IonReader newReader(ByteBuffer ionData)
{
return newReader(_Private_ByteBufferUtils.toByteArrayConsuming(ionData));
}

/**
* Creates a new {@link IonReader} instance over a stream of Ion data,
* detecting whether it's text or binary data.
Expand Down
56 changes: 56 additions & 0 deletions src/main/java/com/amazon/ion/impl/_Private_ByteBufferUtils.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/*
* Copyright 2007-2026 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License").
* You may not use this file except in compliance with the License.
* A copy of the License is located at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* or in the "license" file accompanying this file. This file is distributed
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/

package com.amazon.ion.impl;

import java.nio.ByteBuffer;

/**
* Internal helpers for adapting {@link java.nio.ByteBuffer} inputs to the
* {@code byte[]}-based factory methods on {@link com.amazon.ion.IonSystem}.
* <p>
* <b>This is an internal API and is subject to change without notice.</b>
*/
public final class _Private_ByteBufferUtils
{
private _Private_ByteBufferUtils() {}

/**
* Copies the readable region of the given buffer (the bytes between its
* current {@code position} and its {@code limit}) into a newly allocated
* {@code byte[]}, advancing the buffer's {@code position} to its
* {@code limit} as a side effect (i.e. the remaining bytes are consumed).
* <p>
* This uses a relative bulk {@link ByteBuffer#get(byte[])}, which works for
* every kind of {@link ByteBuffer} &mdash; array-backed, direct (off-heap),
* and read-only &mdash; and never throws {@link java.nio.ReadOnlyBufferException}.
* The returned array is an independent copy, so subsequent mutations of the
* buffer do not affect it.
*
* @param buffer the buffer to read from; must not be null.
* @return a new array containing the buffer's (former) remaining bytes.
* @throws NullPointerException if {@code buffer} is null.
*/
public static byte[] toByteArrayConsuming(ByteBuffer buffer)
{
if (buffer == null)
{
throw new NullPointerException("ionData");
}
byte[] bytes = new byte[buffer.remaining()];
buffer.get(bytes);
return bytes;
}
}
Loading