it_lilo/lifter/
lift_array.rs

1/*
2 * Copyright 2021 Fluence Labs Limited
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *     http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17use 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}