]> git.lizzy.rs Git - rust.git/blob - src/libextra/flate.rs
Fix bug in `match`ing struct patterns
[rust.git] / src / libextra / flate.rs
1 // Copyright 2012 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 /*!
12
13 Simple compression
14
15 */
16
17 #[allow(missing_doc)];
18
19 use std::libc::{c_void, size_t, c_int};
20 use std::libc;
21 use std::vec;
22
23 pub mod rustrt {
24     use std::libc::{c_int, c_void, size_t};
25
26     #[link_name = "rustrt"]
27     extern {
28         pub fn tdefl_compress_mem_to_heap(psrc_buf: *const c_void,
29                                           src_buf_len: size_t,
30                                           pout_len: *mut size_t,
31                                           flags: c_int)
32                                           -> *c_void;
33
34         pub fn tinfl_decompress_mem_to_heap(psrc_buf: *const c_void,
35                                             src_buf_len: size_t,
36                                             pout_len: *mut size_t,
37                                             flags: c_int)
38                                             -> *c_void;
39     }
40 }
41
42 static LZ_NONE : c_int = 0x0;   // Huffman-coding only.
43 static LZ_FAST : c_int = 0x1;   // LZ with only one probe
44 static LZ_NORM : c_int = 0x80;  // LZ with 128 probes, "normal"
45 static LZ_BEST : c_int = 0xfff; // LZ with 4095 probes, "best"
46
47 pub fn deflate_bytes(bytes: &[u8]) -> ~[u8] {
48     do bytes.as_imm_buf |b, len| {
49         unsafe {
50             let mut outsz : size_t = 0;
51             let res =
52                 rustrt::tdefl_compress_mem_to_heap(b as *c_void,
53                                                    len as size_t,
54                                                    &mut outsz,
55                                                    LZ_NORM);
56             assert!(res as int != 0);
57             let out = vec::raw::from_buf_raw(res as *u8,
58                                              outsz as uint);
59             libc::free(res);
60             out
61         }
62     }
63 }
64
65 pub fn inflate_bytes(bytes: &[u8]) -> ~[u8] {
66     do bytes.as_imm_buf |b, len| {
67         unsafe {
68             let mut outsz : size_t = 0;
69             let res =
70                 rustrt::tinfl_decompress_mem_to_heap(b as *c_void,
71                                                      len as size_t,
72                                                      &mut outsz,
73                                                      0);
74             assert!(res as int != 0);
75             let out = vec::raw::from_buf_raw(res as *u8,
76                                             outsz as uint);
77             libc::free(res);
78             out
79         }
80     }
81 }
82
83 #[cfg(test)]
84 mod tests {
85     use super::*;
86     use std::rand;
87     use std::rand::RngUtil;
88
89     #[test]
90     fn test_flate_round_trip() {
91         let mut r = rand::rng();
92         let mut words = ~[];
93         do 20.times {
94             let range = r.gen_uint_range(1, 10);
95             words.push(r.gen_bytes(range));
96         }
97         do 20.times {
98             let mut input = ~[];
99             do 2000.times {
100                 input.push_all(r.choose(words));
101             }
102             debug!("de/inflate of %u bytes of random word-sequences",
103                    input.len());
104             let cmp = deflate_bytes(input);
105             let out = inflate_bytes(cmp);
106             debug!("%u bytes deflated to %u (%.1f%% size)",
107                    input.len(), cmp.len(),
108                    100.0 * ((cmp.len() as float) / (input.len() as float)));
109             assert_eq!(input, out);
110         }
111     }
112 }