Top Description Fields Constructors Methods
com.amazon.ion.impl.lite

pack-priv Class ReverseBinaryEncoder

extends Object
Class Inheritance
Static Imports
com.amazon.ion.SymbolTable.UNKNOWN_SYMBOL_ID, .SystemSymbols.IMPORTS_SID, .SystemSymbols.ION_SYMBOL_TABLE_SID, .SystemSymbols.MAX_ID_SID, .SystemSymbols.NAME_SID, .SystemSymbols.SYMBOLS_SID, .SystemSymbols.VERSION_SID, com.amazon.ion.impl._Private_IonConstants.BINARY_VERSION_MARKER_1_0, ._Private_IonConstants.lnBooleanFalse, ._Private_IonConstants.lnBooleanTrue, ._Private_IonConstants.lnIsNull, ._Private_IonConstants.lnIsVarLen, ._Private_IonConstants.tidBlob, ._Private_IonConstants.tidBoolean, ._Private_IonConstants.tidClob, ._Private_IonConstants.tidDecimal, ._Private_IonConstants.tidFloat, ._Private_IonConstants.tidList, ._Private_IonConstants.tidNegInt, ._Private_IonConstants.tidNull, ._Private_IonConstants.tidPosInt, ._Private_IonConstants.tidSexp, ._Private_IonConstants.tidString, ._Private_IonConstants.tidStruct, ._Private_IonConstants.tidSymbol, ._Private_IonConstants.tidTimestamp, ._Private_IonConstants.tidTypedecl

Encoder implementation that encodes a IonDatagram into binary format using a reverse encoding algorithm instead of the default pre-order (left-to-right) two-pass algorithm.

This reverse encoding algorithm requires a fully materialized IonDatagram DOM to qualify for use. It uses a single buffer, myBuffer, to hold the entire binary-encoded data, with an integer, myOffset, to index the current position to write the bytes.

The algorithm begins by traversing from the last top-level value to the first top-level value. During this traversal, it recursively goes into the nested values of the top-level value being traversed in a similar last-to-first (right-to-left) order.

Field Summary

Modifier and TypeField and Description
private static final BigInteger
private byte[]
myBuffer

Holds the entire binary encoded data.

private IonSystem
private int
myOffset

Index onto the position where the bytes are last written to the buffer.

private SymbolTable
mySymbolTable

The symbol table attached to the IonValue (and its nested values) that the encoder is currently traversing on.

private static final byte[]
private static final int
private static final byte[]
private static final int
private static final int
private static final int
private static final int
private static final int
private static final int
private static final int
private static final int
private static final int
private static final int
private static final int
private static final int
private static final int
private static final int
private static final int

Constructor Summary

AccessConstructor and Description
pack-priv
ReverseBinaryEncoder(int initialSize)

Method Summary

Modifier and TypeMethod and Description
pack-priv int

Returns:

the number of bytes of the byte array
byteSize
()

Returns the size of the Ion binary-encoded byte array.

private void
checkLocalSymbolTablePlacement(IonValue
the next top-level IonValue to be encoded
nextTopLevelValue
)

Determine if the local symbol table attached to the previous top-level value (TLV), mySymbolTable, needs to be encoded before the next TLV is encoded.

private int
findSid(SymbolToken symToken)

private int

Returns:

the updated offset
growBuffer
(int
the original offset
offset
)

Grows the current buffer and returns the updated offset.

pack-priv void
serialize(IonDatagram dg)

Serialize the IonDatagram into Ion binary-encoding, to the internal byte array buffer of the encoder.

pack-priv void
pack-priv byte[]

Returns:

the newly allocated byte array
toNewByteArray
()

Copies the current contents of the Ion binary-encoded byte array into a new byte array.

pack-priv int

Returns:

the number of bytes copied into dst
toNewByteArray
(byte[]
the byte array into which bytes are to be written
dst
)

Copies the current contents of the Ion binary-encoded byte array into a a given byte array.

pack-priv int

Returns:

the number of bytes copied into dst
toNewByteArray
(byte[]
the byte sub-array into which bytes are to be written
dst
,
int
the offset within the sub-array of the first byte to be written; must be non-negative and no larger than dst.length
offset
)

Copies the current contents of the Ion binary-encoded byte array into a a given byte sub-array.

private void
writeAnnotations(IonValue value, int endOfValueOffset)

private void
writeByte(int b)

pack-priv int

Returns:

the number of bytes written into out
writeBytes
(OutputStream out)

Copies the current contents of the Ion binary-encoded byte array to a specified stream.

private void
writeBytes(byte[] bytes)

private void
writeImport(SymbolTable
the shared symbol table, not local, not system
symTab
)

Write a single import declaration (which refers to a shared SymbolTable).

private void
writeImportsField(SymbolTable
the local symbol table, not shared, not system
symTab
)

Write import declarations (which refer to shared symbol tables) if any exists.

private void
private void
private void
private void
private void
private void
private void
private void
private void
private void
private void
private void
private void
private void
private void
private void
private void
private void
writeIonValue(IonValue value)

Writes the IonValue and its nested values recursively, including annotations.

private void
writeLobContent(byte[] lob)

private void
writeLocalSymbolTable(SymbolTable
the local symbol table, not shared, not system
symTab
)

Write contents of a local symbol table as a struct.

private void
writePrefix(int
the value's type, a four-bit high-nibble mask
type
,
int
the number of bytes (octets) in the body, excluding the prefix itself
length
)

Writes the prefix (type and length) preceding the body of an encoded value.

private void
writeSymbolsField(SymbolTable
the local symbol table, not shared, not system
symTab
)

Write declared local symbol names if any exists.

private void
writeUInt(long v)

private void
writeVarInt(int v)

Write a VarInt field.

private void
writeVarUInt(int v)

Write a VarUInt field.

Inherited from java.lang.Object:
cloneequalsfinalizegetClasshashCodenotifynotifyAlltoStringwaitwaitwait

Field Detail

MAX_LONG_VALUEback to summary
private static final BigInteger MAX_LONG_VALUE
myBufferback to summary
private byte[] myBuffer

Holds the entire binary encoded data. When IonDatagram is fully encoded into binary data, this byte array will hold that data.

myIonSystemback to summary
private IonSystem myIonSystem
myOffsetback to summary
private int myOffset

Index onto the position where the bytes are last written to the buffer. That means that if you want to write 1 more byte to the buffer, you have to decrease the index by 1 (myOffset - 1).

mySymbolTableback to summary
private SymbolTable mySymbolTable

The symbol table attached to the IonValue (and its nested values) that the encoder is currently traversing on.

negativeZeroBitArrayback to summary
private static final byte[] negativeZeroBitArray
NULL_LENGTH_MASKback to summary
private static final int NULL_LENGTH_MASK
positiveZeroBitArrayback to summary
private static final byte[] positiveZeroBitArray
TYPE_ANNOTATIONSback to summary
private static final int TYPE_ANNOTATIONS
TYPE_BLOBback to summary
private static final int TYPE_BLOB
TYPE_BOOLback to summary
private static final int TYPE_BOOL
TYPE_CLOBback to summary
private static final int TYPE_CLOB
TYPE_DECIMALback to summary
private static final int TYPE_DECIMAL
TYPE_FLOATback to summary
private static final int TYPE_FLOAT
TYPE_LISTback to summary
private static final int TYPE_LIST
TYPE_NEG_INTback to summary
private static final int TYPE_NEG_INT
TYPE_NULLback to summary
private static final int TYPE_NULL
TYPE_POS_INTback to summary
private static final int TYPE_POS_INT
TYPE_SEXPback to summary
private static final int TYPE_SEXP
TYPE_STRINGback to summary
private static final int TYPE_STRING
TYPE_STRUCTback to summary
private static final int TYPE_STRUCT
TYPE_SYMBOLback to summary
private static final int TYPE_SYMBOL
TYPE_TIMESTAMPback to summary
private static final int TYPE_TIMESTAMP

Constructor Detail

ReverseBinaryEncoderback to summary
pack-priv ReverseBinaryEncoder(int initialSize)

Method Detail

byteSizeback to summary
pack-priv int byteSize()

Returns the size of the Ion binary-encoded byte array.

This makes an unchecked assumption that {serialize(IonDatagram) is already called.

Returns:int

the number of bytes of the byte array

checkLocalSymbolTablePlacementback to summary
private void checkLocalSymbolTablePlacement(IonValue nextTopLevelValue)

Determine if the local symbol table attached to the previous top-level value (TLV), mySymbolTable, needs to be encoded before the next TLV is encoded. This is called before encoding each TLV by writeIonValue(IonValue).

Connotations of "Previous TLV" and "Next TLV" in this method are different from those defined outside of this method. This is done on purpose within this method to facilitate a clear understanding of what is going on within this method.

  • "Previous top-level value" refers to the top-level IonValue that has already been encoded into the buffer.
  • "Next top-level value" refers to the top-level IonValue that is about to be encoded to the buffer. Its contents are not traversed yet.
  • "Previous symbol table" refers to previous TLV's symbol table.
  • "Next symbol table" refers to next TLV's symbol table.
Local symbol tables and IVMs can be interspersed within an IonDatagram. This method checks for such cases by looking at the next symtab and previous symtab.

The following 4 cases define the scenarios where a LST/IVM is written to the buffer:

Next symtab is a local table:

  • Previous symtab is a local table - write LST if the two symtabs are different references
  • Previous symtab is a system table - write IVM always

Next symtab is a system table:

  • Previous symtab is a local table - propagate LST upwards
  • Previous symtab is a system table - write IVM if the two symtabs have different Ion versions.
TODO amazon-ion/ion-java/issues/25 Currently, IonDatagram#systemIterator() doesn't retain information about interspersed IVMs within the IonDatagram. As such, we cannot obtain the location of interspersed IVMs, if any.
Parameters
nextTopLevelValue:IonValue

the next top-level IonValue to be encoded

findSidback to summary
private int findSid(SymbolToken symToken)
growBufferback to summary
private int growBuffer(int offset)

Grows the current buffer and returns the updated offset.

Parameters
offset:int

the original offset

Returns:int

the updated offset

serializeback to summary
pack-priv void serialize(IonDatagram dg) throws IonException

Serialize the IonDatagram into Ion binary-encoding, to the internal byte array buffer of the encoder.

If the IonDatagram has been modified after this method call, you must call this method again to correctly reflect the modifications.

serializeback to summary
pack-priv void serialize(SymbolTable symTab) throws IonException
toNewByteArrayback to summary
pack-priv byte[] toNewByteArray()

Copies the current contents of the Ion binary-encoded byte array into a new byte array. The allocates an array of the size needed to exactly hold the output and copies the entire byte array to it.

This makes an unchecked assumption that {serialize(IonDatagram) is already called.

Returns:byte[]

the newly allocated byte array

toNewByteArrayback to summary
pack-priv int toNewByteArray(byte[] dst)

Copies the current contents of the Ion binary-encoded byte array into a a given byte array.

The given array must be large enough to contain all the bytes of the Ion binary-encoded byte array.

This makes an unchecked assumption that {serialize(IonDatagram) is already called.

TODO To be deprecated along with IonDatagram#getBytes(byte[])

Parameters
dst:byte[]

the byte array into which bytes are to be written

Returns:int

the number of bytes copied into dst

toNewByteArrayback to summary
pack-priv int toNewByteArray(byte[] dst, int offset)

Copies the current contents of the Ion binary-encoded byte array into a a given byte sub-array.

The given sub-array must be large enough to contain all the bytes of the Ion binary-encoded byte array.

This makes an unchecked assumption that {serialize(IonDatagram) is already called.

TODO To be deprecated along with IonDatagram#getBytes(byte[], int)

Parameters
dst:byte[]

the byte sub-array into which bytes are to be written

offset:int

the offset within the sub-array of the first byte to be written; must be non-negative and no larger than dst.length

Returns:int

the number of bytes copied into dst

writeAnnotationsback to summary
private void writeAnnotations(IonValue value, int endOfValueOffset)
writeByteback to summary
private void writeByte(int b)
writeBytesback to summary
pack-priv int writeBytes(OutputStream out) throws IOException

Copies the current contents of the Ion binary-encoded byte array to a specified stream.

This makes an unchecked assumption that {serialize(IonDatagram) is already called.

Returns:int

the number of bytes written into out

writeBytesback to summary
private void writeBytes(byte[] bytes)
writeImportback to summary
private void writeImport(SymbolTable symTab)

Write a single import declaration (which refers to a shared SymbolTable).

Parameters
symTab:SymbolTable

the shared symbol table, not local, not system

writeImportsFieldback to summary
private void writeImportsField(SymbolTable symTab)

Write import declarations (which refer to shared symbol tables) if any exists.

Parameters
symTab:SymbolTable

the local symbol table, not shared, not system

writeIonBlobContentback to summary
private void writeIonBlobContent(IonBlob val)
writeIonBoolContentback to summary
private void writeIonBoolContent(IonBool val)
writeIonClobContentback to summary
private void writeIonClobContent(IonClob val)
writeIonDatagramContentback to summary
private void writeIonDatagramContent(IonDatagram dg)
writeIonDecimalContentback to summary
private void writeIonDecimalContent(BigDecimal bd)
See Also
com.amazon.ion.impl.IonBinary.Writer#writeDecimalContent
writeIonDecimalContentback to summary
private void writeIonDecimalContent(IonDecimal val)
writeIonFloatContentback to summary
private void writeIonFloatContent(IonFloat val)
writeIonIntContentback to summary
private void writeIonIntContent(IonInt val)
See Also
IonBinary#writeUIntValue(BigInteger value, int len)
writeIonListContentback to summary
private void writeIonListContent(IonList val)
writeIonNullContentback to summary
private void writeIonNullContent()
writeIonSequenceContentback to summary
private void writeIonSequenceContent(IonSequence seq)
writeIonSexpContentback to summary
private void writeIonSexpContent(IonSexp val)
writeIonStringContentback to summary
private void writeIonStringContent(IonString val)
writeIonStringContentback to summary
private void writeIonStringContent(String str)
writeIonStructContentback to summary
private void writeIonStructContent(IonStruct val)
writeIonSymbolContentback to summary
private void writeIonSymbolContent(IonSymbol val)
writeIonTimestampContentback to summary
private void writeIonTimestampContent(IonTimestamp val)
writeIonValueback to summary
private void writeIonValue(IonValue value) throws IonException

Writes the IonValue and its nested values recursively, including annotations.

writeLobContentback to summary
private void writeLobContent(byte[] lob)
writeLocalSymbolTableback to summary
private void writeLocalSymbolTable(SymbolTable symTab)

Write contents of a local symbol table as a struct. The contents are the IST:: annotation, declared symbols, and import declarations (that refer to shared symtabs) if they exist.

Parameters
symTab:SymbolTable

the local symbol table, not shared, not system

writePrefixback to summary
private void writePrefix(int type, int length)

Writes the prefix (type and length) preceding the body of an encoded value. This method is only called after a value's body is written to the buffer.

Parameters
type:int

the value's type, a four-bit high-nibble mask

length:int

the number of bytes (octets) in the body, excluding the prefix itself

writeSymbolsFieldback to summary
private void writeSymbolsField(SymbolTable symTab)

Write declared local symbol names if any exists.

Parameters
symTab:SymbolTable

the local symbol table, not shared, not system

writeUIntback to summary
private void writeUInt(long v)
writeVarIntback to summary
private void writeVarInt(int v)

Write a VarInt field. VarInts are sequence of bytes. The high-order bit of the last octet is one, indicating the end of the sequence. All other high-order bits must be zero. The second-highest order bit (0x40) is a sign flag in the first octet of the representation, but part of the extension bits for all other octets.

Writes at least one byte, even for zero values. int parameter is enough as the scalar and container writers do not have APIs that return long or BigInteger representations.

writeVarUIntback to summary
private void writeVarUInt(int v)

Write a VarUInt field. VarUInts are sequence of bytes. The high-order bit of the last octet is one, indicating the end of the sequence. All other high-order bits must be zero.

Writes at least one byte, even for zero values. int parameter is enough as the scalar and container writers do not have APIs that return long or BigInteger representations.