1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
use super::ILifter;
use super::LiError;
use super::LiResult;
use super::MemoryReader;
use super::SequentialReader;
use crate::traits::RecordResolvable;
use crate::utils::record_size;
use crate::IRecordType;
use crate::IType;
use crate::IValue;
use crate::NEVec;
pub fn record_lift_memory<R: RecordResolvable>(
lifter: &ILifter<'_, '_, R>,
record_type: &IRecordType,
offset: usize,
) -> LiResult<IValue> {
let mut values = Vec::with_capacity(record_type.fields.len());
let size = record_size(record_type);
let reader = &lifter.reader;
let seq_reader = reader.sequential_reader(offset, size)?;
for field in (*record_type.fields).iter() {
match &field.ty {
IType::Boolean => values.push(IValue::Boolean(seq_reader.read_u8() != 0)),
IType::S8 => values.push(IValue::S8(seq_reader.read_i8())),
IType::S16 => values.push(IValue::S16(seq_reader.read_i16())),
IType::S32 => values.push(IValue::S32(seq_reader.read_i32())),
IType::S64 => values.push(IValue::S64(seq_reader.read_i64())),
IType::I32 => values.push(IValue::I32(seq_reader.read_i32())),
IType::I64 => values.push(IValue::I64(seq_reader.read_i64())),
IType::U8 => values.push(IValue::U8(seq_reader.read_u8())),
IType::U16 => values.push(IValue::U16(seq_reader.read_u16())),
IType::U32 => values.push(IValue::U32(seq_reader.read_u32())),
IType::U64 => values.push(IValue::U64(seq_reader.read_u64())),
IType::F32 => values.push(IValue::F32(seq_reader.read_f32())),
IType::F64 => values.push(IValue::F64(seq_reader.read_f64())),
IType::String => values.push(IValue::String(read_string(reader, &seq_reader)?)),
IType::ByteArray => values.push(read_byte_array(reader, &seq_reader)?),
IType::Array(ty) => values.push(read_array(&lifter, &seq_reader, &**ty)?),
IType::Record(record_type_id) => {
values.push(read_record(lifter, &seq_reader, *record_type_id)?)
}
}
}
let record = NEVec::new(values.into_iter().collect())
.map_err(|_| LiError::EmptyRecord(record_type.name.clone()))?;
Ok(IValue::Record(record))
}
fn read_string(
reader: &MemoryReader<'_>,
seq_reader: &SequentialReader<'_, '_>,
) -> LiResult<String> {
let offset = seq_reader.read_u32();
let size = seq_reader.read_u32();
let string_mem = reader.read_raw_u8_array(offset as _, size as _)?;
let string = String::from_utf8(string_mem)?;
Ok(string)
}
fn read_byte_array(
reader: &MemoryReader<'_>,
seq_reader: &SequentialReader<'_, '_>,
) -> LiResult<IValue> {
let offset = seq_reader.read_u32();
let size = seq_reader.read_u32();
let array = reader.read_raw_u8_array(offset as _, size as _)?;
Ok(IValue::ByteArray(array))
}
fn read_array<R: RecordResolvable>(
lifter: &ILifter<'_, '_, R>,
seq_reader: &SequentialReader<'_, '_>,
value_type: &IType,
) -> LiResult<IValue> {
let offset = seq_reader.read_u32();
let size = seq_reader.read_u32();
super::array_lift_memory(lifter, value_type, offset as _, size as _)
}
fn read_record<R: RecordResolvable>(
lifter: &ILifter<'_, '_, R>,
seq_reader: &SequentialReader<'_, '_>,
record_type_id: u64,
) -> LiResult<IValue> {
let offset = seq_reader.read_u32();
let record_type = lifter.resolver.resolve_record(record_type_id)?;
record_lift_memory(lifter, &record_type, offset as _)
}