]> git.proxmox.com Git - libgit2.git/blob - src/zstream.c
Merge pull request #2076 from xtao/fix-zstream
[libgit2.git] / src / zstream.c
1 /*
2 * Copyright (C) the libgit2 contributors. All rights reserved.
3 *
4 * This file is part of libgit2, distributed under the GNU GPL v2 with
5 * a Linking Exception. For full terms see the included COPYING file.
6 */
7
8 #include <zlib.h>
9
10 #include "zstream.h"
11 #include "buffer.h"
12
13 #define BUFFER_SIZE (1024 * 1024)
14
15 static int zstream_seterr(int zerr, git_zstream *zstream)
16 {
17 if (zerr == Z_MEM_ERROR)
18 giterr_set_oom();
19 else if (zstream->msg)
20 giterr_set(GITERR_ZLIB, zstream->msg);
21 else
22 giterr_set(GITERR_ZLIB, "Unknown compression error");
23
24 return -1;
25 }
26
27 int git_zstream_init(git_zstream *zstream)
28 {
29 int zerr;
30
31 if ((zerr = deflateInit(zstream, Z_DEFAULT_COMPRESSION)) != Z_OK)
32 return zstream_seterr(zerr, zstream);
33
34 return 0;
35 }
36
37 ssize_t git_zstream_deflate(void *out, size_t out_len, git_zstream *zstream, const void *in, size_t in_len)
38 {
39 int zerr;
40
41 if ((ssize_t)out_len < 0)
42 out_len = INT_MAX;
43
44 zstream->next_in = (Bytef *)in;
45 zstream->avail_in = in_len;
46 zstream->next_out = out;
47 zstream->avail_out = out_len;
48
49 if ((zerr = deflate(zstream, Z_FINISH)) == Z_STREAM_ERROR)
50 return zstream_seterr(zerr, zstream);
51
52 return (out_len - zstream->avail_out);
53 }
54
55 void git_zstream_reset(git_zstream *zstream)
56 {
57 deflateReset(zstream);
58 }
59
60 void git_zstream_free(git_zstream *zstream)
61 {
62 deflateEnd(zstream);
63 }
64
65 int git_zstream_deflatebuf(git_buf *out, const void *in, size_t in_len)
66 {
67 git_zstream zstream = GIT_ZSTREAM_INIT;
68 size_t out_len;
69 ssize_t written;
70 int error = 0;
71
72 if ((error = git_zstream_init(&zstream)) < 0)
73 return error;
74
75 do {
76 if (out->asize - out->size < BUFFER_SIZE)
77 git_buf_grow(out, out->asize + BUFFER_SIZE);
78
79 out_len = out->asize - out->size;
80
81 if ((written = git_zstream_deflate(out->ptr + out->size, out_len, &zstream, in, in_len)) <= 0)
82 break;
83
84 in = (char *)in + written;
85 in_len -= written;
86 out->size += written;
87 } while (written > 0);
88
89 if (written < 0)
90 error = written;
91
92 git_zstream_free(&zstream);
93 return error;
94 }