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.
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.
17 #[allow(missing_doc)];
19 use std::libc::{c_void, size_t, c_int};
24 use std::libc::{c_int, c_void, size_t};
26 #[link(name = "rustrt")]
28 pub fn tdefl_compress_mem_to_heap(psrc_buf: *c_void,
30 pout_len: *mut size_t,
34 pub fn tinfl_decompress_mem_to_heap(psrc_buf: *c_void,
36 pout_len: *mut size_t,
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 static TINFL_FLAG_PARSE_ZLIB_HEADER : c_int = 0x1; // parse zlib header and adler32 checksum
47 static TDEFL_WRITE_ZLIB_HEADER : c_int = 0x01000; // write zlib header and adler32 checksum
49 fn deflate_bytes_internal(bytes: &[u8], flags: c_int) -> ~[u8] {
50 bytes.as_imm_buf(|b, len| {
52 let mut outsz : size_t = 0;
54 rustrt::tdefl_compress_mem_to_heap(b as *c_void,
58 assert!(res as int != 0);
59 let out = vec::raw::from_buf_raw(res as *u8,
67 pub fn deflate_bytes(bytes: &[u8]) -> ~[u8] {
68 deflate_bytes_internal(bytes, LZ_NORM)
71 pub fn deflate_bytes_zlib(bytes: &[u8]) -> ~[u8] {
72 deflate_bytes_internal(bytes, LZ_NORM | TDEFL_WRITE_ZLIB_HEADER)
75 fn inflate_bytes_internal(bytes: &[u8], flags: c_int) -> ~[u8] {
76 bytes.as_imm_buf(|b, len| {
78 let mut outsz : size_t = 0;
80 rustrt::tinfl_decompress_mem_to_heap(b as *c_void,
84 assert!(res as int != 0);
85 let out = vec::raw::from_buf_raw(res as *u8,
93 pub fn inflate_bytes(bytes: &[u8]) -> ~[u8] {
94 inflate_bytes_internal(bytes, 0)
97 pub fn inflate_bytes_zlib(bytes: &[u8]) -> ~[u8] {
98 inflate_bytes_internal(bytes, TINFL_FLAG_PARSE_ZLIB_HEADER)
108 fn test_flate_round_trip() {
109 let mut r = rand::rng();
112 let range = r.gen_range(1u, 10);
113 words.push(r.gen_vec::<u8>(range));
118 input.push_all(r.choose(words));
120 debug!("de/inflate of {} bytes of random word-sequences",
122 let cmp = deflate_bytes(input);
123 let out = inflate_bytes(cmp);
124 debug!("{} bytes deflated to {} ({:.1f}% size)",
125 input.len(), cmp.len(),
126 100.0 * ((cmp.len() as f64) / (input.len() as f64)));
127 assert_eq!(input, out);
132 fn test_zlib_flate() {
133 let bytes = ~[1, 2, 3, 4, 5];
134 let deflated = deflate_bytes(bytes);
135 let inflated = inflate_bytes(deflated);
136 assert_eq!(inflated, bytes);