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
117
118
119
120
121
122
#[macro_use]
extern crate serde_derive;
extern crate serde_cbor;
extern crate byteorder;
extern crate siphasher;
use std::io::Cursor;
use byteorder::{BigEndian, WriteBytesExt, ReadBytesExt};
use siphasher::sip::SipHasher;
use std::hash::{Hash, Hasher};
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct Msg {
pub uid: String,
pub channel: String,
pub message: Vec<u8>,
}
pub fn message_encode(msg: &Msg) -> Vec<u8> {
let encoded = serde_cbor::to_vec(msg);
match encoded {
Ok(encoded) => encoded,
Err(err) => {
println!("Error on encode: {}", err);
Vec::new()
}
}
}
pub fn message_decode(slice: &[u8]) -> Msg {
let value = serde_cbor::from_slice(slice);
match value {
Ok(value) => value,
Err(err) => {
println!("Error on decode: {}", err);
Msg { uid: "".to_string(), channel: "".to_string(), message: Vec::new() }
}
}
}
pub fn read_hdr_type(hdr: &[u8]) -> u32 {
let mut buf = Cursor::new(&hdr[..]);
let num = buf.read_u32::<BigEndian>().unwrap();
num >> 24
}
pub fn read_hdr_len(hdr: &[u8]) -> usize {
let mut buf = Cursor::new(&hdr[..]);
let num = buf.read_u32::<BigEndian>().unwrap();
(num & 0xfff) as usize
}
pub fn write_hdr(len: usize) -> Vec<u8> {
let hdr = (('M' as u32) << 24) | len as u32;
let mut msgv = vec![];
msgv.write_u32::<BigEndian>(hdr).unwrap();
msgv
}
pub fn write_key(val: u64) -> Vec<u8> {
let key = val;
let mut msgv = vec![];
msgv.write_u64::<BigEndian>(key).unwrap();
msgv
}
pub fn read_key(keyv: Vec<u8>) -> u64 {
let mut buf = Cursor::new(&keyv[..]);
let num = buf.read_u64::<BigEndian>().unwrap();
num
}
pub fn do_hash<T: Hash>(t: &T) -> u64 {
let mut s = SipHasher::new();
t.hash(&mut s);
s.finish()
}
#[cfg(test)]
mod tests {
use std::net::SocketAddr;
use super::*;
#[test]
fn test_encode_decode_msg() {
let orig_msg = Msg { uid: "User".to_string(), channel: "Channel".to_string(), message: "a test msg".to_string().into_bytes() };
let cbor_msg = message_encode(&orig_msg);
let decoded_msg = message_decode(&cbor_msg);
assert_eq!(decoded_msg.uid, orig_msg.uid);
assert_eq!(decoded_msg.channel, orig_msg.channel);
assert_eq!(decoded_msg.message, orig_msg.message);
}
#[test]
fn test_hash() {
let addr = "127.0.0.1:8077";
let addr = addr.parse::<SocketAddr>().unwrap();
let orig_key = do_hash(&addr);
let keyv = write_key(orig_key);
let key = read_key(keyv);
assert_eq!(orig_key, key);
}
}