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
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
//! 縮めたものを戻すところ
//!
//! 縮めるほうはテストの中にだけある。いろいろな並びを縮めて、folio の展開で元に戻ることを確かめる。
mod common;
use common::deflate;
use folio::inflate;
/// 決まった並びの疑似乱数。テストのたびに同じ値が出る
fn noise(count: usize, seed: u64) -> Vec<u8> {
let mut value = seed;
let mut result = Vec::with_capacity(count);
for _ in 0..count {
value = value.wrapping_mul(6364136223846793005).wrapping_add(1442695040888963407);
result.push((value >> 33) as u8);
}
result
}
/// 出る回数の大きく偏った並び
///
/// k 番目の文字は 2 の k + 1 乗分の 1 の割合で出る。まれな文字には 11 ビットより長い符号が付くので、
/// 展開する側の 2 段目の表を通る。
fn skewed(count: usize, seed: u64) -> Vec<u8> {
noise(count * 8, seed)
.chunks(8)
.map(|piece| {
let mut word = [0u8; 8];
word.copy_from_slice(piece);
b'a' + u64::from_le_bytes(word).leading_zeros() as u8
})
.collect()
}
/// 試しに使う、性質のちがう並び
fn sample() -> Vec<(&'static str, Vec<u8>)> {
vec![
("空", Vec::new()),
("一文字", b"a".to_vec()),
("同じ語の繰り返し", "<row r=\"1\"><c r=\"A1\"><v>0</v></c></row>".repeat(500).into_bytes()),
("二文字の繰り返し", b"ab".repeat(100000).to_vec()),
("乱数", noise(200000, 7)),
("同じ文字の並び", [vec![b'x'; 70000], vec![b'y'; 5], vec![b'z'; 300000]].concat()),
("窓を超える繰り返し", noise(40000, 3).repeat(3)),
("窓の端までの繰り返し", noise(30000, 41).repeat(4)),
("日本語", "あいうえお かきくけこ".repeat(20000).into_bytes()),
("偏った並び", skewed(300000, 37)),
]
}
#[test]
fn packing_and_unpacking_returns_the_same_bytes() {
for (name, data) in sample() {
let packed = deflate::deflate(&data);
let back = inflate::inflate_sized(&packed, data.len()).expect(name);
assert_eq!(back, data, "{name}");
}
}
#[test]
fn writing_in_pieces_gives_the_same_result() {
for (name, data) in sample() {
let mut state = deflate::Deflate::new();
let mut packed = Vec::new();
let mut cut = 0;
let mut size = 1;
while cut < data.len() {
let stop = (cut + size).min(data.len());
state.write(&data[cut..stop]);
packed.extend_from_slice(&state.take());
cut = stop;
size = (size * 3).min(70000);
}
state.finish();
packed.extend_from_slice(&state.take());
let back = inflate::inflate_sized(&packed, data.len()).expect(name);
assert_eq!(back, data, "{name}");
}
}
#[test]
fn unpacking_can_hand_out_pieces() {
for (name, data) in sample() {
let packed = deflate::deflate(&data);
let mut back = Vec::new();
inflate::inflate_with(&packed, &mut |piece| {
back.extend_from_slice(piece);
Ok(())
})
.expect(name);
assert_eq!(back, data, "{name}");
}
}
#[test]
fn packed_bytes_can_arrive_in_pieces() {
let data = noise(300000, 11);
let packed = deflate::deflate(&data);
let mut cursor = 0;
let mut back = Vec::new();
let mut supply = || {
if cursor >= packed.len() {
return Ok(None);
}
let stop = (cursor + 1000).min(packed.len());
let piece = packed[cursor..stop].to_vec();
cursor = stop;
Ok(Some(piece))
};
inflate::inflate_stream(&mut supply, &mut |piece| {
back.extend_from_slice(piece);
Ok(())
})
.unwrap();
assert_eq!(back, data);
}
#[test]
fn broken_data_fails() {
let data = "これは deflate ではありません".as_bytes().to_vec();
assert!(inflate::inflate(&data).is_err());
}
#[test]
fn truncated_data_fails() {
let data = noise(50000, 17);
let packed = deflate::deflate(&data);
assert!(inflate::inflate(&packed[..packed.len() / 2]).is_err());
}