Skip to content

Commit

Permalink
feat(state_format): add DHT section and its de-serialization
Browse files Browse the repository at this point in the history
Also move function for safe casing `u32 → array` from tests to
binary_io, make it public, and add test for it.
  • Loading branch information
zetok committed May 20, 2016
1 parent 85508e1 commit 8c63279
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 10 deletions.
8 changes: 8 additions & 0 deletions src/toxcore/binary_io.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,14 @@ pub fn array_to_u32(array: &[u8; 4]) -> u32 {
result
}

/// Safely cast `u32` to `[u8; 4]`.
pub fn u32_to_array(num: u32) -> [u8; 4] {
let mut array: [u8; 4] = [0; 4];
for (pos, item) in array.iter_mut().enumerate() {
*item = (num >> (8 * pos)) as u8;
}
array
}

/// Safely cast `&[u8; 8]` to `u64`.
pub fn array_to_u64(array: &[u8; 8]) -> u64 {
Expand Down
60 changes: 60 additions & 0 deletions src/toxcore/state_format/old.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
use toxcore::binary_io::*;
use toxcore::crypto_core::*;
use toxcore::dht::*;
use toxcore::toxid::{NoSpam, NOSPAMBYTES};

// TODO: improve docs
Expand Down Expand Up @@ -265,3 +266,62 @@ impl ToBytes for NospamKeys {
result
}
}


/** DHT section of the old state format.
https://zetok.github.io/tox-spec/#dht-0x02
Serialized format
*/
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct DhtState(pub Vec<PackedNode>);

/// Minimal number of bytes [`DhtState`](./struct.DhtState.html) has.
///
/// Assumes that at least all the magic numbers are present.
const DHT_STATE_SIZE_MIN: usize = 12;

/// Special, magical beginning of DHT section in LE.
const DHT_MAGICAL: u32 = 0x159000d;

/** Special DHT section type encoded in LE.
https://zetok.github.io/tox-spec/#dht-sections
*/
const DHT_SECTION_TYPE: u16 = 0x04;

/** Yet another magical number in DHT section that needs a check.
https://zetok.github.io/tox-spec/#dht-sections
*/
const DHT_2ND_MAGICAL: u16 = 0x11ce;

/** If successful, returns `DhtState` and length of the section in bytes.
If de-serialization failed, returns `None`.
*/
// TODO: better docs; list when can fail
impl FromBytes<(DhtState, usize)> for (DhtState, usize) {
fn from_bytes(bytes: &[u8]) -> Option<Self> {
if
bytes.len() < DHT_STATE_SIZE_MIN ||
// check whether beginning of the section matches DHT magic bytes
&u32_to_array(DHT_MAGICAL.to_le()) != &bytes[..4] ||
// check DHT section type
&u16_to_array(DHT_SECTION_TYPE.to_le()) != &bytes[8..10] ||
// check whether yet another magic number matches ;f
&u16_to_array(DHT_2ND_MAGICAL.to_le()) != &bytes[10..12]
{ return None } // can I haz yet another magical number?

// length of the whole section
let section_len = {
let nodes = array_to_u32(&[bytes[4], bytes[5], bytes[6], bytes[7]]);
u32::from_le(nodes) as usize + DHT_STATE_SIZE_MIN
};

PackedNode::from_bytes_multiple(&bytes[DHT_STATE_SIZE_MIN..section_len])
.map(|pns| (DhtState(pns), section_len))
}
}
// TODO: test ↑
26 changes: 16 additions & 10 deletions src/toxcore_tests/binary_io_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,22 +25,15 @@ use toxcore::binary_io::*;


fn u16_to_array_and_back(num: u16) {
assert!(num == array_to_u16(&u16_to_array(num)));
assert_eq!(num, array_to_u16(&u16_to_array(num)));
}

fn u32_to_array(num: u32) -> [u8; 4] {
let mut array: [u8; 4] = [0; 4];
for (pos, item) in array.iter_mut().enumerate() {
*item = (num >> (8 * pos)) as u8;
}
array
}
fn u32_to_array_and_back(num: u32) {
assert!(num == array_to_u32(&u32_to_array(num)));
assert_eq!(num, array_to_u32(&u32_to_array(num)));
}

fn u64_to_array_and_back(num: u64) {
assert!(num == array_to_u64(&u64_to_array(num)));
assert_eq!(num, array_to_u64(&u64_to_array(num)));
}

#[test]
Expand Down Expand Up @@ -77,6 +70,19 @@ fn array_to_u32_test() {
quickcheck(u32_to_array_and_back as fn(u32));
}

#[test]
fn u32_to_array_test() {
assert_eq!([0, 0, 0, 0], u32_to_array(0));
assert_eq!([1, 0, 0, 0], u32_to_array(1));
assert_eq!([0, 1, 0, 0], u32_to_array(256));
assert_eq!([0, 0, 1, 0], u32_to_array(65536));
assert_eq!([0, 0, 0, 1], u32_to_array(16777216));
assert_eq!([0, 0, 0, 0xff], u32_to_array(4278190080));
assert_eq!([0xff, 0xff, 0xff, 0xff], u32_to_array(u32::max_value()));

quickcheck(u32_to_array_and_back as fn(u32));
}

#[test]
fn array_to_u64_test() {
assert_eq!(array_to_u64(&[0, 0, 0, 0, 0, 0, 0, 0]), 0);
Expand Down

0 comments on commit 8c63279

Please sign in to comment.