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
open Types
let encoded_length s =
let len = String.length s in
let rec loop bits i =
if i < len
then
let input = Char.code s.[i] in
let _, len_in_bits = Huffman_table.encode_table.(input) in
loop (bits + len_in_bits) (i + 1)
else
(bits + 7) / 8
in
loop 0 0
let encode t s =
let bits = ref 0 in
let bits_left = ref 40 in
for i = 0 to String.length s - 1 do
let code, code_len = Huffman_table.encode_table.(Char.code s.[i]) in
bits_left := !bits_left - code_len;
bits := !bits lor (code lsl !bits_left);
while !bits_left <= 32 do
Faraday.write_uint8 t (!bits lsr 32);
bits := !bits lsl 8;
bits_left := !bits_left + 8
done
done;
if !bits_left < 40
then (
bits := !bits lor ((1 lsl !bits_left) - 1);
Faraday.write_uint8 t (!bits lsr 32))
let decode =
let[@inline] add_output buffer c =
if c <> '\000' then Buffer.add_char buffer c
in
let[@inline] exists_in_huffman_table token = token <> -1 in
fun s ->
let len = String.length s in
let buffer = Buffer.create len in
let rec loop id accept i =
if i < len
then (
let input = Char.code s.[i] in
let index = (id lsl 4) + (input lsr 4) in
let id, _, output = Huffman_table.decode_table.(index) in
add_output buffer output;
if exists_in_huffman_table id
then (
let index = (id lsl 4) + (input land 0x0f) in
let id, accept, output = Huffman_table.decode_table.(index) in
add_output buffer output;
if exists_in_huffman_table id
then loop id accept (i + 1)
else Error Decoding_error)
else Error Decoding_error)
else if not accept
then Error Decoding_error
else Ok ()
in
match loop 0 true 0 with
| Ok _ -> Ok (Buffer.contents buffer)
| Error e -> Error e