MCPcopy Create free account
hub / github.com/argumentcomputer/ix / get_expr

Function get_expr

crates/ixon/src/serialize.rs:257–425  ·  view source on GitHub ↗

Deserialize an expression from bytes (iterative to avoid stack overflow).

(buf: &mut &[u8])

Source from the content-addressed store, hash-verified

255/// every delta must be ≥ 1, so the section is strictly ascending and
256/// duplicate-free by construction. `addr_at(i)` resolves an index to
257/// the i-th §2 address; the caller has just scanned §2, so the order
258/// is at hand in every reader.
259fn read_hints_section(
260 buf: &mut &[u8],
261 consts_len: usize,
262 addr_at: impl Fn(usize) -> Address,
263 reader: &str,
264) -> Result<Vec<(Address, ReducibilityHints)>, String> {
265 let n = get_u64(buf)? as usize;
266 if n > consts_len {
267 return Err(format!(
268 "{reader}: hint count {n} exceeds const count \
269 {consts_len}{PRE_COMPACT_KEYS}"
270 ));
271 }
272 // Each hint entry needs at least two bytes (Tag0 delta + Tag0 hint).
273 if n > buf.len() / 2 {
274 return Err(format!("{reader}: hint count {n} exceeds remaining buffer"));
275 }
276 let mut hints = Vec::with_capacity(n);
277 // Index of the next entry must be ≥ cursor (= previous index + 1).
278 let mut cursor: u64 = 0;
279 for k in 0..n {
280 let delta = get_u64(buf)?;
281 if delta == 0 {
282 return Err(format!(
283 "{reader}: hint entry {k} has zero index delta (§3 must be \
284 strictly ascending){PRE_COMPACT_KEYS}"
285 ));
286 }
287 let idx = cursor.checked_add(delta - 1).ok_or_else(|| {
288 format!(
289 "{reader}: hint entry {k} index delta overflows{PRE_COMPACT_KEYS}"
290 )
291 })?;
292 if idx >= consts_len as u64 {
293 return Err(format!(
294 "{reader}: hint entry {k} resolves to constant index {idx}, \
295 out of range ({consts_len} consts){PRE_COMPACT_KEYS}"
296 ));
297 }
298 let hint = unfuse_hint(get_u64(buf)?)
299 .map_err(|e| format!("{reader}: hint entry {k}: {e}"))?;
300 hints.push((addr_at(idx as usize), hint));
301 cursor = idx + 1;
302 }
303 Ok(hints)
304}
305
306fn get_address(buf: &mut &[u8]) -> Result<Address, String> {
307 if buf.len() < 32 {
308 return Err(format!("get_address: need 32 bytes, have {}", buf.len()));
309 }
310 let (bytes, rest) = buf.split_at(32);
311 *buf = rest;
312 Address::from_slice(bytes).map_err(|_| "get_address: invalid".to_string())
313}
314

Callers 5

get_indexedMethod · 0.85
get_sharingFunction · 0.85
getMethod · 0.85
expr_roundtripFunction · 0.85

Calls 9

sortFunction · 0.85
capped_capacityFunction · 0.85
let_Function · 0.85
pushMethod · 0.80
get_u64Function · 0.70
varFunction · 0.50
natFunction · 0.50
appFunction · 0.50
lamFunction · 0.50

Tested by 1