diff options
author | Mark Adler <madler@alumni.caltech.edu> | 2011-10-02 13:24:43 -0700 |
---|---|---|
committer | Mark Adler <madler@alumni.caltech.edu> | 2011-10-02 13:34:29 -0700 |
commit | 26a99cd8957db86bdc75d9d1ebf00146cb20c87c (patch) | |
tree | 2f65d57da589c9e5475902fdf08a4aa8c4294bda /gzwrite.c | |
parent | 3c9d261809bfafc4350147ade7b74022dd144d32 (diff) | |
download | zlib-26a99cd8957db86bdc75d9d1ebf00146cb20c87c.tar.gz zlib-26a99cd8957db86bdc75d9d1ebf00146cb20c87c.tar.bz2 zlib-26a99cd8957db86bdc75d9d1ebf00146cb20c87c.zip |
Add a transparent write mode to gzopen() when 'T' is in the mode.
Diffstat (limited to 'gzwrite.c')
-rw-r--r-- | gzwrite.c | 72 |
1 files changed, 48 insertions, 24 deletions
@@ -18,44 +18,55 @@ local int gz_init(state) | |||
18 | int ret; | 18 | int ret; |
19 | z_streamp strm = &(state->strm); | 19 | z_streamp strm = &(state->strm); |
20 | 20 | ||
21 | /* allocate input and output buffers */ | 21 | /* allocate input buffer */ |
22 | state->in = malloc(state->want); | 22 | state->in = malloc(state->want); |
23 | state->out = malloc(state->want); | 23 | if (state->in == NULL) { |
24 | if (state->in == NULL || state->out == NULL) { | ||
25 | if (state->out != NULL) | ||
26 | free(state->out); | ||
27 | if (state->in != NULL) | ||
28 | free(state->in); | ||
29 | gz_error(state, Z_MEM_ERROR, "out of memory"); | 24 | gz_error(state, Z_MEM_ERROR, "out of memory"); |
30 | return -1; | 25 | return -1; |
31 | } | 26 | } |
32 | 27 | ||
33 | /* allocate deflate memory, set up for gzip compression */ | 28 | /* only need output buffer and deflate state if compressing */ |
34 | strm->zalloc = Z_NULL; | 29 | if (!state->direct) { |
35 | strm->zfree = Z_NULL; | 30 | /* allocate output buffer */ |
36 | strm->opaque = Z_NULL; | 31 | state->out = malloc(state->want); |
37 | ret = deflateInit2(strm, state->level, Z_DEFLATED, | 32 | if (state->out == NULL) { |
38 | 15 + 16, 8, state->strategy); | 33 | free(state->in); |
39 | if (ret != Z_OK) { | 34 | gz_error(state, Z_MEM_ERROR, "out of memory"); |
40 | free(state->in); | 35 | return -1; |
41 | gz_error(state, Z_MEM_ERROR, "out of memory"); | 36 | } |
42 | return -1; | 37 | |
38 | /* allocate deflate memory, set up for gzip compression */ | ||
39 | strm->zalloc = Z_NULL; | ||
40 | strm->zfree = Z_NULL; | ||
41 | strm->opaque = Z_NULL; | ||
42 | ret = deflateInit2(strm, state->level, Z_DEFLATED, | ||
43 | 15 + 16, 8, state->strategy); | ||
44 | if (ret != Z_OK) { | ||
45 | free(state->out); | ||
46 | free(state->in); | ||
47 | gz_error(state, Z_MEM_ERROR, "out of memory"); | ||
48 | return -1; | ||
49 | } | ||
43 | } | 50 | } |
44 | 51 | ||
45 | /* mark state as initialized */ | 52 | /* mark state as initialized */ |
46 | state->size = state->want; | 53 | state->size = state->want; |
47 | 54 | ||
48 | /* initialize write buffer */ | 55 | /* initialize write buffer if compressing */ |
49 | strm->avail_out = state->size; | 56 | if (!state->direct) { |
50 | strm->next_out = state->out; | 57 | strm->avail_out = state->size; |
51 | state->x.next = strm->next_out; | 58 | strm->next_out = state->out; |
59 | state->x.next = strm->next_out; | ||
60 | } | ||
52 | return 0; | 61 | return 0; |
53 | } | 62 | } |
54 | 63 | ||
55 | /* Compress whatever is at avail_in and next_in and write to the output file. | 64 | /* Compress whatever is at avail_in and next_in and write to the output file. |
56 | Return -1 if there is an error writing to the output file, otherwise 0. | 65 | Return -1 if there is an error writing to the output file, otherwise 0. |
57 | flush is assumed to be a valid deflate() flush value. If flush is Z_FINISH, | 66 | flush is assumed to be a valid deflate() flush value. If flush is Z_FINISH, |
58 | then the deflate() state is reset to start a new gzip stream. */ | 67 | then the deflate() state is reset to start a new gzip stream. If gz->direct |
68 | is true, then simply write to the output file without compressing, and | ||
69 | ignore flush. */ | ||
59 | local int gz_comp(state, flush) | 70 | local int gz_comp(state, flush) |
60 | gz_statep state; | 71 | gz_statep state; |
61 | int flush; | 72 | int flush; |
@@ -68,6 +79,17 @@ local int gz_comp(state, flush) | |||
68 | if (state->size == 0 && gz_init(state) == -1) | 79 | if (state->size == 0 && gz_init(state) == -1) |
69 | return -1; | 80 | return -1; |
70 | 81 | ||
82 | /* write directly if requested */ | ||
83 | if (state->direct) { | ||
84 | got = write(state->fd, strm->next_in, strm->avail_in); | ||
85 | if (got < 0 || (unsigned)got != strm->avail_in) { | ||
86 | gz_error(state, Z_ERRNO, zstrerror()); | ||
87 | return -1; | ||
88 | } | ||
89 | strm->avail_in = 0; | ||
90 | return 0; | ||
91 | } | ||
92 | |||
71 | /* run deflate() on provided input until it produces no more output */ | 93 | /* run deflate() on provided input until it produces no more output */ |
72 | ret = Z_OK; | 94 | ret = Z_OK; |
73 | do { | 95 | do { |
@@ -526,8 +548,10 @@ int ZEXPORT gzclose_w(file) | |||
526 | /* flush, free memory, and close file */ | 548 | /* flush, free memory, and close file */ |
527 | if (gz_comp(state, Z_FINISH) == -1) | 549 | if (gz_comp(state, Z_FINISH) == -1) |
528 | ret = state->err; | 550 | ret = state->err; |
529 | (void)deflateEnd(&(state->strm)); | 551 | if (!state->direct) { |
530 | free(state->out); | 552 | (void)deflateEnd(&(state->strm)); |
553 | free(state->out); | ||
554 | } | ||
531 | free(state->in); | 555 | free(state->in); |
532 | gz_error(state, Z_OK, NULL); | 556 | gz_error(state, Z_OK, NULL); |
533 | free(state->path); | 557 | free(state->path); |