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
use ::libc;
pub type __uint32_t = libc::c_uint;
pub type __uint64_t = libc::c_ulong;
pub type uint32_t = __uint32_t;
pub type uint64_t = __uint64_t;
#[inline]
unsafe fn __bswap_32(mut __bsx: __uint32_t) -> __uint32_t {
return (__bsx & 0xff000000 as libc::c_uint) >> 24 as libc::c_int
| (__bsx & 0xff0000 as libc::c_uint) >> 8 as libc::c_int
| (__bsx & 0xff00 as libc::c_uint) << 8 as libc::c_int
| (__bsx & 0xff as libc::c_uint) << 24 as libc::c_int;
}
/// C `vendor/tmux/compat/ntohll.c:23`: `uint64_t ntohll(uint64_t v)`
pub unsafe fn ntohll(mut v: uint64_t) -> uint64_t {
let mut b: uint32_t = 0;
let mut t: uint32_t = 0;
b = __bswap_32((v & 0xffffffff as libc::c_uint as libc::c_ulong) as __uint32_t);
t = __bswap_32((v >> 32 as libc::c_int) as __uint32_t);
return (b as uint64_t) << 32 as libc::c_int | t as libc::c_ulong;
}
#[cfg(test)]
mod tests {
use super::*;
// The C source (vendor/tmux/compat/ntohll.c) computes:
// b = ntohl(v & 0xffffffff); t = ntohl(v >> 32); return ((uint64_t)b << 32 | t);
// On a little-endian host ntohl is a 32-bit byte swap, so ntohll is a full
// 64-bit byte reversal. This Rust port applies __bswap_32 unconditionally,
// matching little-endian behavior (all supported test hosts are LE).
#[test]
fn test_ntohll_known_constant() {
// 0x0123456789ABCDEF byte-reversed is 0xEFCDAB8967452301.
// low32 = 0x89ABCDEF -> bswap -> 0xEFCDAB89 (b)
// high32 = 0x01234567 -> bswap -> 0x67452301 (t)
// result = (b << 32) | t = 0xEFCDAB8967452301
unsafe {
assert_eq!(ntohll(0x0123456789ABCDEF), 0xEFCDAB8967452301);
}
}
#[test]
fn test_ntohll_matches_swap_bytes() {
// On little-endian hosts ntohll is exactly a 64-bit byte swap.
for &v in &[
0u64,
1,
0xFF,
0xFF00000000000000,
0xDEADBEEFCAFEBABE,
u64::MAX,
0x0000_0001_0000_0000,
] {
unsafe {
assert_eq!(ntohll(v), v.swap_bytes());
}
}
}
#[test]
fn test_ntohll_roundtrip() {
// Applying the byte swap twice restores the original value.
for &v in &[
0u64,
0x1,
0xABCDEF0123456789,
u64::MAX,
0x8000_0000_0000_0001,
] {
unsafe {
assert_eq!(ntohll(ntohll(v)), v);
}
}
}
#[test]
fn test_ntohll_edge_values() {
unsafe {
assert_eq!(ntohll(0), 0);
// A single low byte moves to the most-significant byte.
assert_eq!(ntohll(0xFF), 0xFF00000000000000);
// The 32-bit halves are swapped as whole units (plus inner swap).
assert_eq!(ntohll(0x0000_0000_FFFF_FFFF), 0xFFFF_FFFF_0000_0000);
}
}
}