opcua/
lib.rs

1#[macro_use]
2extern crate lazy_static;
3#[macro_use]
4extern crate log;
5#[cfg(test)]
6extern crate tempdir;
7#[macro_use]
8extern crate bitflags;
9#[macro_use]
10extern crate serde_derive;
11#[cfg(feature = "http")]
12extern crate actix_web;
13#[cfg(test)]
14extern crate serde_json;
15#[macro_use]
16extern crate derivative;
17
18// Synchronization structs. This is a wrapper mod around `parking_lot` types so opcua users don't have
19// to reference that other crate.
20pub mod sync {
21    pub type RwLock<T> = parking_lot::RwLock<T>;
22    pub type Mutex<T> = parking_lot::Mutex<T>;
23}
24
25/// Tracing macro for obtaining a lock on a `Mutex`. Sometimes deadlocks can happen in code,
26/// and if they do, this macro is useful for finding out where they happened.
27#[macro_export]
28macro_rules! trace_lock {
29    ( $x:expr ) => {
30        {
31//            use std::thread;
32//            trace!("Thread {:?}, {} locking at {}, line {}", thread::current().id(), stringify!($x), file!(), line!());
33            let v = $x.lock();
34//            trace!("Thread {:?}, {} lock completed", thread::current().id(), stringify!($x));
35            v
36        }
37    }
38}
39
40/// Tracing macro for obtaining a read lock on a `RwLock`.
41#[macro_export]
42macro_rules! trace_read_lock {
43    ( $x:expr ) => {
44        {
45//            use std::thread;
46//            trace!("Thread {:?}, {} read locking at {}, line {}", thread::current().id(), stringify!($x), file!(), line!());
47            let v = $x.read();
48//            trace!("Thread {:?}, {} read lock completed", thread::current().id(), stringify!($x));
49            v
50        }
51    }
52}
53
54/// Tracing macro for obtaining a write lock on a `RwLock`.
55#[macro_export]
56macro_rules! trace_write_lock {
57    ( $x:expr ) => {
58        {
59//            use std::thread;
60//            trace!("Thread {:?}, {} write locking at {}, line {}", thread::current().id(), stringify!($x), file!(), line!());
61            let v = $x.write();
62//            trace!("Thread {:?}, {} write lock completed", thread::current().id(), stringify!($x));
63            v
64        }
65    }
66}
67
68#[cfg(feature = "client")]
69pub mod client;
70#[cfg(feature = "console-logging")]
71pub mod console_logging;
72pub mod core;
73pub mod crypto;
74#[cfg(feature = "server")]
75pub mod server;
76pub mod types;
77
78// Turns hex string to array bytes. Function was extracted & adapted from the deprecated
79// crate rustc-serialize. Function panics if the string is invalid.
80//
81// https://github.com/rust-lang-deprecated/rustc-serialize/blob/master/src/hex.rs
82#[cfg(test)]
83fn from_hex(v: &str) -> Vec<u8> {
84    // This may be an overestimate if there is any whitespace
85    let mut b = Vec::with_capacity(v.len() / 2);
86    let mut modulus = 0;
87    let mut buf = 0;
88
89    for (idx, byte) in v.bytes().enumerate() {
90        buf <<= 4;
91
92        match byte {
93            b'A'..=b'F' => buf |= byte - b'A' + 10,
94            b'a'..=b'f' => buf |= byte - b'a' + 10,
95            b'0'..=b'9' => buf |= byte - b'0',
96            b' ' | b'\r' | b'\n' | b'\t' => {
97                buf >>= 4;
98                continue;
99            }
100            _ => {
101                let ch = v[idx..].chars().next().unwrap();
102                panic!("Invalid hex character {} at {}", ch, idx);
103            }
104        }
105
106        modulus += 1;
107        if modulus == 2 {
108            modulus = 0;
109            b.push(buf);
110        }
111    }
112
113    match modulus {
114        0 => b.into_iter().collect(),
115        _ => panic!("Invalid hex length"),
116    }
117}
118
119mod prelude {
120    #[cfg(feature = "client")]
121    pub use crate::client::prelude::*;
122    pub use crate::core::prelude::*;
123    #[cfg(feature = "server")]
124    pub use crate::server::prelude::*;
125}