]> gitweb.factorcode.org Git - factor.git/commitdiff
compression.zstd: adding a decompress stream frame word
authorJohn Benediktsson <mrjbq7@gmail.com>
Mon, 15 May 2023 20:37:41 +0000 (13:37 -0700)
committerJohn Benediktsson <mrjbq7@gmail.com>
Mon, 15 May 2023 21:21:34 +0000 (14:21 -0700)
basis/compression/zstd/zstd.factor

index a9c437a46df9738fbef00350df749e6336f70dba..58e3c269101977a0db0b6f92678179bc1b89c7ff 100644 (file)
@@ -1,7 +1,10 @@
 ! Copyright (C) 2021 Doug Coleman.
 ! See https://factorcode.org/license.txt for BSD license.
-USING: alien alien.c-types byte-arrays compression.zstd.ffi
-generalizations kernel math math.bitwise sequences ;
+
+USING: accessors alien alien.c-types alien.data byte-arrays
+byte-vectors compression.zstd.ffi destructors generalizations io
+kernel make math math.bitwise sequences ;
+
 IN: compression.zstd
 
 ERROR: zstd-error n str ;
@@ -38,3 +41,48 @@ PRIVATE>
 : zstd-uncompress ( compressed -- byte-array )
     zstd-setup-uncompress-buffers
     [ ZSTD_decompress check-zstd-error ] 4keep 3drop swap head ;
+
+:: zstd-uncompress-stream-frame ( -- byte-array )
+    ZSTD_DStreamInSize :> in-size
+    ZSTD_DStreamOutSize :> out-size
+
+    in-size <byte-vector> :> in
+    out-size <byte-array> :> out
+
+    [
+        [
+            ZSTD_createDCtx &ZSTD_freeDCtx :> dctx
+            0 size_t <ref> :> in-pos
+            0 size_t <ref> :> out-pos
+
+            in [ underlying>> read-into drop length ] [ set-length ] bi
+
+            [
+                dctx
+                out out-size out-pos
+                in in length in-pos
+                ZSTD_decompressStream_simpleArgs check-zstd-error
+
+                out out-pos size_t deref head-slice %
+
+                in-pos size_t deref in-size = [
+                    in [ underlying>> read-into drop length ] [ set-length ] bi
+                    0 in-pos 0 size_t set-alien-value
+                ] when
+
+                zero? [
+                    ! 0 is only seen when a frame is fully
+                    ! decoded *and* fully flushed. But there may
+                    ! be extra input data
+                    f
+                ] [
+                    ! We're not at the end of the frame *or*
+                    ! we're not fully flushed.
+                    in-pos size_t deref in-size =
+                    out-pos size_t deref out-size < and not
+
+                    0 out-pos 0 size_t set-alien-value
+                ] if
+            ] loop
+        ] B{ } make
+    ] with-destructors ;