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
use { file_funcs, FuncMapper, Payload, string };
use error::*;
use func::{ Func, new_func };
use libflo_module::{ ModuleMapper, PathResolver, self_module_name };
use serialization::{ DllSerde, FuncSerde, ParameterSerde };
use sharedlib::LibArc;
use std::collections::HashMap;

pub unsafe fn load(
    module_mapper: &ModuleMapper,
    path_resolver: &PathResolver,
) -> Result<Payload> {
    let my_id = module_mapper.get(self_module_name())?;
    let func_file_name = string::func_file_name();

    let mut pre_func_list = Vec::new();
    let mut pre_func_map = module_mapper.get_raw_map().into_iter().map(|_| None).collect();

    for (module_name, module_id) in module_mapper.get_raw_map() {
        if let Some(dll_json_path) = path_resolver.try_find_submodule_file_path(func_file_name, *module_id, my_id)? {
            let dll_json = file_funcs::dll_from_path(dll_json_path)?;
            create_funcs(dll_json, module_name, *module_id, my_id, &path_resolver, &mut pre_func_list, &mut pre_func_map)?;
        };
    }

    let func_mapper = FuncMapper::new(pre_func_map, pre_func_list);

    let result =
        Payload::new(
            func_mapper,
        );
    Ok(result)
}

unsafe fn create_funcs(
    dll: DllSerde,
    module_name: &String,
    module_id: usize,
    self_module_id: usize,
    path_resolver: &PathResolver,
    pre_func_list: &mut Vec<Box<Func>>,
    pre_func_map: &mut Vec<Option<HashMap<String, usize>>>,
) -> Result<()> {
    let (path, funcs) = dll.destructure();
    let dll_full_path = path_resolver.find_submodule_file_path(path, module_id, self_module_id)?;
    let library = LibArc::new(dll_full_path.clone())
        .chain_err(|| ErrorKind::DllCouldNotLoad(dll_full_path, module_id))?;
    for func in funcs {
        create_func(func, &library, module_name, module_id, pre_func_list, pre_func_map)?;
    }

    Ok(())
}

unsafe fn create_func(
    func: FuncSerde,
    library: &LibArc,
    module_name: &String,
    module_id: usize,
    pre_func_list: &mut Vec<Box<Func>>,
    pre_func_map: &mut Vec<Option<HashMap<String, usize>>>,
) -> Result<()> {
    let (input, output, symbol, name) = func.destructure();

    let input = input.unwrap_or(ParameterSerde::none);
    let output = output.unwrap_or(ParameterSerde::none);
    let name = name.unwrap_or(symbol.clone());
    let func_id = pre_func_list.len();

    if let Some(&None) = pre_func_map.get(module_id) {
        pre_func_map[module_id] = Some(HashMap::new());
    }

    if let Some(&mut Some(ref mut inner_func_map)) = pre_func_map.get_mut(module_id) {
        if let Some(_) = inner_func_map.insert(name.clone(), func_id) {
            return Err(ErrorKind::FuncLoadNameCollision(name, module_name.clone()).into());
        }
    }

    let func = new_func(library, symbol, input, output)?;
    pre_func_list.push(func);

    Ok(())
}