Annotation of src/usr.bin/cvs/compress.c, Revision 1.4
1.4 ! deraadt 1: /* $OpenBSD: compress.c,v 1.3 2006/04/12 13:42:51 xsa Exp $ */
1.1 xsa 2: /*
3: * Copyright (c) 2005 Jean-Francois Brousseau <jfb@openbsd.org>
4: * All rights reserved.
5: *
6: * Redistribution and use in source and binary forms, with or without
7: * modification, are permitted provided that the following conditions
8: * are met:
9: *
10: * 1. Redistributions of source code must retain the above copyright
11: * notice, this list of conditions and the following disclaimer.
12: * 2. The name of the author may not be used to endorse or promote products
13: * derived from this software without specific prior written permission.
14: *
15: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
16: * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
17: * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
18: * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19: * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20: * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
21: * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
22: * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
23: * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
24: * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25: */
26:
27: #include "includes.h"
28:
29: #include "log.h"
30: #include "cvs.h"
31: #include "compress.h"
32:
33: #define CVS_ZLIB_BUFSIZE 1024
34:
35: struct cvs_zlib_ctx {
36: int z_level;
37: z_stream z_instrm;
38: z_stream z_destrm;
39: };
40:
41:
42: /*
43: * cvs_zlib_newctx()
44: *
45: * Allocate a new ZLIB context structure used for both inflation and deflation
46: * of data with compression level <level>, which must be between 0 and 9. A
47: * value of 0 means no compression, and 9 is the highest level of compression.
48: */
49: CVSZCTX *
50: cvs_zlib_newctx(int level)
51: {
52: CVSZCTX *ctx;
53:
1.4 ! deraadt 54: if (level < 0 || level > 9)
1.1 xsa 55: fatal("invalid compression level %d (must be between 0 and 9)",
56: level);
57:
1.2 ray 58: ctx = xcalloc(1, sizeof(*ctx));
1.1 xsa 59:
60: ctx->z_level = level;
61:
62: ctx->z_instrm.zalloc = Z_NULL;
63: ctx->z_instrm.zfree = Z_NULL;
64: ctx->z_instrm.opaque = Z_NULL;
65: ctx->z_destrm.zalloc = Z_NULL;
66: ctx->z_destrm.zfree = Z_NULL;
67: ctx->z_destrm.opaque = Z_NULL;
68:
1.4 ! deraadt 69: if (inflateInit(&(ctx->z_instrm)) != Z_OK ||
! 70: deflateInit(&(ctx->z_destrm), level) != Z_OK)
1.1 xsa 71: fatal("failed to initialize zlib streams");
72:
73: return (ctx);
74: }
75:
76:
77: /*
78: * cvs_zlib_free()
79: *
80: * Free a ZLIB context previously allocated with cvs_zlib_newctx().
81: */
82: void
83: cvs_zlib_free(CVSZCTX *ctx)
84: {
85: if (ctx != NULL) {
86: (void)inflateEnd(&(ctx->z_instrm));
87: (void)deflateEnd(&(ctx->z_destrm));
88: xfree(ctx);
89: }
90: }
91:
92: /*
93: * cvs_zlib_inflate()
94: *
95: * Decompress the first <slen> bytes of <src> using the zlib context <ctx> and
96: * store the resulting data in <dst>.
97: * Returns the number of bytes inflated on success, or -1 on failure.
98: */
99: int
100: cvs_zlib_inflate(CVSZCTX *ctx, BUF *dst, u_char *src, size_t slen)
101: {
102: int bytes, ret;
103: u_char buf[CVS_ZLIB_BUFSIZE];
104:
105: bytes = 0;
106: cvs_buf_empty(dst);
1.3 xsa 107: if (inflateReset(&(ctx->z_instrm)) == Z_STREAM_ERROR)
108: fatal("inflate error: %s", ctx->z_instrm.msg);
1.1 xsa 109:
110: ctx->z_instrm.next_in = src;
111: ctx->z_instrm.avail_in = slen;
112:
113: do {
114: ctx->z_instrm.next_out = buf;
115: ctx->z_instrm.avail_out = sizeof(buf);
116:
117: ret = inflate(&(ctx->z_instrm), Z_FINISH);
1.4 ! deraadt 118: if (ret == Z_MEM_ERROR || ret == Z_BUF_ERROR ||
! 119: ret == Z_STREAM_ERROR || ret == Z_DATA_ERROR)
1.1 xsa 120: fatal("inflate error: %s", ctx->z_instrm.msg);
121:
122: cvs_buf_append(dst, buf, ctx->z_instrm.avail_out);
123: bytes += sizeof(buf) - ctx->z_instrm.avail_out;
124:
125: } while (ret != Z_STREAM_END);
126:
127: return (bytes);
128: }
129:
130: /*
131: * cvs_zlib_deflate()
132: *
133: * Compress the first <slen> bytes of <src> using the zlib context <ctx> and
134: * store the resulting data in <dst>.
135: * Returns the number of bytes deflated on success, or -1 on failure.
136: */
137: int
138: cvs_zlib_deflate(CVSZCTX *ctx, BUF *dst, u_char *src, size_t slen)
139: {
140: int bytes, ret;
141: u_char buf[CVS_ZLIB_BUFSIZE];
142:
143: bytes = 0;
144: cvs_buf_empty(dst);
1.3 xsa 145: if (deflateReset(&(ctx->z_destrm)) == Z_STREAM_ERROR)
146: fatal("deflate error: %s", ctx->z_destrm.msg);
1.1 xsa 147:
148: ctx->z_destrm.next_in = src;
149: ctx->z_destrm.avail_in = slen;
150:
151: do {
152: ctx->z_destrm.next_out = buf;
153: ctx->z_destrm.avail_out = sizeof(buf);
154: ret = deflate(&(ctx->z_destrm), Z_FINISH);
1.4 ! deraadt 155: if (ret == Z_STREAM_ERROR || ret == Z_BUF_ERROR)
1.1 xsa 156: fatal("deflate error: %s", ctx->z_destrm.msg);
157:
158: if (cvs_buf_append(dst, buf,
159: sizeof(buf) - ctx->z_destrm.avail_out) < 0)
160: return (-1);
161: bytes += sizeof(buf) - ctx->z_destrm.avail_out;
162: } while (ret != Z_STREAM_END);
163:
164: return (bytes);
165: }