initial
This commit is contained in:
35
README.md
35
README.md
@@ -2,6 +2,39 @@
|
|||||||
|
|
||||||
is a high-level wrapper around [zlib](https://zlib.net/).
|
is a high-level wrapper around [zlib](https://zlib.net/).
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
```clojure
|
||||||
|
(load "https://veitheller.de/git/carpentry/zlib.git@0.0.1")
|
||||||
|
```
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
The `ZLib` module provides only two functions
|
The `ZLib` module provides only two functions, `inflate` and `deflate`. These
|
||||||
|
functions work in tandem to provide you with data compression.
|
||||||
|
|
||||||
|
```clojure
|
||||||
|
; deflate returns a Result of either binary data or an error message
|
||||||
|
(let [deflated (ZLib.deflate "mystring")]
|
||||||
|
(match deflated
|
||||||
|
; inflate returns a Result of either a string or an error message
|
||||||
|
(Success bin) (println* &(inflate bin))
|
||||||
|
(Error msg) (IO.errorln &msg)))
|
||||||
|
```
|
||||||
|
|
||||||
|
Because it’s a `Result` type, we can apply combinators to it.
|
||||||
|
|
||||||
|
```clojure
|
||||||
|
(=> (ZLib.deflate "mystring")
|
||||||
|
(Result.and-then &ZLib.inflate)
|
||||||
|
(Result.map-error &(fn [msg] (do (println* &msg) msg)))
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
You can also choose different levels of compression using `deflate-with`. The
|
||||||
|
levels are defined in `ZLib.ZLevel`, and are `NoCompression`, `BestSpeed`,
|
||||||
|
`BestCompression`, and `DefaultCompression`, which is, well, the default.
|
||||||
|
|
||||||
|
<hr/>
|
||||||
|
|
||||||
|
Have fun!
|
||||||
|
172
docs/ZLib.html
Normal file
172
docs/ZLib.html
Normal file
@@ -0,0 +1,172 @@
|
|||||||
|
<!DOCTYPE HTML>
|
||||||
|
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
|
||||||
|
<link rel="stylesheet" href="style.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="content">
|
||||||
|
<div class="logo">
|
||||||
|
<a href="http://github.com/carp-lang/Carp">
|
||||||
|
<img src="logo.png">
|
||||||
|
</a>
|
||||||
|
<div class="title">
|
||||||
|
zlib
|
||||||
|
</div>
|
||||||
|
<div class="index">
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<a href="ZLib.html">
|
||||||
|
ZLib
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<h1>
|
||||||
|
ZLib
|
||||||
|
</h1>
|
||||||
|
<div class="module-description">
|
||||||
|
<p>is a high-level wrapper around <a href="https://zlib.net/">zlib</a>.</p>
|
||||||
|
<h2>Installation</h2>
|
||||||
|
<pre><code class="language-clojure">(load "https://veitheller.de/git/carpentry/zlib.git@0.0.1")
|
||||||
|
</code></pre>
|
||||||
|
<h2>Usage</h2>
|
||||||
|
<p>The <code>ZLib</code> module provides only two functions, <a href="#inflate"><code>inflate</code></a> and
|
||||||
|
<a href="#deflate"><code>deflate</code></a>. These functions work in tandem to provide you with data
|
||||||
|
compression.</p>
|
||||||
|
<pre><code class="language-clojure">; deflate returns a Result of either binary data or an error message
|
||||||
|
(let [deflated (ZLib.deflate "mystring")]
|
||||||
|
(match deflated
|
||||||
|
; inflate returns a Result of either a string or an error message
|
||||||
|
(Success bin) (println* &(inflate bin))
|
||||||
|
(Error msg) (IO.errorln &msg)))
|
||||||
|
</code></pre>
|
||||||
|
<p>Because it’s a <code>Result</code> type, we can apply combinators to it.</p>
|
||||||
|
<pre><code class="language-clojure">(=> (ZLib.deflate "mystring")
|
||||||
|
(Result.and-then &ZLib.inflate)
|
||||||
|
(Result.map-error &(fn [msg] (do (println* &msg) msg)))
|
||||||
|
)
|
||||||
|
</code></pre>
|
||||||
|
<p>You can also choose different levels of compression using <code>inflate-with</code>. The
|
||||||
|
levels are defined in <a href="#ZLevel"><code>ZLib.ZLevel</code></a>, and are <code>NoCompression</code>,
|
||||||
|
<code>BestSpeed</code>, <code>BestCompression</code>, and <code>DefaultCompression</code>, which is, well, the
|
||||||
|
default.</p>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="binder">
|
||||||
|
<a class="anchor" href="#ZBytes">
|
||||||
|
<h3 id="ZBytes">
|
||||||
|
ZBytes
|
||||||
|
</h3>
|
||||||
|
</a>
|
||||||
|
<div class="description">
|
||||||
|
module
|
||||||
|
</div>
|
||||||
|
<p class="sig">
|
||||||
|
Module
|
||||||
|
</p>
|
||||||
|
<span>
|
||||||
|
|
||||||
|
</span>
|
||||||
|
<p class="doc">
|
||||||
|
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="binder">
|
||||||
|
<a class="anchor" href="#ZLevel">
|
||||||
|
<h3 id="ZLevel">
|
||||||
|
ZLevel
|
||||||
|
</h3>
|
||||||
|
</a>
|
||||||
|
<div class="description">
|
||||||
|
module
|
||||||
|
</div>
|
||||||
|
<p class="sig">
|
||||||
|
Module
|
||||||
|
</p>
|
||||||
|
<span>
|
||||||
|
|
||||||
|
</span>
|
||||||
|
<p class="doc">
|
||||||
|
<p>is a type used in conjunction with
|
||||||
|
<a href="#deflate-with"><code>deflate-with</code></a>. It controls the compression level.</p>
|
||||||
|
<p>The constructors are <code>NoCompression</code>, <code>BestSpeed</code>, <code>BestCompression</code>, and
|
||||||
|
<code>DefaultCompression</code>, which is, well, the default.</p>
|
||||||
|
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="binder">
|
||||||
|
<a class="anchor" href="#deflate">
|
||||||
|
<h3 id="deflate">
|
||||||
|
deflate
|
||||||
|
</h3>
|
||||||
|
</a>
|
||||||
|
<div class="description">
|
||||||
|
defn
|
||||||
|
</div>
|
||||||
|
<p class="sig">
|
||||||
|
(λ [&String] (Result ZBytes String))
|
||||||
|
</p>
|
||||||
|
<pre class="args">
|
||||||
|
(deflate s)
|
||||||
|
</pre>
|
||||||
|
<p class="doc">
|
||||||
|
<p>takes a bytes object <code>s</code> and returns a <code>Result</code>.</p>
|
||||||
|
<p>The <code>Result</code> will be a <code>Success</code> containing the deflated bytes if all goes
|
||||||
|
well, and an <code>Error</code> returning an error message otherwise.</p>
|
||||||
|
<p>It is equivalent to calling <a href="#deflate-with"><code>deflate-with</code></a> with
|
||||||
|
<code>(ZLevel.DefaultCompression)</code>.</p>
|
||||||
|
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="binder">
|
||||||
|
<a class="anchor" href="#deflate-with">
|
||||||
|
<h3 id="deflate-with">
|
||||||
|
deflate-with
|
||||||
|
</h3>
|
||||||
|
</a>
|
||||||
|
<div class="description">
|
||||||
|
defn
|
||||||
|
</div>
|
||||||
|
<p class="sig">
|
||||||
|
(λ [&String, ZLevel] (Result ZBytes String))
|
||||||
|
</p>
|
||||||
|
<pre class="args">
|
||||||
|
(deflate-with s level)
|
||||||
|
</pre>
|
||||||
|
<p class="doc">
|
||||||
|
<p>takes a bytes object <code>s</code>, a <code>Zlevel</code> <code>level</code> and returns
|
||||||
|
a <code>Result</code>.</p>
|
||||||
|
<p>The <code>Result</code> will be a <code>Success</code> containing the deflated bytes if all goes
|
||||||
|
well, and an <code>Error</code> returning an error message otherwise.</p>
|
||||||
|
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="binder">
|
||||||
|
<a class="anchor" href="#inflate">
|
||||||
|
<h3 id="inflate">
|
||||||
|
inflate
|
||||||
|
</h3>
|
||||||
|
</a>
|
||||||
|
<div class="description">
|
||||||
|
defn
|
||||||
|
</div>
|
||||||
|
<p class="sig">
|
||||||
|
(λ [ZBytes] (Result String String))
|
||||||
|
</p>
|
||||||
|
<pre class="args">
|
||||||
|
(inflate s)
|
||||||
|
</pre>
|
||||||
|
<p class="doc">
|
||||||
|
<p>takes a bytes object <code>s</code> and returns a <code>Result</code>.</p>
|
||||||
|
<p>The <code>Result</code> will be a <code>Success</code> containing the inflated string if all goes
|
||||||
|
well, and an <code>Error</code> returning an error message otherwise.</p>
|
||||||
|
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
110
docs/style.css
Normal file
110
docs/style.css
Normal file
@@ -0,0 +1,110 @@
|
|||||||
|
html {
|
||||||
|
font-family: "Helvetica", sans-serif;
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: #000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul {
|
||||||
|
list-style-type: none;
|
||||||
|
font-family: "Hasklig", "Lucida Console", monospace;
|
||||||
|
line-height: 1.4em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.module-description {
|
||||||
|
margin-bottom: 3em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content {
|
||||||
|
margin: 3em auto auto auto;
|
||||||
|
width: 80%;
|
||||||
|
max-width: 610px;
|
||||||
|
min-width: 400px
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
margin-bottom: 1em;
|
||||||
|
font-weight: 400;
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
font-weight: 400;
|
||||||
|
margin-bottom: 0em;
|
||||||
|
}
|
||||||
|
|
||||||
|
h3 {
|
||||||
|
margin: 0em;
|
||||||
|
font-weight: 400;
|
||||||
|
}
|
||||||
|
|
||||||
|
.binder {
|
||||||
|
margin: 0em 0em 3.5em 0em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sig {
|
||||||
|
font-family: "Hasklig", "Lucida Console", monospace;
|
||||||
|
margin: 0.5em 0em 0.5em 0em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.args {
|
||||||
|
background-color: #eee;
|
||||||
|
display: inline-block;
|
||||||
|
white-space: normal;
|
||||||
|
margin: 0;
|
||||||
|
margin-bottom: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
code {
|
||||||
|
background-color: #eee;
|
||||||
|
}
|
||||||
|
|
||||||
|
pre {
|
||||||
|
background-color: #eee;
|
||||||
|
overflow-y: scroll;
|
||||||
|
}
|
||||||
|
|
||||||
|
.description {
|
||||||
|
margin-top: 0.3em;
|
||||||
|
font-size: 0.8em;
|
||||||
|
color: #aaa;
|
||||||
|
}
|
||||||
|
|
||||||
|
.huge {
|
||||||
|
font-size: 15em;
|
||||||
|
margin: 0em;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Smaller screens */
|
||||||
|
@media only screen and (max-width: 600px) {
|
||||||
|
.logo {
|
||||||
|
margin: 1em;
|
||||||
|
text-align: left;
|
||||||
|
float: left;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.logo img {
|
||||||
|
display: block;
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
width: 50%;
|
||||||
|
}
|
||||||
|
.content {
|
||||||
|
margin: 0.5em;
|
||||||
|
}
|
||||||
|
.binder {
|
||||||
|
margin: 0em 0em 1.5em 0em;
|
||||||
|
}
|
||||||
|
.sig {
|
||||||
|
font-size: 0.9em;
|
||||||
|
}
|
||||||
|
ul {
|
||||||
|
padding: 0px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.title, .index { display: none; }
|
13
gendocs.carp
Normal file
13
gendocs.carp
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
(load "zlib.carp")
|
||||||
|
|
||||||
|
(defndynamic gendocs []
|
||||||
|
(do
|
||||||
|
(Project.config "title" "zlib")
|
||||||
|
(Project.config "docs-directory" "./docs/")
|
||||||
|
(Project.config "docs-logo" "")
|
||||||
|
(Project.config "docs-styling" "style.css")
|
||||||
|
(Project.config "docs-generate-index" false)
|
||||||
|
(save-docs ZLib)))
|
||||||
|
|
||||||
|
(gendocs)
|
||||||
|
(quit)
|
@@ -6,11 +6,11 @@
|
|||||||
|
|
||||||
(deftest test
|
(deftest test
|
||||||
(assert-true test
|
(assert-true test
|
||||||
(Result.success? &(deflate @"hi"))
|
(Result.success? &(deflate "hi"))
|
||||||
"deflation returns success"
|
"deflation returns success"
|
||||||
)
|
)
|
||||||
(assert-true test
|
(assert-true test
|
||||||
(Result.success? &(inflate (Result.unsafe-from-success (deflate @"hi"))))
|
(Result.success? &(inflate (Result.unsafe-from-success (deflate "hi"))))
|
||||||
"deflation->inflation returns success"
|
"deflation->inflation returns success"
|
||||||
)
|
)
|
||||||
(assert-equal test
|
(assert-equal test
|
||||||
@@ -20,7 +20,7 @@
|
|||||||
)
|
)
|
||||||
(assert-equal test
|
(assert-equal test
|
||||||
&(Result.Success @"hi")
|
&(Result.Success @"hi")
|
||||||
&(inflate (Result.unsafe-from-success (deflate @"hi")))
|
&(inflate (Result.unsafe-from-success (deflate "hi")))
|
||||||
"deflation->inflation works"
|
"deflation->inflation works"
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
67
zlib.carp
67
zlib.carp
@@ -1,14 +1,54 @@
|
|||||||
(relative-include "zlib_helper.h")
|
(relative-include "zlib_helper.h")
|
||||||
(add-cflag "-lz")
|
(add-cflag "-lz")
|
||||||
|
|
||||||
|
|
||||||
|
(doc ZLib "is a high-level wrapper around [zlib](https://zlib.net/).
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
```clojure
|
||||||
|
(load \"https://veitheller.de/git/carpentry/zlib.git@0.0.1\")
|
||||||
|
```
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
The `ZLib` module provides only two functions, [`inflate`](#inflate) and
|
||||||
|
[`deflate`](#deflate). These functions work in tandem to provide you with data
|
||||||
|
compression.
|
||||||
|
|
||||||
|
```clojure
|
||||||
|
; deflate returns a Result of either binary data or an error message
|
||||||
|
(let [deflated (ZLib.deflate \"mystring\")]
|
||||||
|
(match deflated
|
||||||
|
; inflate returns a Result of either a string or an error message
|
||||||
|
(Success bin) (println* &(inflate bin))
|
||||||
|
(Error msg) (IO.errorln &msg)))
|
||||||
|
```
|
||||||
|
|
||||||
|
Because it’s a `Result` type, we can apply combinators to it.
|
||||||
|
|
||||||
|
```clojure
|
||||||
|
(=> (ZLib.deflate \"mystring\")
|
||||||
|
(Result.and-then &ZLib.inflate)
|
||||||
|
(Result.map-error &(fn [msg] (do (println* &msg) msg)))
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
You can also choose different levels of compression using `inflate-with`. The
|
||||||
|
levels are defined in [`ZLib.ZLevel`](#ZLevel), and are `NoCompression`,
|
||||||
|
`BestSpeed`, `BestCompression`, and `DefaultCompression`, which is, well, the
|
||||||
|
default.")
|
||||||
; i tried doing this in carp, but it’s a bit of a pain to wrap the API
|
; i tried doing this in carp, but it’s a bit of a pain to wrap the API
|
||||||
; idiomatically, so for now you’ll only get regular inflation and deflation
|
; idiomatically, so for now you’ll only get regular inflation and deflation
|
||||||
(defmodule ZLib
|
(defmodule ZLib
|
||||||
|
(doc ZBytes "is an opaque bytes type with an associated length.")
|
||||||
(register-type ZBytes [
|
(register-type ZBytes [
|
||||||
len Int
|
len Int
|
||||||
bytes String
|
bytes String
|
||||||
])
|
])
|
||||||
|
|
||||||
|
(private ZRes)
|
||||||
|
(hidden ZRes)
|
||||||
(register-type ZRes)
|
(register-type ZRes)
|
||||||
(defmodule ZRes
|
(defmodule ZRes
|
||||||
(register ok? (Fn [&ZRes] Bool) "ZRes_is_ok")
|
(register ok? (Fn [&ZRes] Bool) "ZRes_is_ok")
|
||||||
@@ -17,6 +57,11 @@
|
|||||||
(register err (Fn [ZRes] String) "ZRes_err")
|
(register err (Fn [ZRes] String) "ZRes_err")
|
||||||
)
|
)
|
||||||
|
|
||||||
|
(doc ZLevel "is a type used in conjunction with
|
||||||
|
[`deflate-with`](#deflate-with). It controls the compression level.
|
||||||
|
|
||||||
|
The constructors are `NoCompression`, `BestSpeed`, `BestCompression`, and
|
||||||
|
`DefaultCompression`, which is, well, the default.")
|
||||||
(deftype ZLevel
|
(deftype ZLevel
|
||||||
(NoCompression [])
|
(NoCompression [])
|
||||||
(BestSpeed [])
|
(BestSpeed [])
|
||||||
@@ -32,19 +77,39 @@
|
|||||||
(BestCompression) 9
|
(BestCompression) 9
|
||||||
(DefaultCompression) -1)))
|
(DefaultCompression) -1)))
|
||||||
|
|
||||||
|
(private inflate-)
|
||||||
|
(hidden inflate-)
|
||||||
(register inflate- (Fn [ZBytes] ZRes) "ZLib_inflate_c")
|
(register inflate- (Fn [ZBytes] ZRes) "ZLib_inflate_c")
|
||||||
|
(doc inflate "takes a bytes object `s` and returns a `Result`.
|
||||||
|
|
||||||
|
The `Result` will be a `Success` containing the inflated string if all goes
|
||||||
|
well, and an `Error` returning an error message otherwise.")
|
||||||
(defn inflate [s]
|
(defn inflate [s]
|
||||||
(let [r (inflate- s)]
|
(let [r (inflate- s)]
|
||||||
(if (ZRes.ok? &r)
|
(if (ZRes.ok? &r)
|
||||||
(Result.Success (ZRes.str r))
|
(Result.Success (ZRes.str r))
|
||||||
(Result.Error (ZRes.err r)))))
|
(Result.Error (ZRes.err r)))))
|
||||||
|
|
||||||
(register deflate- (Fn [String Int] ZRes) "ZLib_deflate_c")
|
(private deflate-)
|
||||||
|
(hidden deflate-)
|
||||||
|
(register deflate- (Fn [&String Int] ZRes) "ZLib_deflate_c")
|
||||||
|
(doc deflate-with "takes a bytes object `s`, a `Zlevel` `level` and returns
|
||||||
|
a `Result`.
|
||||||
|
|
||||||
|
The `Result` will be a `Success` containing the deflated bytes if all goes
|
||||||
|
well, and an `Error` returning an error message otherwise.")
|
||||||
(defn deflate-with [s level]
|
(defn deflate-with [s level]
|
||||||
(let [r (deflate- s (ZLevel.to-int level))]
|
(let [r (deflate- s (ZLevel.to-int level))]
|
||||||
(if (ZRes.ok? &r)
|
(if (ZRes.ok? &r)
|
||||||
(Result.Success (ZRes.bytes r))
|
(Result.Success (ZRes.bytes r))
|
||||||
(Result.Error (ZRes.err r)))))
|
(Result.Error (ZRes.err r)))))
|
||||||
|
|
||||||
|
(doc deflate "takes a bytes object `s` and returns a `Result`.
|
||||||
|
|
||||||
|
The `Result` will be a `Success` containing the deflated bytes if all goes
|
||||||
|
well, and an `Error` returning an error message otherwise.
|
||||||
|
|
||||||
|
It is equivalent to calling [`deflate-with`](#deflate-with) with
|
||||||
|
`(ZLevel.DefaultCompression)`.")
|
||||||
(defn deflate [s] (deflate-with s (ZLevel.DefaultCompression)))
|
(defn deflate [s] (deflate-with s (ZLevel.DefaultCompression)))
|
||||||
)
|
)
|
||||||
|
@@ -134,7 +134,7 @@ err:
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
ZRes ZLib_deflate_c(char* s, int level) {
|
ZRes ZLib_deflate_c(String* s, int level) {
|
||||||
int ret, flush;
|
int ret, flush;
|
||||||
unsigned have;
|
unsigned have;
|
||||||
z_stream strm;
|
z_stream strm;
|
||||||
@@ -142,7 +142,7 @@ ZRes ZLib_deflate_c(char* s, int level) {
|
|||||||
unsigned char in[CHUNK];
|
unsigned char in[CHUNK];
|
||||||
unsigned char out[CHUNK];
|
unsigned char out[CHUNK];
|
||||||
int offs = 0;
|
int offs = 0;
|
||||||
int len = strlen(s);
|
int len = strlen(*s);
|
||||||
ZBytes* bytes = malloc(sizeof(ZBytes));
|
ZBytes* bytes = malloc(sizeof(ZBytes));
|
||||||
bytes->bytes = NULL;
|
bytes->bytes = NULL;
|
||||||
bytes->len = 0;
|
bytes->len = 0;
|
||||||
@@ -158,7 +158,7 @@ ZRes ZLib_deflate_c(char* s, int level) {
|
|||||||
do {
|
do {
|
||||||
strm.avail_in = min(CHUNK, len-offs);
|
strm.avail_in = min(CHUNK, len-offs);
|
||||||
if (strm.avail_in <= 0) break;
|
if (strm.avail_in <= 0) break;
|
||||||
memcpy(in, s+offs, strm.avail_in);
|
memcpy(in, (*s)+offs, strm.avail_in);
|
||||||
offs += strm.avail_in;
|
offs += strm.avail_in;
|
||||||
flush = offs >= len-1 ? Z_FINISH : Z_NO_FLUSH;
|
flush = offs >= len-1 ? Z_FINISH : Z_NO_FLUSH;
|
||||||
strm.next_in = in;
|
strm.next_in = in;
|
||||||
|
Reference in New Issue
Block a user