]> gitweb.factorcode.org Git - factor.git/blob - extra/compression/bzip3/bzip3.factor
bzip3: add unit tests, fix unit test problems
[factor.git] / extra / compression / bzip3 / bzip3.factor
1 USING: alien alien.libraries alien.c-types alien.data alien.syntax endian
2        kernel io.encodings.string byte-arrays sequences combinators syntax
3        compression.bzip3.ffi locals math math.order summary pair-rocket ;
4 IN: compression.bzip3
5
6 ERROR: invalid-block-size size ;
7 M: invalid-block-size summary drop "Block size must be between 65 KiB and 511 MiB" ;
8 ERROR: internal-error msg ;
9 M: internal-error summary drop "bzip3: Internal Error" ;
10
11 <PRIVATE
12 CONSTANT: dsize 1048576 ! placeholder block size
13
14 : throw-internal-error ( code -- msg ) {
15     -1 => [ "BZ3_ERR_OUT_OF_BOUNDS" ]
16     -2 => [ "BZ3_ERR_BWT" ]
17     -3 => [ "BZ3_ERR_CRC" ]
18     -4 => [ "BZ3_ERR_MALFORMED_HEADER" ]
19     -5 => [ "BZ3_ERR_TRUNCATED_DATA" ]
20     -6 => [ "BZ3_ERR_DATA_TOO_BIG" ]
21     -7 => [ "BZ3_ERR_INIT" ]
22     [ drop "UNDEFINED_ERR" ]
23   } case internal-error
24 ;
25
26 : KiB ( b -- kib ) 1024 * ;
27 : MiB ( b -- mib ) 1024 * 1024 * ;
28 : validate-block-size ( b -- b ) dup 65 KiB 511 MiB between? 
29   [ invalid-block-size ] unless ;
30 PRIVATE>
31
32 ALIAS: version bz3_version
33 :: compress ( byte-array block-size/f -- byte-array' )
34   byte-array length :> in-size
35   in-size bz3_bound :> out-size
36   out-size <byte-array> :> out
37   block-size/f [ dsize ] unless* validate-block-size
38   byte-array out in-size out-size size_t <ref> bz3_compress
39   dup 0 = [ drop in-size 8 >be out append ] [ throw-internal-error ] if
40 ;
41
42 :: decompress ( byte-array -- byte-array' )
43   byte-array 8 cut-slice :> ( head in )
44   in length :> in-size
45   head be> :> out-size
46   out-size <byte-array> :> out
47   in out in-size out-size size_t <ref> bz3_decompress
48   dup 0 = [ drop out ] [ throw-internal-error ] if
49 ;