pub struct Reader<'a> { /* private fields */ }Expand description
Reads one sample’s bytes.
Implementations§
Source§impl<'a> Reader<'a>
impl<'a> Reader<'a>
Sourcepub const fn new(bytes: &'a [u8], endianness: Endianness) -> Self
pub const fn new(bytes: &'a [u8], endianness: Endianness) -> Self
A reader over bytes in the given byte order.
Sourcepub const fn with_max_align(
bytes: &'a [u8],
endianness: Endianness,
max_align: usize,
) -> Self
pub const fn with_max_align( bytes: &'a [u8], endianness: Endianness, max_align: usize, ) -> Self
A reader whose alignment is capped at max_align. Four for
XCDR2, eight for XCDR1.
Sourcepub const fn with_wchar_width(self, width: WcharWidth) -> Self
pub const fn with_wchar_width(self, width: WcharWidth) -> Self
The same reader expecting a Char16 at another width.
Set from the same
zerodds_ast_layout::WstringLengthPolicy::character_width the
writer was set from, which is what keeps the two agreeing.
Sourcepub const fn wchar_width(&self) -> WcharWidth
pub const fn wchar_width(&self) -> WcharWidth
The Char16 width in force.
Sourcepub const fn with_wchar_framing(self, framing: WcharFraming) -> Self
pub const fn with_wchar_framing(self, framing: WcharFraming) -> Self
The same reader expecting another scalar Char16 framing.
Set from the same zerodds_ast_layout::WcharFraming the writer
and the layout plan were set from.
Sourcepub const fn wchar_framing(&self) -> WcharFraming
pub const fn wchar_framing(&self) -> WcharFraming
The Char16 framing in force.
Sourcepub const fn with_wstring_unit_order(self, order: WstringUnitOrder) -> Self
pub const fn with_wstring_unit_order(self, order: WstringUnitOrder) -> Self
The same reader expecting another wide code-unit order.
Sourcepub const fn wstring_unit_order(&self) -> WstringUnitOrder
pub const fn wstring_unit_order(&self) -> WstringUnitOrder
The wide code-unit order in force.
Sourcepub const fn with_pl_cdr1_framing(self, framing: PlCdr1Framing) -> Self
pub const fn with_pl_cdr1_framing(self, framing: PlCdr1Framing) -> Self
The same reader expecting another PL_CDR1 framing.
Sourcepub const fn pl_cdr1_framing(&self) -> PlCdr1Framing
pub const fn pl_cdr1_framing(&self) -> PlCdr1Framing
The framing in force.
Sourcepub const fn with_pl_cdr1_reading(self, reading: PlCdr1Reading) -> Self
pub const fn with_pl_cdr1_reading(self, reading: PlCdr1Reading) -> Self
The same reader taking, or reporting, a PL_CDR1 stream in another framing than the one it was given.
PlCdr1Reading::Strict is the default. Under
PlCdr1Reading::Tolerant the reader accepts any flags on
PID_EXTENDED and PID_LIST_END (XTypes 1.3 §7.4.1.2.1), the
short and the extended header of a parameter whichever form the
framing names (§7.4.1.2.2), and a declared length that is the
value’s own length or that length rounded up to four (§7.4.1.2).
Sourcepub const fn pl_cdr1_reading(&self) -> PlCdr1Reading
pub const fn pl_cdr1_reading(&self) -> PlCdr1Reading
The PL_CDR1 reading in force.
Sourcepub const fn endianness(&self) -> Endianness
pub const fn endianness(&self) -> Endianness
The byte order this reader was given.
A caller that has to decide something the stream’s order settles
and that this reader does not read for it — a CORBA wstring
without a byte-order mark takes the message’s order, CORBA 3.3
part 2 §9.3.1.6 — has to be able to ask.
Sourcepub fn skip_to(&mut self, target: usize) -> Result<(), WireError>
pub fn skip_to(&mut self, target: usize) -> Result<(), WireError>
Move to target, which is a position this reader has already
been told about.
The one way a header-driven decoder steps over a member it does
not declare: XTypes 1.3 §7.4.3.4.2 gives every MMEMBER an
extent, and §7.4.1.2 gives every PL_CDR1 parameter a length, so
where the next header starts is always known even when what sits
between is not.
§Errors
WireError::Truncated for a target past the end of the stream
and WireError::OutOfRange for one behind the current
position. Neither is silently clamped: a target behind the cursor
means the extent and the value disagree, and a reader that
stayed put would read the value’s bytes as the next header.
Sourcepub fn fit_string(
&self,
value: String,
bound: usize,
behaviour: TryConstruct,
) -> Result<Narrowed<String>, WireError>
pub fn fit_string( &self, value: String, bound: usize, behaviour: TryConstruct, ) -> Result<Narrowed<String>, WireError>
A string this reader has just taken off the wire, against the bound of the member it is going into.
A method rather than a free call so the offset in a
WireError::Discarded is this reader’s own. The narrowing
itself is crate::try_construct::fit_string, which is where
the clause quotations are.
§Errors
Sourcepub fn fit_wstring(
&self,
value: String,
bound: usize,
behaviour: TryConstruct,
) -> Result<Narrowed<String>, WireError>
pub fn fit_wstring( &self, value: String, bound: usize, behaviour: TryConstruct, ) -> Result<Narrowed<String>, WireError>
A wstring this reader has just taken off the wire, against the
bound of the member it is going into.
The bound counts UTF-16 code units and not octets, which is
why this is its own method and not Reader::fit_string with
another argument. The narrowing itself is
crate::try_construct::fit_wstring.
§Errors
Sourcepub fn fit_sequence<T>(
&self,
value: Vec<T>,
bound: usize,
behaviour: TryConstruct,
) -> Result<Narrowed<Vec<T>>, WireError>
pub fn fit_sequence<T>( &self, value: Vec<T>, bound: usize, behaviour: TryConstruct, ) -> Result<Narrowed<Vec<T>>, WireError>
A sequence this reader has just taken off the wire, against the bound of the member it is going into.
§Errors
Sourcepub fn fit_map<K: Ord, V>(
&self,
value: BTreeMap<K, V>,
bound: usize,
behaviour: TryConstruct,
) -> Result<Narrowed<BTreeMap<K, V>>, WireError>
pub fn fit_map<K: Ord, V>( &self, value: BTreeMap<K, V>, bound: usize, behaviour: TryConstruct, ) -> Result<Narrowed<BTreeMap<K, V>>, WireError>
A map this reader has just taken off the wire, against the bound of the member it is going into.
The bound counts entries, which is the unit Table 17’s
O2.length <= T1.length is in for a map<K, V, N>.
§Errors
Sourcepub fn fit_map_entries<K, V>(
&self,
value: Vec<MapEntry<K, V>>,
bound: usize,
behaviour: TryConstruct,
) -> Result<Narrowed<Vec<MapEntry<K, V>>>, WireError>
pub fn fit_map_entries<K, V>( &self, value: Vec<MapEntry<K, V>>, bound: usize, behaviour: TryConstruct, ) -> Result<Narrowed<Vec<MapEntry<K, V>>>, WireError>
A map held as its entries (XTypes 1.3 §7.5.1.3.6), against the bound of the member it is going into.
§Errors
Sourcepub fn align_to(&mut self, align: usize) -> Result<(), WireError>
pub fn align_to(&mut self, align: usize) -> Result<(), WireError>
Skip padding to align.
§Errors
WireError::Truncated when the padding the writer must have
written is not there. The offset reported is where the padding
began, which is where the stream stopped agreeing with itself —
letting the position run past the buffer instead put every later
error at an offset the stream does not have.
Sourcepub fn begin_packed_element(&mut self) -> usize
pub fn begin_packed_element(&mut self) -> usize
Begin a collection element whose alignment is counted from its own first octet, returning the origin it replaced.
The read-side pair of Writer::begin_packed_element, and it
has to move with it: a reader that aligned the departure from the
encapsulation would consume the padding its writer did not emit
and misread every element after the first.
Sourcepub fn finish_packed_element(&mut self, saved: usize)
pub fn finish_packed_element(&mut self, saved: usize)
Restore the stream origin a packed element displaced. The pair of
Self::begin_packed_element.
Sourcepub fn read_bool(&mut self) -> Result<bool, WireError>
pub fn read_bool(&mut self) -> Result<bool, WireError>
boolean.
§Errors
WireError::Truncated, or WireError::OutOfRange for a byte
that is neither 0 nor 1 — a boolean that is 2 is a stream that
disagrees with its own type.
Sourcepub fn read_wchar(&mut self, position: WcharPosition) -> Result<char, WireError>
pub fn read_wchar(&mut self, position: WcharPosition) -> Result<char, WireError>
wchar, at the width Reader::wchar_width names.
The four-byte form is RTI’s XCDR1 one, where the high sixteen bits are zero padding around a code unit. A value that uses them is refused rather than truncated: narrowing it here would return a character the peer did not send.
position selects the framing exactly as it does on the writing
side, and for the same reason: under
WcharFraming::GiopLengthPrefixedMemberOnly a member carries a
count octet and an element does not, so a reader given the wrong
position takes the first half of a code unit for a count and
refuses — or, at the one width where the count is a plausible
unit, returns a character nobody sent.
§Errors
WireError::Truncated, or WireError::OutOfRange for a code
point that is not a character, or for a four-byte character
holding more than one UTF-16 code unit.
Sourcepub fn read_wchar_member(&mut self) -> Result<char, WireError>
pub fn read_wchar_member(&mut self) -> Result<char, WireError>
Reader::read_wchar at the member position.
The reading counterpart of Writer::write_wchar_member, and
there for the same reason: a collection combinator takes a path
of one argument.
§Errors
Sourcepub fn read_wchar_element(&mut self) -> Result<char, WireError>
pub fn read_wchar_element(&mut self) -> Result<char, WireError>
Sourcepub fn read_bitmask(
&mut self,
bit_bound: u16,
declared: u64,
) -> Result<u64, WireError>
pub fn read_bitmask( &mut self, bit_bound: u16, declared: u64, ) -> Result<u64, WireError>
A bitmask, read from the holder its @bit_bound names, reduced to
the bits the type declares.
declared is the set of positions the bitmask names, one bit per
position, and it is an argument rather than a runtime table
because the type is the generated code’s and the wire is this
crate’s.
DDS-XTypes 1.3 §7.4.1.1.3.2: “the states of the remaining serialized bits are not specified, and those bits are not considered to be part of the bitmask”, and Table 18: “Preserve bit values by index for all bits identified in both T1 and T2.” A bit the stream sets and the type does not name is therefore not part of the value this type reads, and it is dropped; it is not a reason to refuse the sample, which would make a reader refuse a writer whose type Table 18 declares assignable.
§Errors
WireError::Truncated for a short stream, and
WireError::OutOfRange for a bound outside 1..=64.
Sourcepub fn read_bitset(&mut self, anchor_bytes: u32) -> Result<u64, WireError>
pub fn read_bitset(&mut self, anchor_bytes: u32) -> Result<u64, WireError>
A bitset’s anchor integer, of the width the plan sized it at.
The counterpart of Writer::write_bitset; the unpacking of the
fields out of the anchor is the generated code’s, because the
positions belong to the type and not to the wire.
§Errors
WireError::Truncated for a short stream, and
WireError::OutOfRange for an anchor that is not one, two,
four or eight octets.
Sourcepub fn read_u16_little(&mut self) -> Result<u16, WireError>
pub fn read_u16_little(&mut self) -> Result<u16, WireError>
A 16-bit value in little-endian order whatever the stream’s
order is. The counterpart of Writer::write_u16_little, and see
there for the one caller it has.
§Errors
Sourcepub fn read_u16_big(&mut self) -> Result<u16, WireError>
pub fn read_u16_big(&mut self) -> Result<u16, WireError>
A 16-bit value in big-endian order whatever the stream’s
order is. The counterpart of Writer::write_u16_big.
§Errors
Sourcepub fn read_u32_little(&mut self) -> Result<u32, WireError>
pub fn read_u32_little(&mut self) -> Result<u32, WireError>
A 32-bit value in little-endian order whatever the stream’s
order is. The counterpart of Writer::write_u32_little.
§Errors
Sourcepub fn read_u32_big(&mut self) -> Result<u32, WireError>
pub fn read_u32_big(&mut self) -> Result<u32, WireError>
A 32-bit value in big-endian order whatever the stream’s
order is. The counterpart of Writer::write_u32_big.
§Errors
Sourcepub fn read_f128(&mut self) -> Result<Float128, WireError>
pub fn read_f128(&mut self) -> Result<Float128, WireError>
long double: all sixteen bytes, as IEEE 754 binary128.
The counterpart of Writer::write_f128. This used to read the
first eight bytes as a double and skip the rest, which decoded
every value a double cannot hold as a different number and said
nothing.
The bytes are taken whole and reversed as a whole for a
big-endian stream, per CORBA 3.3 part 2 Figure 9.2. Alignment is
eight, capped to four under XCDR2 by
Reader::align_to’s MAXALIGN.
§Errors
Sourcepub fn read_fixed(
&mut self,
digits: u8,
scale: u8,
policy: FixedDigits,
) -> Result<String, WireError>
pub fn read_fixed( &mut self, digits: u8, scale: u8, policy: FixedDigits, ) -> Result<String, WireError>
fixed<P, S>: packed BCD, CORBA 3.3 part 2 §9.3.2.8, as a decimal
string.
A string and not a number, for the reason the twenty other language
columns of this project carry it as text too: fixed<31, 2> fits no
integer Rust has, and a binary float would be the wrong answer rather
than an approximate one, because fixed exists to be exact.
The text that comes back is the one spelling the declaration admits —
no leading zeros past a single one before the point, exactly S
after it, and a - only on a value that is neither zero nor
positive. 1.5 and 0001.500 are the same sample under
fixed<7, 3> and only one string can come out of it.
§Errors
WireError::Truncated for a stream that ends inside the field.
WireError::OutOfRange for a declaration outside IDL 4.2 rule
(42), a nibble that is neither a digit nor a sign, or — under
FixedDigits::ValuePrecision or FixedDigits::ValueStringDigits —
a field that presents no sign nibble within the widest fixed IDL
admits.
Sourcepub fn read_string(&mut self) -> Result<String, WireError>
pub fn read_string(&mut self) -> Result<String, WireError>
A string: a length including the terminator, the bytes, the NUL.
§Errors
WireError::ImpossibleLength for a length the stream cannot
hold — allocating for it is how a reader turns a bad message into
an out-of-memory. WireError::NotUtf8 for bytes that are not.
Sourcepub fn read_wstring(
&mut self,
policy: WstringLengthPolicy,
order: WstringUnitOrder,
position: WirePosition,
) -> Result<String, WireError>
pub fn read_wstring( &mut self, policy: WstringLengthPolicy, order: WstringUnitOrder, position: WirePosition, ) -> Result<String, WireError>
A wstring, in the cell policy and order name.
The default is XTypes 1.3 §7.4.1.1.2 — an octet count, “twice
the number of characters in the string”, no terminator and no
byte-order mark to strip. Eight of the nine measured
implementations write something else in at least one axis, and
WstringLengthPolicy carries the octets and the argument.
§Nothing here looks at the length to decide which cell it is
The length is the field a hostile peer controls, and the cells
are not separable anyway: Fast DDS’s @final struct { wstring w; long n; } with w = "ab", n = 7 is 02000000 61006200 07000000, and the specification’s encoding of the same type with
w = "a", n = 7 is 02000000 6100, two octets of padding,
07000000. Twelve octets each, differing only in the content of
padding that no clause fixes. A reader choosing between those two
samples would not be resolving an ambiguity, it would be taking
its answer from the length field.
So the configured cell is read, and a length that cell cannot have produced is refused with the cell it does fit named in the error — a diagnosis after the refusal, not a parse decided by the stream.
§Errors
WireError::WrongFraming for a length the configured cell
cannot have produced: an octet count the unit width does not
divide, or a count of zero where C2 says the count includes a
terminator. Rounding an odd octet count down would leave the
remainder in the stream and put every later member at the wrong
offset.
WireError::ImpossibleLength for a length past the end of the
stream — allocating for it is how a reader turns a bad message
into an out-of-memory.
WireError::OutOfRange for a four-octet character above
0xFFFF (the wide form zero-extends a code unit, so a value
that does not fit one is not a form this reader knows how to
narrow), for a terminator that is not a NUL where one is
expected, for a NUL inside the text where a terminator is
expected — every C peer stops at it, so this reader’s value and
the peer’s would differ for octets both accepted — and for units
that are not well-formed UTF-16. An unpaired surrogate is
refused rather than replaced: U+FFFD in its place would be a
character the sender never had.
That last refusal catches less than it looks. Fast CDR’s
truncation of U+1D11E is U+D11E, a Hangul syllable and
well-formed UTF-16, so the wrong character arrives with nothing
to object to. Only a code point whose low sixteen bits land in
D800..=DFFF fails here — which is why
Writer::write_wstring refuses to produce the truncation in
the first place.
Sourcepub fn read_wstring_utf8(
&mut self,
policy: WstringLengthPolicy,
position: WirePosition,
) -> Result<String, WireError>
pub fn read_wstring_utf8( &mut self, policy: WstringLengthPolicy, position: WirePosition, ) -> Result<String, WireError>
A wstring whose characters arrive as their own UTF-8 octets.
The read side of Writer::write_wstring_utf8 and of
WstringCodeUnits::Utf8: the declared length is the UTF-8 octet
count, and the terminator, when the cell carries one, is the last
of those octets. A count the stream cannot hold is refused before
a byte is read, for the reason Reader::read_wstring gives.
§Errors
WireError::ImpossibleLength for a length larger than the
stream can hold, WireError::OutOfRange for a terminator cell
whose last octet is not a NUL or whose run carries one earlier,
and WireError::NotUtf8 for octets that are not well-formed
UTF-8.
Sourcepub fn read_dheader(&mut self) -> Result<usize, WireError>
pub fn read_dheader(&mut self) -> Result<usize, WireError>
A DHEADER: the length the members that follow occupy.
§Errors
WireError::ImpossibleLength when it claims more than is left.
Sourcepub fn read_emheader(&mut self) -> Result<EmHeaderRead, WireError>
pub fn read_emheader(&mut self) -> Result<EmHeaderRead, WireError>
An EMHEADER, unpacked into its parts, its NEXTINT and the extent of the member it introduces.
§The NEXTINT of length codes 5 to 7 is not consumed
XTypes 1.3 §7.4.3.4.2 gives the NEXTINT of codes 5, 6 and 7 two jobs: it “shall be reused also as part of the serialized member … because the serialization of certain members also starts with an integer length, which would take exactly the same value as NEXTINT. Therefore the use of length codes 5 to 7 saves 4 bytes in the serialization.”
Writer::write_emheader reserves a placeholder for code 4 only,
for that reason. This read it for every code from 4 up and left
the position four bytes into the member — so the sequence that
followed lost its own length word and every byte after it was
read at the wrong offset. It is peeked now, and the member is
read from where it starts.
§The extent
extent is how many bytes the member occupies counted from the
position this call leaves the reader at, which is the number a
caller needs whichever code it turned out to be:
| code | extent |
|---|---|
| 0, 1, 2, 3 | 1, 2, 4, 8 |
| 4 | the NEXTINT, which this call consumed |
| 5 | 4 + NEXTINT |
| 6 | 4 + 4 × NEXTINT |
| 7 | 4 + 8 × NEXTINT |
§Errors
WireError::Truncated, or WireError::ImpossibleLength for
a NEXTINT claiming more than the stream holds. Allocating on an
unchecked NEXTINT is how a reader turns a malformed message into
an out-of-memory; this returned Ok for ffffffff.
Sourcepub fn read_pid(&mut self) -> Result<PidRead, WireError>
pub fn read_pid(&mut self) -> Result<PidRead, WireError>
A PL_CDR1 parameter header, in whichever form it was written.
§The flag bits are not part of the id
XTypes 1.3 §7.4.1.2 splits the sixteen-bit field: the member id
is the low fourteen bits, bit 14 is must-understand and bit 15 is
implementation-specific. Cyclone DDS sets must-understand on
every parameter it writes, so its PID_EXTENDED goes out as
0x7f01 and its sentinel as 0x7f02 —
crates/ast-layout/tests/fixtures/vendor_bytes.md §2 records
both, and RTI Connext writes the same sentinel.
Comparing the whole word against 0x3f01 and 0x3f02 therefore
recognised neither. A Cyclone parameter list read that way takes
the extended header’s id and length for eight bytes of value, and
runs on past the sentinel into whatever follows it, with no error
anywhere. Two of the three implementations this project is
measured against write those bytes.
§Errors
WireError::Truncated; WireError::ImpossibleLength for a
declared length longer than the stream holds;
WireError::OutOfRange for an extended header whose short
length is not the 8 §7.4.1.2 fixes it at.
Sourcepub fn read_pid_as(&mut self, role: ParameterRole) -> Result<PidRead, WireError>
pub fn read_pid_as(&mut self, role: ParameterRole) -> Result<PidRead, WireError>
A PL_CDR1 parameter header in a named role.
The bytes are the same bytes; the role decides which length
convention Reader::finish_pid checks the declared length
against, because one implementation pads a @mutable member’s
and not an @optional member’s. See ParameterRole.
§Errors
As Reader::read_pid.
Sourcepub fn finish_pid(&mut self, header: PidRead) -> Result<(), WireError>
pub fn finish_pid(&mut self, header: PidRead) -> Result<(), WireError>
End a parameter’s value and step to the next header.
The padding to four follows the value and is outside the declared length, so the next parameter is found by alignment and not by adding the length — which is what lets one reader take RTI’s rounded-up length and Fast DDS’s exact one.
The padding is consumed here only under a framing that writes it
(PlCdr1Framing::pad_after_value), mirroring
Writer::finish_pid: under Fast DDS’s and OpenDDS’s framing a
parameter writes no padding of its own — the next header aligns
itself in read_pid_as — and a final @optional parameter of
a non-mutable type ends the stream where its value does, so an
unconditional alignment here read two bytes past the end of a
stream the writer had closed correctly (measured:
zerodds-rust/opendds-xcdr1-*/annotation-must-understand-unannotated).
§Errors
WireError::Truncated where the framing’s padding is not
there.
Sourcepub fn skip_parameter(&mut self, header: PidRead) -> Result<(), WireError>
pub fn skip_parameter(&mut self, header: PidRead) -> Result<(), WireError>
End a parameter whose member this reader does not declare.
Reader::finish_pid finds the next header by alignment from
wherever the value’s read left the cursor, which is the right
answer when the value was read; it also checks the declared
length against how far the cursor moved, which for a member
nobody read has moved nowhere. This one steps over the declared
length instead. §7.4.1.2 gives every parameter one, which is what
makes an unknown member skippable at all.
§Errors
WireError::Truncated where the declared length runs past the
stream, and whatever the alignment to the next header returns.
Sourcepub fn read_sequence<T, F: Fn(&mut Self) -> Result<T, WireError>>(
&mut self,
element: F,
) -> Result<Vec<T>, WireError>
pub fn read_sequence<T, F: Fn(&mut Self) -> Result<T, WireError>>( &mut self, element: F, ) -> Result<Vec<T>, WireError>
A sequence: a count, then each element.
§Errors
WireError::ImpossibleLength for a count larger than the
stream can hold — a count is one element or more, so a stream
with fewer bytes than elements cannot be honest about it.
Sourcepub fn read_array<T, F: Fn(&mut Self) -> Result<T, WireError>>(
&mut self,
element: F,
count: usize,
) -> Result<Vec<T>, WireError>
pub fn read_array<T, F: Fn(&mut Self) -> Result<T, WireError>>( &mut self, element: F, count: usize, ) -> Result<Vec<T>, WireError>
Sourcepub fn read_delimited_sequence<T, F: Fn(&mut Self) -> Result<T, WireError>>(
&mut self,
element: F,
) -> Result<Vec<T>, WireError>
pub fn read_delimited_sequence<T, F: Fn(&mut Self) -> Result<T, WireError>>( &mut self, element: F, ) -> Result<Vec<T>, WireError>
A sequence behind a delimiter. XTypes 1.3 §7.4.3.5 rule (12).
The delimiter is read and discarded: it exists so a reader can skip a collection it cannot decode, and this reader decodes it.
§Errors
As Reader::read_sequence, plus a short buffer at the
delimiter.
Sourcepub fn read_delimited_array<T, F: Fn(&mut Self) -> Result<T, WireError>>(
&mut self,
element: F,
count: usize,
) -> Result<Vec<T>, WireError>
pub fn read_delimited_array<T, F: Fn(&mut Self) -> Result<T, WireError>>( &mut self, element: F, count: usize, ) -> Result<Vec<T>, WireError>
An array behind a delimiter. Rule (9), the array counterpart.
§Errors
As Reader::read_array, plus a short buffer at the delimiter.
Sourcepub fn read_map<K, V, FK, FV>(
&mut self,
key: FK,
value: FV,
) -> Result<BTreeMap<K, V>, WireError>
pub fn read_map<K, V, FK, FV>( &mut self, key: FK, value: FV, ) -> Result<BTreeMap<K, V>, WireError>
A map: an entry count, then each entry’s key followed by its value.
The count is entries and not halves — see
crate::Writer::write_map
for the clause and the recorded foreign measurement it is read
against.
§A repeated key is refused
BTreeMap::insert would answer a second entry under a key it
already holds by returning the first and keeping the second: the
sample would decode, report success, and hold fewer entries than
the count on the wire said. That is the silent half of a bad
decode, so it is an error here. A map is not supposed to carry
one, which is exactly why a stream that does is a statement about
the stream.
§Errors
WireError::ImpossibleLength for a count larger than the
stream can hold, WireError::OutOfRange for a repeated key,
and whatever either half’s function returns.
Sourcepub fn read_map_entries<K, V, FK, FV>(
&mut self,
key: FK,
value: FV,
) -> Result<Vec<MapEntry<K, V>>, WireError>
pub fn read_map_entries<K, V, FK, FV>( &mut self, key: FK, value: FV, ) -> Result<Vec<MapEntry<K, V>>, WireError>
A map as the sequence of its entries (XTypes 1.3 §7.5.1.3.6, §7.4.1.1.4): the entries
in the order the stream carries them. Unlike Reader::read_map this does not refuse
a key that repeats: the wire carries a sequence, and what a repeated key means is the
application’s.
§Errors
WireError::ImpossibleLength for a count the stream cannot hold, and whatever either
half’s function returns.
Sourcepub fn read_delimited_map_entries<K, V, FK, FV>(
&mut self,
key: FK,
value: FV,
) -> Result<Vec<MapEntry<K, V>>, WireError>
pub fn read_delimited_map_entries<K, V, FK, FV>( &mut self, key: FK, value: FV, ) -> Result<Vec<MapEntry<K, V>>, WireError>
The entries of a map behind a delimiter. Rule (15).
§Errors
As Reader::read_map_entries, plus a short buffer at the delimiter.
Sourcepub fn read_delimited_map<K, V, FK, FV>(
&mut self,
key: FK,
value: FV,
) -> Result<BTreeMap<K, V>, WireError>
pub fn read_delimited_map<K, V, FK, FV>( &mut self, key: FK, value: FV, ) -> Result<BTreeMap<K, V>, WireError>
A map behind a delimiter. XTypes 1.3 §7.4.3.5 rule (15).
The delimiter is read and discarded, as
Reader::read_delimited_sequence does.
§Errors
As Reader::read_map, plus a short buffer at the delimiter.
Sourcepub fn read_array_n<T, const N: usize, F: Fn(&mut Self) -> Result<T, WireError>>(
&mut self,
element: F,
) -> Result<[T; N], WireError>
pub fn read_array_n<T, const N: usize, F: Fn(&mut Self) -> Result<T, WireError>>( &mut self, element: F, ) -> Result<[T; N], WireError>
An array of a length the type fixes, as [T; N].
The count is in the type — XTypes 1.3 §7.4.3.5 — so a generated
field for long grid[2][3] is [[i32; 3]; 2] and not a Vec.
Reader::read_array hands back a Vec, which is the right
answer for a caller that wants one and does not fit that field:
a Vec of the wrong length assigns to nothing, and one of the
right length still has to be converted. N is inferred from the
destination, so the generated call carries no turbofish.
§Errors
As Reader::read_array, plus WireError::OutOfRange if the
elements read do not number N — which cannot happen given the
loop below, and is returned rather than unwrapped because a
panic in a decoder is a denial of service a peer can send.
Sourcepub fn read_delimited_array_n<T, const N: usize, F: Fn(&mut Self) -> Result<T, WireError>>(
&mut self,
element: F,
) -> Result<[T; N], WireError>
pub fn read_delimited_array_n<T, const N: usize, F: Fn(&mut Self) -> Result<T, WireError>>( &mut self, element: F, ) -> Result<[T; N], WireError>
A fixed-length array behind a delimiter. Rule (9).
§Errors
As Reader::read_array_n, plus a short buffer at the
delimiter.
Sourcepub fn read_bytes(&mut self, count: usize) -> Result<&'a [u8], WireError>
pub fn read_bytes(&mut self, count: usize) -> Result<&'a [u8], WireError>
count bytes as they lie, with no alignment and no
interpretation.
The opaque payloads have no other reader: a GIOP request body is a byte string whose type the receiving skeleton knows and this reader does not, a CDR encapsulation carries its own byte-order octet and has to be read by a second reader, and an octet sequence is its length followed by exactly this.
§Errors
WireError::Truncated when fewer than count bytes remain.
The offset reported is where the read began.