Skip to content

Commit

Permalink
Use <byte-vector> instead of <string> for compress/uncompress
Browse files Browse the repository at this point in the history
  • Loading branch information
fraya committed Oct 22, 2024
1 parent 695d131 commit 2e51f47
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 46 deletions.
10 changes: 3 additions & 7 deletions source/library.dylan
Original file line number Diff line number Diff line change
Expand Up @@ -78,16 +78,11 @@ define module zlib-binding
z-compress,
z-compress-2,
z-compress-bound,
z-uncompress;
z-uncompress,
z-uncompress-2;
end module;

define module zlib
create
$z-no-compression,
$z-best-speed,
$z-best-compression,
$z-default-compression;

create
<zlib-error>,
<zlib-errno-error>,
Expand All @@ -105,6 +100,7 @@ end module;
define module zlib-impl
use common-dylan;
use c-ffi;
use byte-vector;
use zlib;
use zlib-binding;

Expand Down
20 changes: 11 additions & 9 deletions source/zlib-binding.dylan
Original file line number Diff line number Diff line change
@@ -1,20 +1,22 @@
module: zlib-binding
// Utility functions
define simple-C-mapped-subtype <C-buffer-offset> (<C-void*>)
export-map <machine-word>, export-function: identity;
end;

define C-function z-compress
parameter destination :: <C-string>;
parameter destination :: <C-buffer-offset>;
parameter destination-length :: <C-unsigned-long*>;
parameter source :: <C-string>;
parameter source :: <C-buffer-offset>;
parameter source-length :: <C-unsigned-long>;
result return-code :: <C-int>;
c-name: "compress"
end;

define C-function z-compress-2
parameter destination :: <C-string>;
parameter destination :: <C-buffer-offset>;
parameter destination-length :: <C-unsigned-long*>;
parameter source :: <C-string>;
parameter source :: <C-buffer-offset>;
parameter source-length :: <C-unsigned-long>;
parameter level :: <C-int>;
result return-code :: <C-int>;
Expand All @@ -28,18 +30,18 @@ define C-function z-compress-bound
end;

define C-function z-uncompress
parameter destination :: <C-string>;
parameter destination :: <C-buffer-offset>;
parameter destination-length :: <C-unsigned-long*>;
parameter source :: <C-string>;
parameter source :: <C-buffer-offset>;
parameter source-length :: <C-unsigned-long>;
result return-code :: <C-int>;
c-name: "uncompress"
end;

define C-function z-uncompress-2
parameter destination :: <C-string>;
parameter destination :: <C-buffer-offset>;
parameter destination-length :: <C-unsigned-long*>;
parameter source :: <C-string>;
parameter source :: <C-buffer-offset>;
parameter source-length :: <C-unsigned-long*>;
result return-code :: <C-int>;
c-name: "uncompress2"
Expand Down
54 changes: 25 additions & 29 deletions source/zlib.dylan
Original file line number Diff line number Diff line change
Expand Up @@ -34,43 +34,39 @@ define function zlib-abort
end zlib-abort;

define function zlib-compress
(string :: <string>, #key level :: <integer> = 6)
=> (compressed :: <string>)
let string-size = string.size;
let estimated-size = z-compress-bound(string-size);
let compressed = make(<string>, size: estimated-size);
let actual-size = make(<C-unsigned-long*>);
(data, #key level :: <integer> = $z-default-compression)
=> (compressed :: <byte-vector>)
let estimated-size = z-compress-bound(data.size);
let buffer = make(<byte-vector>, size: estimated-size);
let actual-size = make(<C-unsigned-long*>);
actual-size.pointer-value := estimated-size;
let destination = byte-storage-address(buffer);
let source = byte-storage-address(data);

let status-code = z-compress-2(compressed,
actual-size,
string,
string-size,
level);

unless (status-code = $z-ok)
zlib-abort(status-code)
let status = z-compress-2(destination, actual-size, source, data.size, level);
unless (status = $z-ok)
zlib-abort(status)
end;

copy-sequence(compressed, end: actual-size.pointer-value);
let compressed-size = actual-size.pointer-value;
let compressed = make(<byte-vector>, size: compressed-size);
copy-bytes(compressed, 0, buffer, 0, compressed-size);
compressed
end zlib-compress;

define function zlib-uncompress
(compressed :: <string>, length :: <integer>)
=> (string :: <string>)
// allocate uncompressed string of expected 'length'
let string = make(<string>, size: length);
let string-size = make(<C-unsigned-long*>);
string-size.pointer-value := length;

let status-code = z-uncompress(string,
string-size,
compressed,
compressed.size);
(compressed :: <byte-vector>, length :: <integer>)
=> (uncompressed :: <byte-vector>)
let uncompressed = make(<byte-vector>, size: length);
let uncompressed-size = make(<C-unsigned-long*>);
uncompressed-size.pointer-value := length;
let destination = byte-storage-address(uncompressed);
let source = byte-storage-address(compressed);

unless (status-code = $z-ok)
zlib-abort(status-code)
let status = z-uncompress(destination, uncompressed-size, source, compressed.size);
unless (status = $z-ok)
zlib-abort(status)
end;

string
uncompressed
end zlib-uncompress;
2 changes: 1 addition & 1 deletion tests/zlib-test-suite.dylan
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ define test compress-uncompress-idempotence-test ()
let phrase = "A horse, a horse, my kingdom for a horse";
let compressed = zlib-compress(phrase);
let uncompressed = zlib-uncompress(compressed, phrase.size);
assert-equal(phrase, uncompressed)
assert-equal(phrase, as(<string>, uncompressed))
end test;

define test compression-level-test ()
Expand Down

0 comments on commit 2e51f47

Please sign in to comment.