1use super::record_lift_memory;
18use super::ILifter;
19use super::LiResult;
20use crate::traits::RecordResolvable;
21use crate::utils::ser_type_size;
22use crate::IType;
23use crate::IValue;
24
25use it_memory_traits::MemoryView;
26
27pub fn array_lift_memory<
28 R: RecordResolvable,
29 MV: MemoryView<Store>,
30 Store: it_memory_traits::Store,
31>(
32 store: &mut <Store as it_memory_traits::Store>::ActualStore<'_>,
33 lifter: &ILifter<'_, R, MV, Store>,
34 value_type: &IType,
35 offset: u32,
36 elements_count: u32,
37) -> LiResult<IValue> {
38 if elements_count == 0 {
39 return Ok(IValue::Array(vec![]));
40 }
41
42 let reader = &lifter.reader;
43
44 let ivalues = match value_type {
45 IType::Boolean => reader.read_bool_array(store, offset, elements_count)?,
46 IType::S8 => reader.read_s8_array(store, offset, elements_count)?,
47 IType::S16 => reader.read_s16_array(store, offset, elements_count)?,
48 IType::S32 => reader.read_s32_array(store, offset, elements_count)?,
49 IType::S64 => reader.read_s64_array(store, offset, elements_count)?,
50 IType::I32 => reader.read_i32_array(store, offset, elements_count)?,
51 IType::I64 => reader.read_i64_array(store, offset, elements_count)?,
52 IType::U8 => reader.read_u8_array(store, offset, elements_count)?,
53 IType::U16 => reader.read_u16_array(store, offset, elements_count)?,
54 IType::U32 => reader.read_u32_array(store, offset, elements_count)?,
55 IType::U64 => reader.read_u64_array(store, offset, elements_count)?,
56 IType::F32 => reader.read_f32_array(store, offset, elements_count)?,
57 IType::F64 => reader.read_f64_array(store, offset, elements_count)?,
58 IType::String => read_string_array(store, lifter, offset, elements_count)?,
59 IType::ByteArray => read_array_array(store, lifter, &IType::U8, offset, elements_count)?,
60 IType::Array(ty) => read_array_array(store, lifter, &ty, offset, elements_count)?,
61 IType::Record(record_type_id) => {
62 read_record_array(store, lifter, *record_type_id, offset, elements_count)?
63 }
64 };
65
66 Ok(IValue::Array(ivalues))
67}
68
69fn read_string_array<R: RecordResolvable, MV: MemoryView<Store>, Store: it_memory_traits::Store>(
70 store: &mut <Store as it_memory_traits::Store>::ActualStore<'_>,
71 lifter: &ILifter<'_, R, MV, Store>,
72 offset: u32,
73 elements_count: u32,
74) -> LiResult<Vec<IValue>> {
75 let mut result = Vec::with_capacity(elements_count as usize);
76 let seq_reader = lifter.reader.sequential_reader(
77 store,
78 offset,
79 ser_type_size(&IType::String) * elements_count,
80 )?;
81
82 for _ in 0..elements_count {
83 let offset = seq_reader.read_u32(store);
84 let size = seq_reader.read_u32(store);
85
86 let raw_str = lifter.reader.read_raw_u8_array(store, offset, size)?;
87 let str = String::from_utf8(raw_str)?;
88 result.push(IValue::String(str));
89 }
90
91 Ok(result)
92}
93
94fn read_array_array<R: RecordResolvable, MV: MemoryView<Store>, Store: it_memory_traits::Store>(
95 store: &mut <Store as it_memory_traits::Store>::ActualStore<'_>,
96 lifter: &ILifter<'_, R, MV, Store>,
97 ty: &IType,
98 offset: u32,
99 elements_count: u32,
100) -> LiResult<Vec<IValue>> {
101 let mut result = Vec::with_capacity(elements_count as usize);
102 let seq_reader =
103 lifter
104 .reader
105 .sequential_reader(store, offset, ser_type_size(ty) * elements_count)?;
106
107 for _ in 0..elements_count {
108 let offset = seq_reader.read_u32(store);
109 let size = seq_reader.read_u32(store);
110
111 let array = array_lift_memory(store, lifter, ty, offset, size)?;
112 result.push(array);
113 }
114
115 Ok(result)
116}
117
118fn read_record_array<R: RecordResolvable, MV: MemoryView<Store>, Store: it_memory_traits::Store>(
119 store: &mut <Store as it_memory_traits::Store>::ActualStore<'_>,
120 lifter: &ILifter<'_, R, MV, Store>,
121 record_type_id: u64,
122 offset: u32,
123 elements_count: u32,
124) -> LiResult<Vec<IValue>> {
125 let mut result = Vec::with_capacity(elements_count as usize);
126 let seq_reader = lifter.reader.sequential_reader(
127 store,
128 offset,
129 ser_type_size(&IType::Record(0)) * elements_count,
130 )?;
131
132 for _ in 0..elements_count {
133 let offset = seq_reader.read_u32(store);
134 let record_ty = lifter.resolver.resolve_record(record_type_id)?;
135
136 let record = record_lift_memory(store, lifter, &record_ty, offset)?;
137 result.push(record);
138 }
139
140 Ok(result)
141}