|
| 1 | +(* |
| 2 | + * Copyright (c) 2015, Christopher Zimmermann |
| 3 | + * |
| 4 | + * Permission to use, copy, modify, and/or distribute this software for any |
| 5 | + * purpose with or without fee is hereby granted, provided that the above |
| 6 | + * copyright notice and this permission notice appear in all copies. |
| 7 | + * |
| 8 | + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
| 9 | + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
| 10 | + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY |
| 11 | + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
| 12 | + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION |
| 13 | + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN |
| 14 | + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
| 15 | + *) |
| 16 | + |
| 17 | +type status = |
| 18 | + | Ok (* 0 *) |
| 19 | + | Stream_end (* 1 *) |
| 20 | + | Need_dict (* 2 *) |
| 21 | + | Buf_error (* 3 (zlib -5) *) |
| 22 | + | Data_error of string (* 0 (zlib -3) *) |
| 23 | + |
| 24 | +type algo = Deflated |
| 25 | + |
| 26 | +type strategy = |
| 27 | + | Default_strategy (* 0 *) |
| 28 | + | Filtered (* 1 *) |
| 29 | + | Huffman_only (* 2 *) |
| 30 | + | RLE (* 3 *) |
| 31 | + | Fixed (* 4 *) |
| 32 | + |
| 33 | +type flush = |
| 34 | + | No_flush (* 0 *) |
| 35 | + | Partial_flush (* 1 *) |
| 36 | + | Sync_flush (* 2 *) |
| 37 | + | Full_flush (* 3 *) |
| 38 | + | Finish (* 4 *) |
| 39 | + | Block (* 5 *) |
| 40 | + | Trees (* 6 *) |
| 41 | + |
| 42 | +type data_type = |
| 43 | + | Binary (* 0 *) |
| 44 | + | Text (* 1 *) |
| 45 | + | Unknown (* 2 *) |
| 46 | + |
| 47 | +type deflate |
| 48 | +type inflate |
| 49 | +type 'a state |
| 50 | +type bigstring = (char, Bigarray.int8_unsigned_elt, Bigarray.c_layout) Bigarray.Array1.t |
| 51 | + |
| 52 | +type 'a t = |
| 53 | + { state : 'a state |
| 54 | + ; mutable in_buf : (char, Bigarray.int8_unsigned_elt, Bigarray.c_layout) Bigarray.Array1.t |
| 55 | + ; mutable out_buf : (char, Bigarray.int8_unsigned_elt, Bigarray.c_layout) Bigarray.Array1.t |
| 56 | + ; mutable in_ofs : int |
| 57 | + ; mutable out_ofs : int |
| 58 | + ; mutable in_len : int |
| 59 | + ; mutable out_len : int |
| 60 | + ; mutable in_total : int |
| 61 | + ; mutable out_total : int |
| 62 | + ; mutable data_type : int |
| 63 | + ; mutable cksum : int32 |
| 64 | + } |
| 65 | + |
| 66 | +type header = |
| 67 | + { text : bool |
| 68 | + ; mtime : int32 |
| 69 | + ; os : int |
| 70 | + ; xflags : int |
| 71 | + ; extra : string option |
| 72 | + ; name : string option |
| 73 | + ; comment : string option |
| 74 | + } |
| 75 | + |
| 76 | +external inflate_init : window_bits:int -> inflate state = "zlib_inflate_init" |
| 77 | + |
| 78 | +external deflate_init |
| 79 | + : level:int |
| 80 | + -> algo:algo |
| 81 | + -> window_bits:int |
| 82 | + -> memory:int |
| 83 | + -> strategy:strategy |
| 84 | + -> deflate state |
| 85 | + = "zlib_deflate_init" |
| 86 | + |
| 87 | +(* calculate upper bound on deflated stream. *) |
| 88 | +external deflate_bound : deflate state -> int -> int = "zlib_deflate_bound" |
| 89 | + |
| 90 | +(* flate handle flush *) |
| 91 | +external flate : 'a t -> flush -> status = "zlib_flate" |
| 92 | + |
| 93 | +(* set dictionary *) |
| 94 | +external deflate_set_dictionary : deflate state -> string -> int32 = "zlib_deflate_set_dictionary" |
| 95 | +external inflate_set_dictionary : inflate state -> string -> status = "zlib_inflate_set_dictionary" |
| 96 | + |
| 97 | +(* set/get header *) |
| 98 | +external set_header : deflate state -> header -> unit = "zlib_set_header" |
| 99 | +external get_header : inflate state -> header = "zlib_get_header" |
| 100 | + |
| 101 | +(* reset *) |
| 102 | +external reset : 'a t -> unit = "zlib_reset" |
| 103 | + |
| 104 | +(* adler32 *) |
| 105 | +external adler32 : int32 -> string -> int32 = "zlib_adler32" |
| 106 | + |
| 107 | +let adler32_empty = Int32.one |
| 108 | + |
| 109 | +let get_data_type (mlstate : deflate t) = |
| 110 | + match mlstate.data_type with 0 -> Binary | 1 -> Text | 2 -> Unknown | _ -> assert false |
| 111 | +;; |
| 112 | + |
| 113 | +(* create caml record wrapping zlib state and bigarray buffers *) |
| 114 | +0 |
| 115 | + |
| 116 | +let create_deflate, create_inflate = |
| 117 | + let dummy_buf = Bigarray.(Array1.create char c_layout 0) in |
| 118 | + let wrap state = |
| 119 | + { state |
| 120 | + ; in_buf = dummy_buf |
| 121 | + ; out_buf = dummy_buf |
| 122 | + ; in_ofs = 0 |
| 123 | + ; out_ofs = 0 |
| 124 | + ; in_len = -1 |
| 125 | + ; out_len = -1 |
| 126 | + ; in_total = 0 |
| 127 | + ; out_total = 0 |
| 128 | + ; cksum = Int32.zero |
| 129 | + ; data_type = 2 |
| 130 | + } |
| 131 | + in |
| 132 | + let create_deflate |
| 133 | + ?(level = -1) |
| 134 | + ?(algo = Deflated) |
| 135 | + ?(window_bits = 15) |
| 136 | + ?(memory = 8) |
| 137 | + ?(strategy = Default_strategy) |
| 138 | + () |
| 139 | + = |
| 140 | + wrap (deflate_init ~level ~algo ~window_bits ~memory ~strategy) |
| 141 | + in |
| 142 | + let create_inflate ?(window_bits = 15) () = wrap (inflate_init ~window_bits) in |
| 143 | + create_deflate, create_inflate |
| 144 | +;; |
0 commit comments