aboutsummaryrefslogtreecommitdiff
path: root/zlib.c
blob: 8f19d2fe388b2a75699d873618da05a15dd4e2a0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
/*
 * zlib wrappers to make sure we don't silently miss errors
 * at init time.
 */
#include "cache.h"

static const char *zerr_to_string(int status)
{
	switch (status) {
	case Z_MEM_ERROR:
		return "out of memory";
	case Z_VERSION_ERROR:
		return "wrong version";
	case Z_NEED_DICT:
		return "needs dictionary";
	case Z_DATA_ERROR:
		return "data stream error";
	case Z_STREAM_ERROR:
		return "stream consistency error";
	default:
		return "unknown error";
	}
}

void git_inflate_init(z_streamp strm)
{
	int status = inflateInit(strm);

	if (status == Z_OK)
		return;
	die("inflateInit: %s (%s)", zerr_to_string(status),
	    strm->msg ? strm->msg : "no message");
}

void git_inflate_init_gzip_only(z_streamp strm)
{
	/*
	 * Use default 15 bits, +16 is to accept only gzip and to
	 * yield Z_DATA_ERROR when fed zlib format.
	 */
	const int windowBits = 15 + 16;
	int status = inflateInit2(strm, windowBits);

	if (status == Z_OK)
		return;
	die("inflateInit2: %s (%s)", zerr_to_string(status),
	    strm->msg ? strm->msg : "no message");
}

void git_inflate_end(z_streamp strm)
{
	int status = inflateEnd(strm);

	if (status == Z_OK)
		return;
	error("inflateEnd: %s (%s)", zerr_to_string(status),
	      strm->msg ? strm->msg : "no message");
}

int git_inflate(z_streamp strm, int flush)
{
	int status = inflate(strm, flush);

	switch (status) {
	/* Z_BUF_ERROR: normal, needs more space in the output buffer */
	case Z_BUF_ERROR:
	case Z_OK:
	case Z_STREAM_END:
		return status;

	case Z_MEM_ERROR:
		die("inflate: out of memory");
	default:
		break;
	}
	error("inflate: %s (%s)", zerr_to_string(status),
	      strm->msg ? strm->msg : "no message");
	return status;
}

#if defined(NO_DEFLATE_BOUND) || ZLIB_VERNUM < 0x1200
#define deflateBound(c,s)  ((s) + (((s) + 7) >> 3) + (((s) + 63) >> 6) + 11)
#endif

unsigned long git_deflate_bound(z_streamp strm, unsigned long size)
{
	return deflateBound(strm, size);
}

void git_deflate_init(z_streamp strm, int level)
{
	int status = deflateInit(strm, level);

	if (status == Z_OK)
		return;
	die("deflateInit: %s (%s)", zerr_to_string(status),
	    strm->msg ? strm->msg : "no message");
}

void git_deflate_init_gzip(z_streamp strm, int level)
{
	/*
	 * Use default 15 bits, +16 is to generate gzip header/trailer
	 * instead of the zlib wrapper.
	 */
	const int windowBits = 15 + 16;
	int status = deflateInit2(strm, level,
				  Z_DEFLATED, windowBits,
				  8, Z_DEFAULT_STRATEGY);
	if (status == Z_OK)
		return;
	die("deflateInit2: %s (%s)", zerr_to_string(status),
	    strm->msg ? strm->msg : "no message");
}

void git_deflate_end(z_streamp strm)
{
	int status = deflateEnd(strm);

	if (status == Z_OK)
		return;
	error("deflateEnd: %s (%s)", zerr_to_string(status),
	      strm->msg ? strm->msg : "no message");
}

int git_deflate_end_gently(z_streamp strm)
{
	return deflateEnd(strm);
}

int git_deflate(z_streamp strm, int flush)
{
	int status = deflate(strm, flush);

	switch (status) {
	/* Z_BUF_ERROR: normal, needs more space in the output buffer */
	case Z_BUF_ERROR:
	case Z_OK:
	case Z_STREAM_END:
		return status;

	case Z_MEM_ERROR:
		die("deflate: out of memory");
	default:
		break;
	}
	error("deflate: %s (%s)", zerr_to_string(status),
	      strm->msg ? strm->msg : "no message");
	return status;
}