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