Skip to content

Commit

Permalink
Add 1.1 binary reader support for typed nulls
Browse files Browse the repository at this point in the history
  • Loading branch information
nirosys committed May 13, 2024
1 parent ba7718d commit 35d0894
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 3 deletions.
26 changes: 26 additions & 0 deletions src/lazy/binary/raw/v1_1/reader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -457,4 +457,30 @@ mod tests {

Ok(())
}

#[test]
fn nulls() -> IonResult<()> {
#[rustfmt::skip]
let data: Vec<([u8; 2], IonType)> = vec![
([0xEB, 0x00], IonType::Bool), // null.bool
([0xEB, 0x01], IonType::Int), // null.int
([0xEB, 0x02], IonType::Float), // null.float
([0xEB, 0x03], IonType::Decimal), // null.decimal
([0xEB, 0x04], IonType::Timestamp), // null.timestamp
([0xEB, 0x05], IonType::String), // null.string
([0xEB, 0x06], IonType::Symbol), // null.symbol
([0xEB, 0x07], IonType::Blob), // null.blob
([0xEB, 0x08], IonType::Clob), // null.clob
([0xEB, 0x09], IonType::List), // null.list
([0xEB, 0x0A], IonType::SExp), // null.sexp
([0xEB, 0x0B], IonType::Struct), // null.struct
];

for (data, expected_type) in data {
let mut reader = LazyRawBinaryReader_1_1::new(&data);
let actual_type = reader.next()?.expect_value()?.read()?.expect_null()?;
assert_eq!(actual_type, expected_type);
}
Ok(())
}
}
16 changes: 16 additions & 0 deletions src/lazy/binary/raw/v1_1/type_descriptor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,20 @@ pub struct Opcode {
/// A statically defined array of TypeDescriptor that allows a binary reader to map a given
/// byte (`u8`) to a `TypeDescriptor` without having to perform any masking or bitshift operations.
pub(crate) static ION_1_1_OPCODES: &[Opcode; 256] = &init_opcode_cache();
pub(crate) static ION_1_1_TYPED_NULL_TYPES: &[IonType; 12] = &[
IonType::Bool,
IonType::Int,
IonType::Float,
IonType::Decimal,
IonType::Timestamp,
IonType::String,
IonType::Symbol,
IonType::Blob,
IonType::Clob,
IonType::List,
IonType::SExp,
IonType::Struct,
];

const DEFAULT_HEADER: Opcode = Opcode {
opcode_type: OpcodeType::Nop,
Expand Down Expand Up @@ -48,6 +62,7 @@ impl Opcode {
(0xE, 0x0) => (IonVersionMarker, low_nibble, None),
(0xE, 0x1..=0x3) => (SymbolAddress, low_nibble, Some(IonType::Symbol)),
(0xE, 0xA) => (NullNull, low_nibble, Some(IonType::Null)),
(0xE, 0xB) => (TypedNull, low_nibble, Some(IonType::Null)),
(0xE, 0xC..=0xD) => (Nop, low_nibble, None),
(0xF, 0x5) => (LargeInteger, low_nibble, Some(IonType::Int)),
(0xF, 0x8) => (String, 0xFF, Some(IonType::String)), // 0xFF indicates >15 byte string.
Expand Down Expand Up @@ -123,6 +138,7 @@ impl Header {
(OpcodeType::String, 0..=15) => InOpcode(self.length_code),
(OpcodeType::InlineSymbol, n) if n < 16 => InOpcode(n),
(OpcodeType::SymbolAddress, n) if n < 4 => InOpcode(n),
(OpcodeType::TypedNull, _) => InOpcode(1),
_ => FlexUIntFollows,
}
}
Expand Down
12 changes: 9 additions & 3 deletions src/lazy/binary/raw/v1_1/value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ use crate::{
raw::{
v1_1::{
annotations_iterator::RawBinaryAnnotationsIterator_1_1,
immutable_buffer::ImmutableBuffer, Header, OpcodeType,
immutable_buffer::ImmutableBuffer, type_descriptor::ION_1_1_TYPED_NULL_TYPES,
Header, OpcodeType,
},
value::ValueParseResult,
},
Expand Down Expand Up @@ -150,8 +151,13 @@ impl<'top> LazyRawBinaryValue_1_1<'top> {
/// or [`LazyStruct`](crate::lazy::struct::LazyStruct) that can be traversed to access the container's contents.
pub fn read(&self) -> ValueParseResult<'top, BinaryEncoding_1_1> {
if self.is_null() {
let raw_value_ref = RawValueRef::Null(self.ion_type());
return Ok(raw_value_ref);
let ion_type = if self.encoded_value.header.ion_type_code == OpcodeType::TypedNull {
let body = self.value_body()?;
ION_1_1_TYPED_NULL_TYPES[body[0] as usize]
} else {
self.ion_type()
};
return Ok(RawValueRef::Null(ion_type));
}

match self.ion_type() {
Expand Down

0 comments on commit 35d0894

Please sign in to comment.