public interface IonWriter extends Closeable, Flushable, Faceted
WARNING: This interface should not be implemented or extended by code outside of this library.
A value is written via the set of typed write*()
methods such as
writeBool(boolean)
and writeInt(long)
.
Each of these methods outputs a single Ion value, and afterwards the writer
is prepared to receive the data for the next sibling value.
Any type annotations must be set before the value is written. Once the value has been written the "pending annotations" are erased, so they are must be set again if they need to be applied to the next value.
Similarly the field name must be set before the value is written (assuming the value is a field in a structure). The field name is also "erased" once used, so it must be set for each field.
To write a container, first write any annotations and/or field name
applicable to the container itself.
Then call stepIn(IonType)
with the desired container type.
Then write each child value in order.
Finally, call stepOut()
to complete the container.
Once all the top-level values have been written (and stepped-out back to
the starting level), the caller must close()
the writer
(or at least flush()
or finish()
it) before accessing
the data written to the underlying data sink
(for example, via ByteArrayOutputStream.toByteArray()
).
The writer may have internal buffers and without closing, flushing, or
finishing it, it may not have written everything to the underlying data
sink.
IonWriter
is a generic interface for generating Ion data, and it's
not possible to fully specify the set of exceptions that could be thrown
from the underlying data sink. Thus all failures are thrown as instances
of IonException
, wrapping the originating cause. If an application
wants to handle (say) IOException
s specially, then it needs to
extract that from the wrappers; the documentation of IonException
explains how to do that.IonStreamUtils
,
IonTextWriterBuilder
Modifier and Type | Method and Description |
---|---|
void |
addTypeAnnotation(String annotation)
Adds a given string to the list of pending annotations.
|
void |
close()
Closes this stream and releases any system resources associated with it.
|
void |
finish()
Indicates that writing is completed and all buffered data should be
written and flushed as if this were the end of the Ion data stream.
|
void |
flush()
Flushes this writer by writing any buffered output to the underlying
output target without finalizing the stream's local symbol table.
|
SymbolTable |
getSymbolTable()
Gets the symbol table that is currently in use by the writer.
|
boolean |
isInStruct()
Determines whether values are being written as fields of a struct.
|
void |
setFieldName(String name)
Sets the pending field name to the given text.
|
void |
setFieldNameSymbol(SymbolToken name)
Sets the pending field name to the given token.
|
void |
setTypeAnnotations(String... annotations)
Sets the full list of pending annotations to the given text symbols.
|
void |
setTypeAnnotationSymbols(SymbolToken... annotations)
Sets the full list of pending annotations to the given symbols.
|
void |
stepIn(IonType containerType)
Writes the beginning of a non-null container (list, sexp, or struct).
|
void |
stepOut()
Writes the end of the current container, returning this writer to the
context of parent container.
|
void |
writeBlob(byte[] value)
write the byte array out as an IonBlob value.
|
void |
writeBlob(byte[] value,
int start,
int len)
Writes a portion of the byte array out as an IonBlob value.
|
void |
writeBool(boolean value)
writes a non-null boolean value (true or false) as an IonBool
to output.
|
void |
writeClob(byte[] value)
write the byte array out as an IonClob value.
|
void |
writeClob(byte[] value,
int start,
int len)
Writes a portion of the byte array out as an IonClob value.
|
void |
writeDecimal(BigDecimal value)
Writes a BigDecimal value as an Ion decimal.
|
void |
writeFloat(double value)
writes a 64 bit binary floating point value, a Java double,
as an IonFloat.
|
void |
writeInt(BigInteger value)
writes a BigInteger value as an IonInt.
|
void |
writeInt(long value)
writes a signed 64 bit value, a Java long, as an IonInt.
|
void |
writeNull()
Writes a value of Ion's null type (
null aka null.null ). |
void |
writeNull(IonType type)
Writes a null value of a specified Ion type.
|
void |
writeString(String value)
Writes a
String as an Ion string. |
void |
writeSymbol(String content)
Writes the text of an Ion symbol value.
|
void |
writeSymbolToken(SymbolToken content)
Writes the content of an Ion symbol value.
|
void |
writeTimestamp(Timestamp value)
Writes a timestamp value.
|
void |
writeTimestampUTC(Date value)
Deprecated.
Use
IonWriter.writeTimestamp( Timestamp.forDateZ(Date)) instead. |
void |
writeValue(IonReader reader)
Writes the current value from a reader.
|
void |
writeValue(IonValue value)
Deprecated.
Use
IonValue.writeTo(IonWriter) instead. |
void |
writeValues(IonReader reader)
Writes a reader's current value, and all following values until the end
of the current container.
|
SymbolTable getSymbolTable()
Note that the table may be replaced during processing. For example, the stream may start out with a system table that's later replaced by a local table in order to store newly-encountered symbols.
When this method returns a local table, it may be
mutable, meaning that additional
symbols may be interned until it is
made read-only. Note that
manually mutating local symbol tables is a deprecated feature;
please instead use
IonSystem.newBinaryWriter(java.io.OutputStream, SymbolTable...)
or IonSystem.newTextWriter(java.io.OutputStream, SymbolTable...)
to provide custom symbol table(s) to writers upon construction.
void flush() throws IOException
For some implementations this may have no effect even when some data is buffered, because it's not always possible to fully write partial data. In particular, when writing binary Ion data, Ion's length-prefixed encoding requires a complete top-level value to be written at once.
If localSymbolTableAppend is enabled (see
IonBinaryWriterBuilder.withLocalSymbolTableAppendEnabled()
),
this feature can be used to flush buffered data before writing more
values without subsequently having to redeclare the current local
symbol table. Applications that produce long streams of binary Ion may
wish to flush occasionally to relieve memory pressure, then continue
writing data using the same local symbol table. The symbol table will
be appended with newly-encountered symbols as necessary.
flush
in interface Flushable
IOException
- if thrown by the underlying output target.finish()
void finish() throws IOException
This method may only be called when all top-level values are completely written and stepped-out.
Implementations should allow the application to continue writing further
top-level values following the semantics for concatenating Ion data
streams. If another top-level value is written, the result must behave
as if it were preceded by an Ion version marker, resetting the stream
context as if this were a new stream. (Whether or not an IVM is written
may depend upon the writer's configuration; see
IvmMinimizing
.)
This feature can be used to flush buffered data and reset the local
symbol table before writing more values. Applications that produce long
streams of binary Ion may wish to finish occasionally to relieve memory
pressure, then continue writing data using a new local symbol table.
This is particularly useful for streams that contain an ever-growing
number of unique symbols to avoid unbounded growth of the symbol table,
which may degrade performance and bloat the encoding. Applications that
produce long streams with a limited number of unique symbols should
enable localSymbolTableAppend (see
IonBinaryWriterBuilder.withLocalSymbolTableAppendEnabled()
)
and flush()
instead to avoid re-declaring the local symbol
table unnecessarily.
IOException
- if thrown by the underlying output target.IllegalStateException
- when not between top-level values.flush()
,
close()
void close() throws IOException
If the cursor is between top-level values, this method will
finish()
before closing the underlying output stream.
If not, the resulting data may be incomplete and invalid Ion.
In other words: unless you're recovering from a failure condition, don't close the writer until you've stepped-out back to the starting level.
close
in interface AutoCloseable
close
in interface Closeable
IOException
- if thrown by the underlying output target.finish()
void setFieldName(String name)
The pending field name is cleared when the current value is
written via stepIn()
or one of the
write*()
methods.
name
- text of the field nameIllegalStateException
- if the current container isn't a struct,
that is, if isInStruct()
is false.NullPointerException
- if name
is null.void setFieldNameSymbol(SymbolToken name)
The pending field name is cleared when the current value is
written via stepIn()
or one of the
write*()
methods.
name
- text of the field nameIllegalStateException
- if the current container isn't a struct,
that is, if isInStruct()
is false.NullPointerException
- if name
is null.void setTypeAnnotations(String... annotations)
annotations
array are copied into this
writer, so the caller does not need to preserve the array.
The list of pending annotations is cleared when the current value is
written via stepIn()
or one of the
write*()
methods.
annotations
- string array with the annotations.
If null or empty, any pending annotations are cleared.void setTypeAnnotationSymbols(SymbolToken... annotations)
annotations
array are copied into this
writer, so the caller does not need to preserve the array.
The list of pending annotations is cleared when the current value is
written via stepIn()
or one of the
write*()
methods.
This is an "expert method": correct use requires deep understanding of the Ion binary format. You almost certainly don't want to use it.
annotations
- If null or empty, any pending annotations are cleared.void addTypeAnnotation(String annotation)
The list of pending annotations is cleared when the current value is
written via stepIn()
or one of the
write*()
methods.
annotation
- string annotation to append to the annotation listvoid stepIn(IonType containerType) throws IOException
stepOut()
after the last
child value.
This method is not used to write null.list
et al.
To write null values use writeNull(IonType)
.
containerType
- must be one of
IonType.LIST
, IonType.SEXP
, or IonType.STRUCT
.IOException
void stepOut() throws IOException
stepIn(IonType)
.IOException
boolean isInStruct()
@Deprecated void writeValue(IonValue value) throws IOException
IonValue.writeTo(IonWriter)
instead.This method also writes annotations and field names (if in a struct), and performs a deep write, including the contents of any containers encountered.
value
- may be null, in which case this method does nothing.IOException
void writeValue(IonReader reader) throws IOException
This method also writes annotations and field names (if in a struct), and performs a deep write, including the contents of any containers encountered.
IOException
void writeValues(IonReader reader) throws IOException
IonReader.next()
to get going.
This method iterates until IonReader.next()
returns null
and does not step out to the container
of the current cursor position.
This method also writes annotations and field names (if in a struct), and performs a deep write, including the contents of any containers encountered.
IOException
void writeNull() throws IOException
null
aka null.null
).IOException
void writeNull(IonType type) throws IOException
type
- type of the null to be writtenIOException
void writeBool(boolean value) throws IOException
value
- true or false as desiredIOException
void writeInt(long value) throws IOException
value
- signed int to writeIOException
void writeInt(BigInteger value) throws IOException
value
- BigInteger to writeIOException
void writeFloat(double value) throws IOException
value
- double to writeIOException
void writeDecimal(BigDecimal value) throws IOException
To write a negative zero value, pass this method a
Decimal
instance.
value
- may be null to represent null.decimal
.IOException
void writeTimestamp(Timestamp value) throws IOException
value
- may be null to represent null.timestamp
.IOException
@Deprecated void writeTimestampUTC(Date value) throws IOException
IonWriter.writeTimestamp(
Timestamp.forDateZ(Date))
instead.value
- java.util Date holding the UTC timestamp;
may be null to represent null.timestamp
.IOException
void writeSymbol(String content) throws IOException
content
- may be null to represent null.symbol
.IllegalArgumentException
- if the value contains an invalid UTF-16
surrogate pair.IOException
void writeSymbolToken(SymbolToken content) throws IOException
content
- may be null to represent null.symbol
.IllegalArgumentException
- if the value contains an invalid UTF-16
surrogate pair.IOException
void writeString(String value) throws IOException
String
as an Ion string. Since Ion strings are
UTF-8 and Java Strings are Unicode 16. As such the resulting
lengths may not match. In addition some Java strings are not
valid as they may contain only one of the two needed surrogate
code units necessary to define the Unicode code point to be
output, an exception will be raised if this case is encountered.value
- may be null to represent null.string
.IllegalArgumentException
- if the value contains an invalid UTF-16
surrogate pair.IOException
void writeClob(byte[] value) throws IOException
value
- may be null to represent null.clob
.IOException
void writeClob(byte[] value, int start, int len) throws IOException
value
- bytes to be written.
May be null
to represent null.clob
.start
- offset of the first byte in value to writelen
- number of bytes to write from valueIOException
void writeBlob(byte[] value) throws IOException
value
- may be null to represent null.blob
.IOException
void writeBlob(byte[] value, int start, int len) throws IOException
value
- bytes to be written.
May be null
to represent null.blob
.start
- offset of the first byte in value to writelen
- number of bytes to write from valueIOException