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
use binread::BinRead;
use crc32fast::Hasher;
use crate::{HashToIndex, DirInfo, StreamEntry, QuickDir};
#[repr(transparent)]
#[derive(BinRead, Debug, Clone, Copy, PartialEq, Eq, Ord, PartialOrd, Hash)]
pub struct Hash40(pub u64);
impl Hash40 {
pub fn as_u64(&self) -> u64 {
self.0
}
pub fn len(&self) -> u8 {
(self.0 >> 32) as u8
}
pub fn crc32(&self) -> u32 {
self.0 as u32
}
}
impl From<&Hash40> for Hash40 {
fn from(hash: &Hash40) -> Self {
*hash
}
}
impl From<u64> for Hash40 {
fn from(hash: u64) -> Self {
Hash40(hash)
}
}
impl From<&str> for Hash40 {
fn from(string: &str) -> Self {
hash40(string)
}
}
impl From<&HashToIndex> for Hash40 {
fn from(hash_index: &HashToIndex) -> Self {
hash_index.hash40()
}
}
impl From<HashToIndex> for Hash40 {
fn from(hash_index: HashToIndex) -> Self {
hash_index.hash40()
}
}
impl From<&StreamEntry> for Hash40 {
fn from(hash_index: &StreamEntry) -> Self {
hash_index.hash40()
}
}
impl From<StreamEntry> for Hash40 {
fn from(hash_index: StreamEntry) -> Self {
hash_index.hash40()
}
}
impl HashToIndex {
pub fn hash40(&self) -> Hash40 {
Hash40((self.hash() as u64) + ((self.length() as u64) << 32))
}
}
impl StreamEntry {
pub fn hash40(&self) -> Hash40 {
Hash40((self.hash() as u64) + ((self.name_length() as u64) << 32))
}
}
impl DirInfo {
pub fn path_hash40(&self) -> Hash40 {
Hash40((self.path_hash as u64) + ((self.dir_offset_index as u64) & 0xFF) << 32)
}
}
impl QuickDir {
pub fn hash40(&self) -> Hash40 {
Hash40((self.hash() as u64) + ((self.name_length() as u64) << 32))
}
}
pub fn hash40(string: &str) -> Hash40 {
let bytes = string.as_bytes();
Hash40(((bytes.len() as u64) << 32) + crc32(bytes) as u64)
}
fn crc32(bytes: &[u8]) -> u32 {
let mut hasher = Hasher::new();
hasher.update(bytes);
hasher.finalize()
}