ยปCore Development>Code coverage>Modules/zlib/gzwrite.c

Python code coverage for Modules/zlib/gzwrite.c

#countcontent
1n/a/* gzwrite.c -- zlib functions for writing gzip files
2n/a * Copyright (C) 2004-2017 Mark Adler
3n/a * For conditions of distribution and use, see copyright notice in zlib.h
4n/a */
5n/a
6n/a#include "gzguts.h"
7n/a
8n/a/* Local functions */
9n/alocal int gz_init OF((gz_statep));
10n/alocal int gz_comp OF((gz_statep, int));
11n/alocal int gz_zero OF((gz_statep, z_off64_t));
12n/alocal z_size_t gz_write OF((gz_statep, voidpc, z_size_t));
13n/a
14n/a/* Initialize state for writing a gzip file. Mark initialization by setting
15n/a state->size to non-zero. Return -1 on a memory allocation failure, or 0 on
16n/a success. */
17n/alocal int gz_init(state)
18n/a gz_statep state;
19n/a{
20n/a int ret;
21n/a z_streamp strm = &(state->strm);
22n/a
23n/a /* allocate input buffer (double size for gzprintf) */
24n/a state->in = (unsigned char *)malloc(state->want << 1);
25n/a if (state->in == NULL) {
26n/a gz_error(state, Z_MEM_ERROR, "out of memory");
27n/a return -1;
28n/a }
29n/a
30n/a /* only need output buffer and deflate state if compressing */
31n/a if (!state->direct) {
32n/a /* allocate output buffer */
33n/a state->out = (unsigned char *)malloc(state->want);
34n/a if (state->out == NULL) {
35n/a free(state->in);
36n/a gz_error(state, Z_MEM_ERROR, "out of memory");
37n/a return -1;
38n/a }
39n/a
40n/a /* allocate deflate memory, set up for gzip compression */
41n/a strm->zalloc = Z_NULL;
42n/a strm->zfree = Z_NULL;
43n/a strm->opaque = Z_NULL;
44n/a ret = deflateInit2(strm, state->level, Z_DEFLATED,
45n/a MAX_WBITS + 16, DEF_MEM_LEVEL, state->strategy);
46n/a if (ret != Z_OK) {
47n/a free(state->out);
48n/a free(state->in);
49n/a gz_error(state, Z_MEM_ERROR, "out of memory");
50n/a return -1;
51n/a }
52n/a strm->next_in = NULL;
53n/a }
54n/a
55n/a /* mark state as initialized */
56n/a state->size = state->want;
57n/a
58n/a /* initialize write buffer if compressing */
59n/a if (!state->direct) {
60n/a strm->avail_out = state->size;
61n/a strm->next_out = state->out;
62n/a state->x.next = strm->next_out;
63n/a }
64n/a return 0;
65n/a}
66n/a
67n/a/* Compress whatever is at avail_in and next_in and write to the output file.
68n/a Return -1 if there is an error writing to the output file or if gz_init()
69n/a fails to allocate memory, otherwise 0. flush is assumed to be a valid
70n/a deflate() flush value. If flush is Z_FINISH, then the deflate() state is
71n/a reset to start a new gzip stream. If gz->direct is true, then simply write
72n/a to the output file without compressing, and ignore flush. */
73n/alocal int gz_comp(state, flush)
74n/a gz_statep state;
75n/a int flush;
76n/a{
77n/a int ret, writ;
78n/a unsigned have, put, max = ((unsigned)-1 >> 2) + 1;
79n/a z_streamp strm = &(state->strm);
80n/a
81n/a /* allocate memory if this is the first time through */
82n/a if (state->size == 0 && gz_init(state) == -1)
83n/a return -1;
84n/a
85n/a /* write directly if requested */
86n/a if (state->direct) {
87n/a while (strm->avail_in) {
88n/a put = strm->avail_in > max ? max : strm->avail_in;
89n/a writ = write(state->fd, strm->next_in, put);
90n/a if (writ < 0) {
91n/a gz_error(state, Z_ERRNO, zstrerror());
92n/a return -1;
93n/a }
94n/a strm->avail_in -= (unsigned)writ;
95n/a strm->next_in += writ;
96n/a }
97n/a return 0;
98n/a }
99n/a
100n/a /* run deflate() on provided input until it produces no more output */
101n/a ret = Z_OK;
102n/a do {
103n/a /* write out current buffer contents if full, or if flushing, but if
104n/a doing Z_FINISH then don't write until we get to Z_STREAM_END */
105n/a if (strm->avail_out == 0 || (flush != Z_NO_FLUSH &&
106n/a (flush != Z_FINISH || ret == Z_STREAM_END))) {
107n/a while (strm->next_out > state->x.next) {
108n/a put = strm->next_out - state->x.next > (int)max ? max :
109n/a (unsigned)(strm->next_out - state->x.next);
110n/a writ = write(state->fd, state->x.next, put);
111n/a if (writ < 0) {
112n/a gz_error(state, Z_ERRNO, zstrerror());
113n/a return -1;
114n/a }
115n/a state->x.next += writ;
116n/a }
117n/a if (strm->avail_out == 0) {
118n/a strm->avail_out = state->size;
119n/a strm->next_out = state->out;
120n/a state->x.next = state->out;
121n/a }
122n/a }
123n/a
124n/a /* compress */
125n/a have = strm->avail_out;
126n/a ret = deflate(strm, flush);
127n/a if (ret == Z_STREAM_ERROR) {
128n/a gz_error(state, Z_STREAM_ERROR,
129n/a "internal error: deflate stream corrupt");
130n/a return -1;
131n/a }
132n/a have -= strm->avail_out;
133n/a } while (have);
134n/a
135n/a /* if that completed a deflate stream, allow another to start */
136n/a if (flush == Z_FINISH)
137n/a deflateReset(strm);
138n/a
139n/a /* all done, no errors */
140n/a return 0;
141n/a}
142n/a
143n/a/* Compress len zeros to output. Return -1 on a write error or memory
144n/a allocation failure by gz_comp(), or 0 on success. */
145n/alocal int gz_zero(state, len)
146n/a gz_statep state;
147n/a z_off64_t len;
148n/a{
149n/a int first;
150n/a unsigned n;
151n/a z_streamp strm = &(state->strm);
152n/a
153n/a /* consume whatever's left in the input buffer */
154n/a if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1)
155n/a return -1;
156n/a
157n/a /* compress len zeros (len guaranteed > 0) */
158n/a first = 1;
159n/a while (len) {
160n/a n = GT_OFF(state->size) || (z_off64_t)state->size > len ?
161n/a (unsigned)len : state->size;
162n/a if (first) {
163n/a memset(state->in, 0, n);
164n/a first = 0;
165n/a }
166n/a strm->avail_in = n;
167n/a strm->next_in = state->in;
168n/a state->x.pos += n;
169n/a if (gz_comp(state, Z_NO_FLUSH) == -1)
170n/a return -1;
171n/a len -= n;
172n/a }
173n/a return 0;
174n/a}
175n/a
176n/a/* Write len bytes from buf to file. Return the number of bytes written. If
177n/a the returned value is less than len, then there was an error. */
178n/alocal z_size_t gz_write(state, buf, len)
179n/a gz_statep state;
180n/a voidpc buf;
181n/a z_size_t len;
182n/a{
183n/a z_size_t put = len;
184n/a
185n/a /* if len is zero, avoid unnecessary operations */
186n/a if (len == 0)
187n/a return 0;
188n/a
189n/a /* allocate memory if this is the first time through */
190n/a if (state->size == 0 && gz_init(state) == -1)
191n/a return 0;
192n/a
193n/a /* check for seek request */
194n/a if (state->seek) {
195n/a state->seek = 0;
196n/a if (gz_zero(state, state->skip) == -1)
197n/a return 0;
198n/a }
199n/a
200n/a /* for small len, copy to input buffer, otherwise compress directly */
201n/a if (len < state->size) {
202n/a /* copy to input buffer, compress when full */
203n/a do {
204n/a unsigned have, copy;
205n/a
206n/a if (state->strm.avail_in == 0)
207n/a state->strm.next_in = state->in;
208n/a have = (unsigned)((state->strm.next_in + state->strm.avail_in) -
209n/a state->in);
210n/a copy = state->size - have;
211n/a if (copy > len)
212n/a copy = len;
213n/a memcpy(state->in + have, buf, copy);
214n/a state->strm.avail_in += copy;
215n/a state->x.pos += copy;
216n/a buf = (const char *)buf + copy;
217n/a len -= copy;
218n/a if (len && gz_comp(state, Z_NO_FLUSH) == -1)
219n/a return 0;
220n/a } while (len);
221n/a }
222n/a else {
223n/a /* consume whatever's left in the input buffer */
224n/a if (state->strm.avail_in && gz_comp(state, Z_NO_FLUSH) == -1)
225n/a return 0;
226n/a
227n/a /* directly compress user buffer to file */
228n/a state->strm.next_in = (z_const Bytef *)buf;
229n/a do {
230n/a unsigned n = (unsigned)-1;
231n/a if (n > len)
232n/a n = len;
233n/a state->strm.avail_in = n;
234n/a state->x.pos += n;
235n/a if (gz_comp(state, Z_NO_FLUSH) == -1)
236n/a return 0;
237n/a len -= n;
238n/a } while (len);
239n/a }
240n/a
241n/a /* input was all buffered or compressed */
242n/a return put;
243n/a}
244n/a
245n/a/* -- see zlib.h -- */
246n/aint ZEXPORT gzwrite(file, buf, len)
247n/a gzFile file;
248n/a voidpc buf;
249n/a unsigned len;
250n/a{
251n/a gz_statep state;
252n/a
253n/a /* get internal structure */
254n/a if (file == NULL)
255n/a return 0;
256n/a state = (gz_statep)file;
257n/a
258n/a /* check that we're writing and that there's no error */
259n/a if (state->mode != GZ_WRITE || state->err != Z_OK)
260n/a return 0;
261n/a
262n/a /* since an int is returned, make sure len fits in one, otherwise return
263n/a with an error (this avoids a flaw in the interface) */
264n/a if ((int)len < 0) {
265n/a gz_error(state, Z_DATA_ERROR, "requested length does not fit in int");
266n/a return 0;
267n/a }
268n/a
269n/a /* write len bytes from buf (the return value will fit in an int) */
270n/a return (int)gz_write(state, buf, len);
271n/a}
272n/a
273n/a/* -- see zlib.h -- */
274n/az_size_t ZEXPORT gzfwrite(buf, size, nitems, file)
275n/a voidpc buf;
276n/a z_size_t size;
277n/a z_size_t nitems;
278n/a gzFile file;
279n/a{
280n/a z_size_t len;
281n/a gz_statep state;
282n/a
283n/a /* get internal structure */
284n/a if (file == NULL)
285n/a return 0;
286n/a state = (gz_statep)file;
287n/a
288n/a /* check that we're writing and that there's no error */
289n/a if (state->mode != GZ_WRITE || state->err != Z_OK)
290n/a return 0;
291n/a
292n/a /* compute bytes to read -- error on overflow */
293n/a len = nitems * size;
294n/a if (size && len / size != nitems) {
295n/a gz_error(state, Z_STREAM_ERROR, "request does not fit in a size_t");
296n/a return 0;
297n/a }
298n/a
299n/a /* write len bytes to buf, return the number of full items written */
300n/a return len ? gz_write(state, buf, len) / size : 0;
301n/a}
302n/a
303n/a/* -- see zlib.h -- */
304n/aint ZEXPORT gzputc(file, c)
305n/a gzFile file;
306n/a int c;
307n/a{
308n/a unsigned have;
309n/a unsigned char buf[1];
310n/a gz_statep state;
311n/a z_streamp strm;
312n/a
313n/a /* get internal structure */
314n/a if (file == NULL)
315n/a return -1;
316n/a state = (gz_statep)file;
317n/a strm = &(state->strm);
318n/a
319n/a /* check that we're writing and that there's no error */
320n/a if (state->mode != GZ_WRITE || state->err != Z_OK)
321n/a return -1;
322n/a
323n/a /* check for seek request */
324n/a if (state->seek) {
325n/a state->seek = 0;
326n/a if (gz_zero(state, state->skip) == -1)
327n/a return -1;
328n/a }
329n/a
330n/a /* try writing to input buffer for speed (state->size == 0 if buffer not
331n/a initialized) */
332n/a if (state->size) {
333n/a if (strm->avail_in == 0)
334n/a strm->next_in = state->in;
335n/a have = (unsigned)((strm->next_in + strm->avail_in) - state->in);
336n/a if (have < state->size) {
337n/a state->in[have] = (unsigned char)c;
338n/a strm->avail_in++;
339n/a state->x.pos++;
340n/a return c & 0xff;
341n/a }
342n/a }
343n/a
344n/a /* no room in buffer or not initialized, use gz_write() */
345n/a buf[0] = (unsigned char)c;
346n/a if (gz_write(state, buf, 1) != 1)
347n/a return -1;
348n/a return c & 0xff;
349n/a}
350n/a
351n/a/* -- see zlib.h -- */
352n/aint ZEXPORT gzputs(file, str)
353n/a gzFile file;
354n/a const char *str;
355n/a{
356n/a int ret;
357n/a z_size_t len;
358n/a gz_statep state;
359n/a
360n/a /* get internal structure */
361n/a if (file == NULL)
362n/a return -1;
363n/a state = (gz_statep)file;
364n/a
365n/a /* check that we're writing and that there's no error */
366n/a if (state->mode != GZ_WRITE || state->err != Z_OK)
367n/a return -1;
368n/a
369n/a /* write string */
370n/a len = strlen(str);
371n/a ret = gz_write(state, str, len);
372n/a return ret == 0 && len != 0 ? -1 : ret;
373n/a}
374n/a
375n/a#if defined(STDC) || defined(Z_HAVE_STDARG_H)
376n/a#include <stdarg.h>
377n/a
378n/a/* -- see zlib.h -- */
379n/aint ZEXPORTVA gzvprintf(gzFile file, const char *format, va_list va)
380n/a{
381n/a int len;
382n/a unsigned left;
383n/a char *next;
384n/a gz_statep state;
385n/a z_streamp strm;
386n/a
387n/a /* get internal structure */
388n/a if (file == NULL)
389n/a return Z_STREAM_ERROR;
390n/a state = (gz_statep)file;
391n/a strm = &(state->strm);
392n/a
393n/a /* check that we're writing and that there's no error */
394n/a if (state->mode != GZ_WRITE || state->err != Z_OK)
395n/a return Z_STREAM_ERROR;
396n/a
397n/a /* make sure we have some buffer space */
398n/a if (state->size == 0 && gz_init(state) == -1)
399n/a return state->err;
400n/a
401n/a /* check for seek request */
402n/a if (state->seek) {
403n/a state->seek = 0;
404n/a if (gz_zero(state, state->skip) == -1)
405n/a return state->err;
406n/a }
407n/a
408n/a /* do the printf() into the input buffer, put length in len -- the input
409n/a buffer is double-sized just for this function, so there is guaranteed to
410n/a be state->size bytes available after the current contents */
411n/a if (strm->avail_in == 0)
412n/a strm->next_in = state->in;
413n/a next = (char *)(state->in + (strm->next_in - state->in) + strm->avail_in);
414n/a next[state->size - 1] = 0;
415n/a#ifdef NO_vsnprintf
416n/a# ifdef HAS_vsprintf_void
417n/a (void)vsprintf(next, format, va);
418n/a for (len = 0; len < state->size; len++)
419n/a if (next[len] == 0) break;
420n/a# else
421n/a len = vsprintf(next, format, va);
422n/a# endif
423n/a#else
424n/a# ifdef HAS_vsnprintf_void
425n/a (void)vsnprintf(next, state->size, format, va);
426n/a len = strlen(next);
427n/a# else
428n/a len = vsnprintf(next, state->size, format, va);
429n/a# endif
430n/a#endif
431n/a
432n/a /* check that printf() results fit in buffer */
433n/a if (len == 0 || (unsigned)len >= state->size || next[state->size - 1] != 0)
434n/a return 0;
435n/a
436n/a /* update buffer and position, compress first half if past that */
437n/a strm->avail_in += (unsigned)len;
438n/a state->x.pos += len;
439n/a if (strm->avail_in >= state->size) {
440n/a left = strm->avail_in - state->size;
441n/a strm->avail_in = state->size;
442n/a if (gz_comp(state, Z_NO_FLUSH) == -1)
443n/a return state->err;
444n/a memcpy(state->in, state->in + state->size, left);
445n/a strm->next_in = state->in;
446n/a strm->avail_in = left;
447n/a }
448n/a return len;
449n/a}
450n/a
451n/aint ZEXPORTVA gzprintf(gzFile file, const char *format, ...)
452n/a{
453n/a va_list va;
454n/a int ret;
455n/a
456n/a va_start(va, format);
457n/a ret = gzvprintf(file, format, va);
458n/a va_end(va);
459n/a return ret;
460n/a}
461n/a
462n/a#else /* !STDC && !Z_HAVE_STDARG_H */
463n/a
464n/a/* -- see zlib.h -- */
465n/aint ZEXPORTVA gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
466n/a a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)
467n/a gzFile file;
468n/a const char *format;
469n/a int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
470n/a a11, a12, a13, a14, a15, a16, a17, a18, a19, a20;
471n/a{
472n/a unsigned len, left;
473n/a char *next;
474n/a gz_statep state;
475n/a z_streamp strm;
476n/a
477n/a /* get internal structure */
478n/a if (file == NULL)
479n/a return Z_STREAM_ERROR;
480n/a state = (gz_statep)file;
481n/a strm = &(state->strm);
482n/a
483n/a /* check that can really pass pointer in ints */
484n/a if (sizeof(int) != sizeof(void *))
485n/a return Z_STREAM_ERROR;
486n/a
487n/a /* check that we're writing and that there's no error */
488n/a if (state->mode != GZ_WRITE || state->err != Z_OK)
489n/a return Z_STREAM_ERROR;
490n/a
491n/a /* make sure we have some buffer space */
492n/a if (state->size == 0 && gz_init(state) == -1)
493n/a return state->error;
494n/a
495n/a /* check for seek request */
496n/a if (state->seek) {
497n/a state->seek = 0;
498n/a if (gz_zero(state, state->skip) == -1)
499n/a return state->error;
500n/a }
501n/a
502n/a /* do the printf() into the input buffer, put length in len -- the input
503n/a buffer is double-sized just for this function, so there is guaranteed to
504n/a be state->size bytes available after the current contents */
505n/a if (strm->avail_in == 0)
506n/a strm->next_in = state->in;
507n/a next = (char *)(strm->next_in + strm->avail_in);
508n/a next[state->size - 1] = 0;
509n/a#ifdef NO_snprintf
510n/a# ifdef HAS_sprintf_void
511n/a sprintf(next, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12,
512n/a a13, a14, a15, a16, a17, a18, a19, a20);
513n/a for (len = 0; len < size; len++)
514n/a if (next[len] == 0)
515n/a break;
516n/a# else
517n/a len = sprintf(next, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11,
518n/a a12, a13, a14, a15, a16, a17, a18, a19, a20);
519n/a# endif
520n/a#else
521n/a# ifdef HAS_snprintf_void
522n/a snprintf(next, state->size, format, a1, a2, a3, a4, a5, a6, a7, a8, a9,
523n/a a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
524n/a len = strlen(next);
525n/a# else
526n/a len = snprintf(next, state->size, format, a1, a2, a3, a4, a5, a6, a7, a8,
527n/a a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
528n/a# endif
529n/a#endif
530n/a
531n/a /* check that printf() results fit in buffer */
532n/a if (len == 0 || len >= state->size || next[state->size - 1] != 0)
533n/a return 0;
534n/a
535n/a /* update buffer and position, compress first half if past that */
536n/a strm->avail_in += len;
537n/a state->x.pos += len;
538n/a if (strm->avail_in >= state->size) {
539n/a left = strm->avail_in - state->size;
540n/a strm->avail_in = state->size;
541n/a if (gz_comp(state, Z_NO_FLUSH) == -1)
542n/a return state->err;
543n/a memcpy(state->in, state->in + state->size, left);
544n/a strm->next_in = state->in;
545n/a strm->avail_in = left;
546n/a }
547n/a return (int)len;
548n/a}
549n/a
550n/a#endif
551n/a
552n/a/* -- see zlib.h -- */
553n/aint ZEXPORT gzflush(file, flush)
554n/a gzFile file;
555n/a int flush;
556n/a{
557n/a gz_statep state;
558n/a
559n/a /* get internal structure */
560n/a if (file == NULL)
561n/a return Z_STREAM_ERROR;
562n/a state = (gz_statep)file;
563n/a
564n/a /* check that we're writing and that there's no error */
565n/a if (state->mode != GZ_WRITE || state->err != Z_OK)
566n/a return Z_STREAM_ERROR;
567n/a
568n/a /* check flush parameter */
569n/a if (flush < 0 || flush > Z_FINISH)
570n/a return Z_STREAM_ERROR;
571n/a
572n/a /* check for seek request */
573n/a if (state->seek) {
574n/a state->seek = 0;
575n/a if (gz_zero(state, state->skip) == -1)
576n/a return state->err;
577n/a }
578n/a
579n/a /* compress remaining data with requested flush */
580n/a (void)gz_comp(state, flush);
581n/a return state->err;
582n/a}
583n/a
584n/a/* -- see zlib.h -- */
585n/aint ZEXPORT gzsetparams(file, level, strategy)
586n/a gzFile file;
587n/a int level;
588n/a int strategy;
589n/a{
590n/a gz_statep state;
591n/a z_streamp strm;
592n/a
593n/a /* get internal structure */
594n/a if (file == NULL)
595n/a return Z_STREAM_ERROR;
596n/a state = (gz_statep)file;
597n/a strm = &(state->strm);
598n/a
599n/a /* check that we're writing and that there's no error */
600n/a if (state->mode != GZ_WRITE || state->err != Z_OK)
601n/a return Z_STREAM_ERROR;
602n/a
603n/a /* if no change is requested, then do nothing */
604n/a if (level == state->level && strategy == state->strategy)
605n/a return Z_OK;
606n/a
607n/a /* check for seek request */
608n/a if (state->seek) {
609n/a state->seek = 0;
610n/a if (gz_zero(state, state->skip) == -1)
611n/a return state->err;
612n/a }
613n/a
614n/a /* change compression parameters for subsequent input */
615n/a if (state->size) {
616n/a /* flush previous input with previous parameters before changing */
617n/a if (strm->avail_in && gz_comp(state, Z_BLOCK) == -1)
618n/a return state->err;
619n/a deflateParams(strm, level, strategy);
620n/a }
621n/a state->level = level;
622n/a state->strategy = strategy;
623n/a return Z_OK;
624n/a}
625n/a
626n/a/* -- see zlib.h -- */
627n/aint ZEXPORT gzclose_w(file)
628n/a gzFile file;
629n/a{
630n/a int ret = Z_OK;
631n/a gz_statep state;
632n/a
633n/a /* get internal structure */
634n/a if (file == NULL)
635n/a return Z_STREAM_ERROR;
636n/a state = (gz_statep)file;
637n/a
638n/a /* check that we're writing */
639n/a if (state->mode != GZ_WRITE)
640n/a return Z_STREAM_ERROR;
641n/a
642n/a /* check for seek request */
643n/a if (state->seek) {
644n/a state->seek = 0;
645n/a if (gz_zero(state, state->skip) == -1)
646n/a ret = state->err;
647n/a }
648n/a
649n/a /* flush, free memory, and close file */
650n/a if (gz_comp(state, Z_FINISH) == -1)
651n/a ret = state->err;
652n/a if (state->size) {
653n/a if (!state->direct) {
654n/a (void)deflateEnd(&(state->strm));
655n/a free(state->out);
656n/a }
657n/a free(state->in);
658n/a }
659n/a gz_error(state, Z_OK, NULL);
660n/a free(state->path);
661n/a if (close(state->fd) == -1)
662n/a ret = Z_ERRNO;
663n/a free(state);
664n/a return ret;
665n/a}