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
extern crate libc;
extern crate matrix;
use matrix::format::{Compressed, Conventional, Diagonal};
use std::ffi::CString;
use std::fs;
use std::io::{Error, ErrorKind, Result};
use std::path::Path;
mod ffi;
macro_rules! raise(
($kind:ident, $message:expr) => (
return Err(Error::new(ErrorKind::$kind, $message))
);
);
macro_rules! str_to_cstr(
($str:expr) => (match CString::new($str) {
Ok(result) => result,
_ => raise!(Other, "failed to process the arguments"),
});
);
macro_rules! path_to_cstr(
($path:expr) => (match $path.to_str() {
Some(path) => str_to_cstr!(path),
_ => raise!(Other, "failed to process the arguments"),
});
);
pub struct Circuit {
pub units: usize,
pub nodes: usize,
pub capacitance: Diagonal<f64>,
pub conductance: Compressed<f64>,
}
impl Circuit {
pub fn new<F: AsRef<Path>, C: AsRef<Path>>(floorplan: F, config: C) -> Result<Circuit> {
use std::slice::from_raw_parts;
let (floorplan, config) = (floorplan.as_ref(), config.as_ref());
if fs::metadata(floorplan).is_err() {
raise!(NotFound, "the floorplan file does not exist");
}
if fs::metadata(config).is_err() {
raise!(NotFound, "the configuration file does not exist");
}
unsafe {
let floorplan = path_to_cstr!(floorplan);
let config = path_to_cstr!(config);
let circuit = ffi::new_Circuit(floorplan.as_ptr(), config.as_ptr());
if circuit.is_null() {
raise!(Other, "failed to construct a thermal circuit");
}
let circuit = &*circuit;
let units = circuit.units as usize;
let nodes = circuit.nodes as usize;
let capacitance = from_raw_parts(circuit.capacitance as *const _, nodes);
let capacitance = Diagonal::from_slice(nodes, capacitance);
let conductance = from_raw_parts(circuit.conductance as *const _, nodes * nodes);
let conductance = Conventional::from_slice(nodes, conductance);
let conductance = Compressed::from(conductance);
ffi::drop_Circuit(circuit as *const _ as *mut _);
Ok(Circuit {
units: units,
nodes: nodes,
capacitance: capacitance,
conductance: conductance,
})
}
}
}