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
use super::serde::Deserialize;
use crate::io::Source;
use crate::utils::{DynString, LinkedHashMap, C256, C4};
use super::Token;
pub struct TokenBuilder {}
impl TokenBuilder {
pub fn create_from_template(template: &Token, source: &mut Source) -> Token {
match template {
Token::UInt8(_) => u8::from_le_vec(source).into(),
Token::UInt16(_) => u16::from_le_vec(source).into(),
Token::UInt32(_) => u32::from_le_vec(source).into(),
Token::Int8(_) => i8::from_le_vec(source).into(),
Token::Int16(_) => i16::from_le_vec(source).into(),
Token::Int32(_) => i32::from_le_vec(source).into(),
Token::Float32(_) => f32::from_le_vec(source).into(),
Token::Float64(_) => f64::from_le_vec(source).into(),
Token::Char4(_) => C4::from_le_vec(source).into(),
Token::Char256(_) => C256::from_le_vec(source).into(),
Token::Str16(_) => DynString::<u16>::from_le_vec(source).into(),
Token::Str32(_) => DynString::<u32>::from_le_vec(source).into(),
Token::Union(map) => {
let mut mock = LinkedHashMap::new();
let keys = map.keys();
let patchs = &map.patchs;
for (index, token) in map.iter().enumerate() {
let key = &keys[index];
let mut template = token.clone();
if patchs.contains_key(key) {
let patch = &patchs[key];
match patch.dep_type {
crate::utils::map::DepType::Exist => {
let flag = patch
.source
.iter()
.map(|key| mock[key].try_compatible_u64() > 0)
.fold(true, |sum, val| sum & val);
if !flag {
template.try_mut_vec().clear();
}
}
crate::utils::map::DepType::Calculate => match patch.manipulation {
crate::utils::map::Manipulation::Equal => {
let dep_key = &patch.source[0];
let num = mock[dep_key].try_compatible_u64();
let vec = template.try_mut_vec();
let unit = vec[0].clone();
vec.clear();
for _ in 0..num {
vec.push(unit.clone());
}
}
crate::utils::map::Manipulation::Multiple => {
let rkey = &patch.source[0];
let lkey = &patch.source[1];
let rnum = mock[rkey].try_compatible_u64();
let lnum = mock[lkey].try_compatible_u64();
let vec = template.try_mut_vec();
let unit = vec[0].clone();
vec.clear();
for _ in 0..lnum * rnum {
vec.push(unit.clone());
}
}
},
}
}
mock.push_back(key, TokenBuilder::create_from_template(&template, source));
}
mock.into()
}
Token::Vector(vec) => {
let mut mock = Vec::<Token>::new();
for token in vec {
mock.push(Self::create_from_template(token, source))
}
mock.into()
}
}
}
}