MCPcopy Create free account
hub / github.com/apache/avro-rs / decode_internal

Function decode_internal

avro/src/decode.rs:77–352  ·  view source on GitHub ↗
(
    schema: &Schema,
    names: &HashMap<Name, S>,
    enclosing_namespace: NamespaceRef,
    reader: &mut R,
)

Source from the content-addressed store, hash-verified

75/// shared budget of [`max_allocation_bytes`] bytes, instead of each
76/// collection only being checked in isolation.
77#[derive(Debug)]
78pub(crate) struct DecodeContext {
79 /// Bytes still available for allocations while decoding the current datum.
80 remaining_budget: usize,
81 /// Current recursion depth of `decode_internal`.
82 depth: usize,
83}
84
85impl DecodeContext {
86 /// Create a new context.
87 ///
88 /// This should only be done when a new datum is being decoded, never during the decoding.
89 pub(crate) fn new() -> Self {
90 Self {
91 remaining_budget: max_allocation_bytes(DEFAULT_MAX_ALLOCATION_BYTES),
92 depth: 0,
93 }
94 }
95
96 /// Debit `bytes` from the per-datum allocation budget
97 ///
98 /// # Errors
99 /// `Details::MemoryAllocation` if the maximum budget is exceeded.
100 fn debit_bytes(&mut self, bytes: usize) -> AvroResult<()> {
101 match self.remaining_budget.checked_sub(bytes) {
102 Some(remaining) => {
103 self.remaining_budget = remaining;
104 Ok(())
105 }
106 None => Err(Details::MemoryAllocation {
107 desired: Some(bytes),
108 maximum: max_allocation_bytes(DEFAULT_MAX_ALLOCATION_BYTES),
109 }
110 .into()),
111 }
112 }
113
114 /// Debit the amount of bytes for `n` items of `T`.
115 ///
116 /// # Errors
117 /// `Details::MemoryAllocation` if the maximum budget is exceeded.
118 fn debit_items<T>(&mut self, n: usize) -> AvroResult<()> {
119 let bytes = n
120 .checked_mul(size_of::<T>())
121 .ok_or(Details::IntegerOverflow)?;
122 self.debit_bytes(bytes)
123 }
124
125 /// Track one level of decoding recursion, erroring once the configured
126 /// maximum depth is exceeded.
127 fn enter(&mut self) -> AvroResult<()> {
128 self.depth += 1;
129 let maximum = decode_recursion_limit();
130 if self.depth > maximum {
131 Err(Details::DecodeRecursionLimit { maximum }.into())
132 } else {
133 Ok(())
134 }

Callers 4

decodeFunction · 0.85
read_valueMethod · 0.85
read_valueMethod · 0.85
read_nextMethod · 0.85

Calls 15

DecimalClass · 0.85
deserialize_big_decimalFunction · 0.85
decode_intFunction · 0.85
zag_i32Function · 0.85
decode_longFunction · 0.85
zag_i64Function · 0.85
decode_lenFunction · 0.85
BytesClass · 0.85
decode_seq_lenFunction · 0.85
RecordClass · 0.85
EnumEnum · 0.85
copy_only_sizeMethod · 0.80

Tested by

no test coverage detected