1275793eaSopenharmony_ci/* gzwrite.c -- zlib functions for writing gzip files 2275793eaSopenharmony_ci * Copyright (C) 2004-2019 Mark Adler 3275793eaSopenharmony_ci * For conditions of distribution and use, see copyright notice in zlib.h 4275793eaSopenharmony_ci */ 5275793eaSopenharmony_ci 6275793eaSopenharmony_ci#include "gzguts.h" 7275793eaSopenharmony_ci#include <sys/types.h> 8275793eaSopenharmony_ci#include <unistd.h> 9275793eaSopenharmony_ci 10275793eaSopenharmony_ci/* Initialize state for writing a gzip file. Mark initialization by setting 11275793eaSopenharmony_ci state->size to non-zero. Return -1 on a memory allocation failure, or 0 on 12275793eaSopenharmony_ci success. */ 13275793eaSopenharmony_cilocal int gz_init(gz_statep state) 14275793eaSopenharmony_ci{ 15275793eaSopenharmony_ci int ret; 16275793eaSopenharmony_ci z_streamp strm = &(state->strm); 17275793eaSopenharmony_ci 18275793eaSopenharmony_ci /* allocate input buffer (double size for gzprintf) */ 19275793eaSopenharmony_ci state->in = (unsigned char *)malloc(state->want << 1); 20275793eaSopenharmony_ci if (state->in == NULL) { 21275793eaSopenharmony_ci gz_error(state, Z_MEM_ERROR, "out of memory"); 22275793eaSopenharmony_ci return -1; 23275793eaSopenharmony_ci } 24275793eaSopenharmony_ci 25275793eaSopenharmony_ci /* only need output buffer and deflate state if compressing */ 26275793eaSopenharmony_ci if (!state->direct) { 27275793eaSopenharmony_ci /* allocate output buffer */ 28275793eaSopenharmony_ci state->out = (unsigned char *)malloc(state->want); 29275793eaSopenharmony_ci if (state->out == NULL) { 30275793eaSopenharmony_ci free(state->in); 31275793eaSopenharmony_ci gz_error(state, Z_MEM_ERROR, "out of memory"); 32275793eaSopenharmony_ci return -1; 33275793eaSopenharmony_ci } 34275793eaSopenharmony_ci 35275793eaSopenharmony_ci /* allocate deflate memory, set up for gzip compression */ 36275793eaSopenharmony_ci strm->zalloc = Z_NULL; 37275793eaSopenharmony_ci strm->zfree = Z_NULL; 38275793eaSopenharmony_ci strm->opaque = Z_NULL; 39275793eaSopenharmony_ci ret = deflateInit2(strm, state->level, Z_DEFLATED, 40275793eaSopenharmony_ci MAX_WBITS + 16, DEF_MEM_LEVEL, state->strategy); 41275793eaSopenharmony_ci if (ret != Z_OK) { 42275793eaSopenharmony_ci free(state->out); 43275793eaSopenharmony_ci free(state->in); 44275793eaSopenharmony_ci gz_error(state, Z_MEM_ERROR, "out of memory"); 45275793eaSopenharmony_ci return -1; 46275793eaSopenharmony_ci } 47275793eaSopenharmony_ci strm->next_in = NULL; 48275793eaSopenharmony_ci } 49275793eaSopenharmony_ci 50275793eaSopenharmony_ci /* mark state as initialized */ 51275793eaSopenharmony_ci state->size = state->want; 52275793eaSopenharmony_ci 53275793eaSopenharmony_ci /* initialize write buffer if compressing */ 54275793eaSopenharmony_ci if (!state->direct) { 55275793eaSopenharmony_ci strm->avail_out = state->size; 56275793eaSopenharmony_ci strm->next_out = state->out; 57275793eaSopenharmony_ci state->x.next = strm->next_out; 58275793eaSopenharmony_ci } 59275793eaSopenharmony_ci return 0; 60275793eaSopenharmony_ci} 61275793eaSopenharmony_ci 62275793eaSopenharmony_ci/* Compress whatever is at avail_in and next_in and write to the output file. 63275793eaSopenharmony_ci Return -1 if there is an error writing to the output file or if gz_init() 64275793eaSopenharmony_ci fails to allocate memory, otherwise 0. flush is assumed to be a valid 65275793eaSopenharmony_ci deflate() flush value. If flush is Z_FINISH, then the deflate() state is 66275793eaSopenharmony_ci reset to start a new gzip stream. If gz->direct is true, then simply write 67275793eaSopenharmony_ci to the output file without compressing, and ignore flush. */ 68275793eaSopenharmony_cilocal int gz_comp(gz_statep state, int flush) 69275793eaSopenharmony_ci{ 70275793eaSopenharmony_ci int ret, writ; 71275793eaSopenharmony_ci unsigned have, put, max = ((unsigned)-1 >> 2) + 1; 72275793eaSopenharmony_ci z_streamp strm = &(state->strm); 73275793eaSopenharmony_ci 74275793eaSopenharmony_ci /* allocate memory if this is the first time through */ 75275793eaSopenharmony_ci if (state->size == 0 && gz_init(state) == -1) 76275793eaSopenharmony_ci return -1; 77275793eaSopenharmony_ci 78275793eaSopenharmony_ci /* write directly if requested */ 79275793eaSopenharmony_ci if (state->direct) { 80275793eaSopenharmony_ci while (strm->avail_in) { 81275793eaSopenharmony_ci put = strm->avail_in > max ? max : strm->avail_in; 82275793eaSopenharmony_ci writ = write(state->fd, strm->next_in, put); 83275793eaSopenharmony_ci if (writ < 0) { 84275793eaSopenharmony_ci gz_error(state, Z_ERRNO, zstrerror()); 85275793eaSopenharmony_ci return -1; 86275793eaSopenharmony_ci } 87275793eaSopenharmony_ci strm->avail_in -= (unsigned)writ; 88275793eaSopenharmony_ci strm->next_in += writ; 89275793eaSopenharmony_ci } 90275793eaSopenharmony_ci return 0; 91275793eaSopenharmony_ci } 92275793eaSopenharmony_ci 93275793eaSopenharmony_ci /* check for a pending reset */ 94275793eaSopenharmony_ci if (state->reset) { 95275793eaSopenharmony_ci /* don't start a new gzip member unless there is data to write */ 96275793eaSopenharmony_ci if (strm->avail_in == 0) 97275793eaSopenharmony_ci return 0; 98275793eaSopenharmony_ci deflateReset(strm); 99275793eaSopenharmony_ci state->reset = 0; 100275793eaSopenharmony_ci } 101275793eaSopenharmony_ci 102275793eaSopenharmony_ci /* run deflate() on provided input until it produces no more output */ 103275793eaSopenharmony_ci ret = Z_OK; 104275793eaSopenharmony_ci do { 105275793eaSopenharmony_ci /* write out current buffer contents if full, or if flushing, but if 106275793eaSopenharmony_ci doing Z_FINISH then don't write until we get to Z_STREAM_END */ 107275793eaSopenharmony_ci if (strm->avail_out == 0 || (flush != Z_NO_FLUSH && 108275793eaSopenharmony_ci (flush != Z_FINISH || ret == Z_STREAM_END))) { 109275793eaSopenharmony_ci while (strm->next_out > state->x.next) { 110275793eaSopenharmony_ci put = strm->next_out - state->x.next > (int)max ? max : 111275793eaSopenharmony_ci (unsigned)(strm->next_out - state->x.next); 112275793eaSopenharmony_ci writ = write(state->fd, state->x.next, put); 113275793eaSopenharmony_ci if (writ < 0) { 114275793eaSopenharmony_ci gz_error(state, Z_ERRNO, zstrerror()); 115275793eaSopenharmony_ci return -1; 116275793eaSopenharmony_ci } 117275793eaSopenharmony_ci state->x.next += writ; 118275793eaSopenharmony_ci } 119275793eaSopenharmony_ci if (strm->avail_out == 0) { 120275793eaSopenharmony_ci strm->avail_out = state->size; 121275793eaSopenharmony_ci strm->next_out = state->out; 122275793eaSopenharmony_ci state->x.next = state->out; 123275793eaSopenharmony_ci } 124275793eaSopenharmony_ci } 125275793eaSopenharmony_ci 126275793eaSopenharmony_ci /* compress */ 127275793eaSopenharmony_ci have = strm->avail_out; 128275793eaSopenharmony_ci ret = deflate(strm, flush); 129275793eaSopenharmony_ci if (ret == Z_STREAM_ERROR) { 130275793eaSopenharmony_ci gz_error(state, Z_STREAM_ERROR, 131275793eaSopenharmony_ci "internal error: deflate stream corrupt"); 132275793eaSopenharmony_ci return -1; 133275793eaSopenharmony_ci } 134275793eaSopenharmony_ci have -= strm->avail_out; 135275793eaSopenharmony_ci } while (have); 136275793eaSopenharmony_ci 137275793eaSopenharmony_ci /* if that completed a deflate stream, allow another to start */ 138275793eaSopenharmony_ci if (flush == Z_FINISH) 139275793eaSopenharmony_ci state->reset = 1; 140275793eaSopenharmony_ci 141275793eaSopenharmony_ci /* all done, no errors */ 142275793eaSopenharmony_ci return 0; 143275793eaSopenharmony_ci} 144275793eaSopenharmony_ci 145275793eaSopenharmony_ci/* Compress len zeros to output. Return -1 on a write error or memory 146275793eaSopenharmony_ci allocation failure by gz_comp(), or 0 on success. */ 147275793eaSopenharmony_cilocal int gz_zero(gz_statep state, z_off64_t len) 148275793eaSopenharmony_ci{ 149275793eaSopenharmony_ci int first; 150275793eaSopenharmony_ci unsigned n; 151275793eaSopenharmony_ci z_streamp strm = &(state->strm); 152275793eaSopenharmony_ci 153275793eaSopenharmony_ci /* consume whatever's left in the input buffer */ 154275793eaSopenharmony_ci if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1) 155275793eaSopenharmony_ci return -1; 156275793eaSopenharmony_ci 157275793eaSopenharmony_ci /* compress len zeros (len guaranteed > 0) */ 158275793eaSopenharmony_ci first = 1; 159275793eaSopenharmony_ci while (len) { 160275793eaSopenharmony_ci n = GT_OFF(state->size) || (z_off64_t)state->size > len ? 161275793eaSopenharmony_ci (unsigned)len : state->size; 162275793eaSopenharmony_ci if (first) { 163275793eaSopenharmony_ci memset(state->in, 0, n); 164275793eaSopenharmony_ci first = 0; 165275793eaSopenharmony_ci } 166275793eaSopenharmony_ci strm->avail_in = n; 167275793eaSopenharmony_ci strm->next_in = state->in; 168275793eaSopenharmony_ci state->x.pos += n; 169275793eaSopenharmony_ci if (gz_comp(state, Z_NO_FLUSH) == -1) 170275793eaSopenharmony_ci return -1; 171275793eaSopenharmony_ci len -= n; 172275793eaSopenharmony_ci } 173275793eaSopenharmony_ci return 0; 174275793eaSopenharmony_ci} 175275793eaSopenharmony_ci 176275793eaSopenharmony_ci/* Write len bytes from buf to file. Return the number of bytes written. If 177275793eaSopenharmony_ci the returned value is less than len, then there was an error. */ 178275793eaSopenharmony_cilocal z_size_t gz_write(gz_statep state, voidpc buf, z_size_t len) 179275793eaSopenharmony_ci{ 180275793eaSopenharmony_ci z_size_t put = len; 181275793eaSopenharmony_ci 182275793eaSopenharmony_ci /* if len is zero, avoid unnecessary operations */ 183275793eaSopenharmony_ci if (len == 0) 184275793eaSopenharmony_ci return 0; 185275793eaSopenharmony_ci 186275793eaSopenharmony_ci /* allocate memory if this is the first time through */ 187275793eaSopenharmony_ci if (state->size == 0 && gz_init(state) == -1) 188275793eaSopenharmony_ci return 0; 189275793eaSopenharmony_ci 190275793eaSopenharmony_ci /* check for seek request */ 191275793eaSopenharmony_ci if (state->seek) { 192275793eaSopenharmony_ci state->seek = 0; 193275793eaSopenharmony_ci if (gz_zero(state, state->skip) == -1) 194275793eaSopenharmony_ci return 0; 195275793eaSopenharmony_ci } 196275793eaSopenharmony_ci 197275793eaSopenharmony_ci /* for small len, copy to input buffer, otherwise compress directly */ 198275793eaSopenharmony_ci if (len < state->size) { 199275793eaSopenharmony_ci /* copy to input buffer, compress when full */ 200275793eaSopenharmony_ci do { 201275793eaSopenharmony_ci unsigned have, copy; 202275793eaSopenharmony_ci 203275793eaSopenharmony_ci if (state->strm.avail_in == 0) 204275793eaSopenharmony_ci state->strm.next_in = state->in; 205275793eaSopenharmony_ci have = (unsigned)((state->strm.next_in + state->strm.avail_in) - 206275793eaSopenharmony_ci state->in); 207275793eaSopenharmony_ci copy = state->size - have; 208275793eaSopenharmony_ci if (copy > len) 209275793eaSopenharmony_ci copy = (unsigned)len; 210275793eaSopenharmony_ci memcpy(state->in + have, buf, copy); 211275793eaSopenharmony_ci state->strm.avail_in += copy; 212275793eaSopenharmony_ci state->x.pos += copy; 213275793eaSopenharmony_ci buf = (const char *)buf + copy; 214275793eaSopenharmony_ci len -= copy; 215275793eaSopenharmony_ci if (len && gz_comp(state, Z_NO_FLUSH) == -1) 216275793eaSopenharmony_ci return 0; 217275793eaSopenharmony_ci } while (len); 218275793eaSopenharmony_ci } 219275793eaSopenharmony_ci else { 220275793eaSopenharmony_ci /* consume whatever's left in the input buffer */ 221275793eaSopenharmony_ci if (state->strm.avail_in && gz_comp(state, Z_NO_FLUSH) == -1) 222275793eaSopenharmony_ci return 0; 223275793eaSopenharmony_ci 224275793eaSopenharmony_ci /* directly compress user buffer to file */ 225275793eaSopenharmony_ci state->strm.next_in = (z_const Bytef *)buf; 226275793eaSopenharmony_ci do { 227275793eaSopenharmony_ci unsigned n = (unsigned)-1; 228275793eaSopenharmony_ci if (n > len) 229275793eaSopenharmony_ci n = (unsigned)len; 230275793eaSopenharmony_ci state->strm.avail_in = n; 231275793eaSopenharmony_ci state->x.pos += n; 232275793eaSopenharmony_ci if (gz_comp(state, Z_NO_FLUSH) == -1) 233275793eaSopenharmony_ci return 0; 234275793eaSopenharmony_ci len -= n; 235275793eaSopenharmony_ci } while (len); 236275793eaSopenharmony_ci } 237275793eaSopenharmony_ci 238275793eaSopenharmony_ci /* input was all buffered or compressed */ 239275793eaSopenharmony_ci return put; 240275793eaSopenharmony_ci} 241275793eaSopenharmony_ci 242275793eaSopenharmony_ci/* -- see zlib.h -- */ 243275793eaSopenharmony_ciint ZEXPORT gzwrite(gzFile file, voidpc buf, unsigned len) { 244275793eaSopenharmony_ci gz_statep state; 245275793eaSopenharmony_ci 246275793eaSopenharmony_ci /* get internal structure */ 247275793eaSopenharmony_ci if (file == NULL) 248275793eaSopenharmony_ci return 0; 249275793eaSopenharmony_ci state = (gz_statep)file; 250275793eaSopenharmony_ci 251275793eaSopenharmony_ci /* check that we're writing and that there's no error */ 252275793eaSopenharmony_ci if (state->mode != GZ_WRITE || state->err != Z_OK) 253275793eaSopenharmony_ci return 0; 254275793eaSopenharmony_ci 255275793eaSopenharmony_ci /* since an int is returned, make sure len fits in one, otherwise return 256275793eaSopenharmony_ci with an error (this avoids a flaw in the interface) */ 257275793eaSopenharmony_ci if ((int)len < 0) { 258275793eaSopenharmony_ci gz_error(state, Z_DATA_ERROR, "requested length does not fit in int"); 259275793eaSopenharmony_ci return 0; 260275793eaSopenharmony_ci } 261275793eaSopenharmony_ci 262275793eaSopenharmony_ci /* write len bytes from buf (the return value will fit in an int) */ 263275793eaSopenharmony_ci return (int)gz_write(state, buf, len); 264275793eaSopenharmony_ci} 265275793eaSopenharmony_ci 266275793eaSopenharmony_ci/* -- see zlib.h -- */ 267275793eaSopenharmony_ciz_size_t ZEXPORT gzfwrite(voidpc buf, z_size_t size, z_size_t nitems, 268275793eaSopenharmony_ci gzFile file) 269275793eaSopenharmony_ci{ 270275793eaSopenharmony_ci z_size_t len; 271275793eaSopenharmony_ci gz_statep state; 272275793eaSopenharmony_ci 273275793eaSopenharmony_ci /* get internal structure */ 274275793eaSopenharmony_ci if (file == NULL) 275275793eaSopenharmony_ci return 0; 276275793eaSopenharmony_ci state = (gz_statep)file; 277275793eaSopenharmony_ci 278275793eaSopenharmony_ci /* check that we're writing and that there's no error */ 279275793eaSopenharmony_ci if (state->mode != GZ_WRITE || state->err != Z_OK) 280275793eaSopenharmony_ci return 0; 281275793eaSopenharmony_ci 282275793eaSopenharmony_ci /* compute bytes to read -- error on overflow */ 283275793eaSopenharmony_ci len = nitems * size; 284275793eaSopenharmony_ci if (size && len / size != nitems) { 285275793eaSopenharmony_ci gz_error(state, Z_STREAM_ERROR, "request does not fit in a size_t"); 286275793eaSopenharmony_ci return 0; 287275793eaSopenharmony_ci } 288275793eaSopenharmony_ci 289275793eaSopenharmony_ci /* write len bytes to buf, return the number of full items written */ 290275793eaSopenharmony_ci return len ? gz_write(state, buf, len) / size : 0; 291275793eaSopenharmony_ci} 292275793eaSopenharmony_ci 293275793eaSopenharmony_ci/* -- see zlib.h -- */ 294275793eaSopenharmony_ciint ZEXPORT gzputc(gzFile file, int c) { 295275793eaSopenharmony_ci unsigned have; 296275793eaSopenharmony_ci unsigned char buf[1]; 297275793eaSopenharmony_ci gz_statep state; 298275793eaSopenharmony_ci z_streamp strm; 299275793eaSopenharmony_ci 300275793eaSopenharmony_ci /* get internal structure */ 301275793eaSopenharmony_ci if (file == NULL) 302275793eaSopenharmony_ci return -1; 303275793eaSopenharmony_ci state = (gz_statep)file; 304275793eaSopenharmony_ci strm = &(state->strm); 305275793eaSopenharmony_ci 306275793eaSopenharmony_ci /* check that we're writing and that there's no error */ 307275793eaSopenharmony_ci if (state->mode != GZ_WRITE || state->err != Z_OK) 308275793eaSopenharmony_ci return -1; 309275793eaSopenharmony_ci 310275793eaSopenharmony_ci /* check for seek request */ 311275793eaSopenharmony_ci if (state->seek) { 312275793eaSopenharmony_ci state->seek = 0; 313275793eaSopenharmony_ci if (gz_zero(state, state->skip) == -1) 314275793eaSopenharmony_ci return -1; 315275793eaSopenharmony_ci } 316275793eaSopenharmony_ci 317275793eaSopenharmony_ci /* try writing to input buffer for speed (state->size == 0 if buffer not 318275793eaSopenharmony_ci initialized) */ 319275793eaSopenharmony_ci if (state->size) { 320275793eaSopenharmony_ci if (strm->avail_in == 0) 321275793eaSopenharmony_ci strm->next_in = state->in; 322275793eaSopenharmony_ci have = (unsigned)((strm->next_in + strm->avail_in) - state->in); 323275793eaSopenharmony_ci if (have < state->size) { 324275793eaSopenharmony_ci state->in[have] = (unsigned char)c; 325275793eaSopenharmony_ci strm->avail_in++; 326275793eaSopenharmony_ci state->x.pos++; 327275793eaSopenharmony_ci return c & 0xff; 328275793eaSopenharmony_ci } 329275793eaSopenharmony_ci } 330275793eaSopenharmony_ci 331275793eaSopenharmony_ci /* no room in buffer or not initialized, use gz_write() */ 332275793eaSopenharmony_ci buf[0] = (unsigned char)c; 333275793eaSopenharmony_ci if (gz_write(state, buf, 1) != 1) 334275793eaSopenharmony_ci return -1; 335275793eaSopenharmony_ci return c & 0xff; 336275793eaSopenharmony_ci} 337275793eaSopenharmony_ci 338275793eaSopenharmony_ci/* -- see zlib.h -- */ 339275793eaSopenharmony_ciint ZEXPORT gzputs(gzFile file, const char *s) { 340275793eaSopenharmony_ci z_size_t len, put; 341275793eaSopenharmony_ci gz_statep state; 342275793eaSopenharmony_ci 343275793eaSopenharmony_ci /* get internal structure */ 344275793eaSopenharmony_ci if (file == NULL) 345275793eaSopenharmony_ci return -1; 346275793eaSopenharmony_ci state = (gz_statep)file; 347275793eaSopenharmony_ci 348275793eaSopenharmony_ci /* check that we're writing and that there's no error */ 349275793eaSopenharmony_ci if (state->mode != GZ_WRITE || state->err != Z_OK) 350275793eaSopenharmony_ci return -1; 351275793eaSopenharmony_ci 352275793eaSopenharmony_ci /* write string */ 353275793eaSopenharmony_ci len = strlen(s); 354275793eaSopenharmony_ci if ((int)len < 0 || (unsigned)len != len) { 355275793eaSopenharmony_ci gz_error(state, Z_STREAM_ERROR, "string length does not fit in int"); 356275793eaSopenharmony_ci return -1; 357275793eaSopenharmony_ci } 358275793eaSopenharmony_ci put = gz_write(state, s, len); 359275793eaSopenharmony_ci return put < len ? -1 : (int)len; 360275793eaSopenharmony_ci} 361275793eaSopenharmony_ci 362275793eaSopenharmony_ci#if defined(STDC) || defined(Z_HAVE_STDARG_H) 363275793eaSopenharmony_ci#include <stdarg.h> 364275793eaSopenharmony_ci 365275793eaSopenharmony_ci/* -- see zlib.h -- */ 366275793eaSopenharmony_ciint ZEXPORTVA gzvprintf(gzFile file, const char *format, va_list va) { 367275793eaSopenharmony_ci int len; 368275793eaSopenharmony_ci unsigned left; 369275793eaSopenharmony_ci char *next; 370275793eaSopenharmony_ci gz_statep state; 371275793eaSopenharmony_ci z_streamp strm; 372275793eaSopenharmony_ci 373275793eaSopenharmony_ci /* get internal structure */ 374275793eaSopenharmony_ci if (file == NULL) 375275793eaSopenharmony_ci return Z_STREAM_ERROR; 376275793eaSopenharmony_ci state = (gz_statep)file; 377275793eaSopenharmony_ci strm = &(state->strm); 378275793eaSopenharmony_ci 379275793eaSopenharmony_ci /* check that we're writing and that there's no error */ 380275793eaSopenharmony_ci if (state->mode != GZ_WRITE || state->err != Z_OK) 381275793eaSopenharmony_ci return Z_STREAM_ERROR; 382275793eaSopenharmony_ci 383275793eaSopenharmony_ci /* make sure we have some buffer space */ 384275793eaSopenharmony_ci if (state->size == 0 && gz_init(state) == -1) 385275793eaSopenharmony_ci return state->err; 386275793eaSopenharmony_ci 387275793eaSopenharmony_ci /* check for seek request */ 388275793eaSopenharmony_ci if (state->seek) { 389275793eaSopenharmony_ci state->seek = 0; 390275793eaSopenharmony_ci if (gz_zero(state, state->skip) == -1) 391275793eaSopenharmony_ci return state->err; 392275793eaSopenharmony_ci } 393275793eaSopenharmony_ci 394275793eaSopenharmony_ci /* do the printf() into the input buffer, put length in len -- the input 395275793eaSopenharmony_ci buffer is double-sized just for this function, so there is guaranteed to 396275793eaSopenharmony_ci be state->size bytes available after the current contents */ 397275793eaSopenharmony_ci if (strm->avail_in == 0) 398275793eaSopenharmony_ci strm->next_in = state->in; 399275793eaSopenharmony_ci next = (char *)(state->in + (strm->next_in - state->in) + strm->avail_in); 400275793eaSopenharmony_ci next[state->size - 1] = 0; 401275793eaSopenharmony_ci#ifdef NO_vsnprintf 402275793eaSopenharmony_ci# ifdef HAS_vsprintf_void 403275793eaSopenharmony_ci (void)vsprintf(next, format, va); 404275793eaSopenharmony_ci for (len = 0; len < state->size; len++) 405275793eaSopenharmony_ci if (next[len] == 0) break; 406275793eaSopenharmony_ci# else 407275793eaSopenharmony_ci len = vsprintf(next, format, va); 408275793eaSopenharmony_ci# endif 409275793eaSopenharmony_ci#else 410275793eaSopenharmony_ci# ifdef HAS_vsnprintf_void 411275793eaSopenharmony_ci (void)vsnprintf(next, state->size, format, va); 412275793eaSopenharmony_ci len = strlen(next); 413275793eaSopenharmony_ci# else 414275793eaSopenharmony_ci len = vsnprintf(next, state->size, format, va); 415275793eaSopenharmony_ci# endif 416275793eaSopenharmony_ci#endif 417275793eaSopenharmony_ci 418275793eaSopenharmony_ci /* check that printf() results fit in buffer */ 419275793eaSopenharmony_ci if (len == 0 || (unsigned)len >= state->size || next[state->size - 1] != 0) 420275793eaSopenharmony_ci return 0; 421275793eaSopenharmony_ci 422275793eaSopenharmony_ci /* update buffer and position, compress first half if past that */ 423275793eaSopenharmony_ci strm->avail_in += (unsigned)len; 424275793eaSopenharmony_ci state->x.pos += len; 425275793eaSopenharmony_ci if (strm->avail_in >= state->size) { 426275793eaSopenharmony_ci left = strm->avail_in - state->size; 427275793eaSopenharmony_ci strm->avail_in = state->size; 428275793eaSopenharmony_ci if (gz_comp(state, Z_NO_FLUSH) == -1) 429275793eaSopenharmony_ci return state->err; 430275793eaSopenharmony_ci memmove(state->in, state->in + state->size, left); 431275793eaSopenharmony_ci strm->next_in = state->in; 432275793eaSopenharmony_ci strm->avail_in = left; 433275793eaSopenharmony_ci } 434275793eaSopenharmony_ci return len; 435275793eaSopenharmony_ci} 436275793eaSopenharmony_ci 437275793eaSopenharmony_ciint ZEXPORTVA gzprintf(gzFile file, const char *format, ...) { 438275793eaSopenharmony_ci va_list va; 439275793eaSopenharmony_ci int ret; 440275793eaSopenharmony_ci 441275793eaSopenharmony_ci va_start(va, format); 442275793eaSopenharmony_ci ret = gzvprintf(file, format, va); 443275793eaSopenharmony_ci va_end(va); 444275793eaSopenharmony_ci return ret; 445275793eaSopenharmony_ci} 446275793eaSopenharmony_ci 447275793eaSopenharmony_ci#else /* !STDC && !Z_HAVE_STDARG_H */ 448275793eaSopenharmony_ci 449275793eaSopenharmony_ci/* -- see zlib.h -- */ 450275793eaSopenharmony_ciint ZEXPORTVA gzprintf(gzFile file, const char *format, int a1, int a2, int a3, 451275793eaSopenharmony_ci int a4, int a5, int a6, int a7, int a8, int a9, int a10, 452275793eaSopenharmony_ci int a11, int a12, int a13, int a14, int a15, int a16, 453275793eaSopenharmony_ci int a17, int a18, int a19, int a20) { 454275793eaSopenharmony_ci unsigned len, left; 455275793eaSopenharmony_ci char *next; 456275793eaSopenharmony_ci gz_statep state; 457275793eaSopenharmony_ci z_streamp strm; 458275793eaSopenharmony_ci 459275793eaSopenharmony_ci /* get internal structure */ 460275793eaSopenharmony_ci if (file == NULL) 461275793eaSopenharmony_ci return Z_STREAM_ERROR; 462275793eaSopenharmony_ci state = (gz_statep)file; 463275793eaSopenharmony_ci strm = &(state->strm); 464275793eaSopenharmony_ci 465275793eaSopenharmony_ci /* check that can really pass pointer in ints */ 466275793eaSopenharmony_ci if (sizeof(int) != sizeof(void *)) 467275793eaSopenharmony_ci return Z_STREAM_ERROR; 468275793eaSopenharmony_ci 469275793eaSopenharmony_ci /* check that we're writing and that there's no error */ 470275793eaSopenharmony_ci if (state->mode != GZ_WRITE || state->err != Z_OK) 471275793eaSopenharmony_ci return Z_STREAM_ERROR; 472275793eaSopenharmony_ci 473275793eaSopenharmony_ci /* make sure we have some buffer space */ 474275793eaSopenharmony_ci if (state->size == 0 && gz_init(state) == -1) 475275793eaSopenharmony_ci return state->error; 476275793eaSopenharmony_ci 477275793eaSopenharmony_ci /* check for seek request */ 478275793eaSopenharmony_ci if (state->seek) { 479275793eaSopenharmony_ci state->seek = 0; 480275793eaSopenharmony_ci if (gz_zero(state, state->skip) == -1) 481275793eaSopenharmony_ci return state->error; 482275793eaSopenharmony_ci } 483275793eaSopenharmony_ci 484275793eaSopenharmony_ci /* do the printf() into the input buffer, put length in len -- the input 485275793eaSopenharmony_ci buffer is double-sized just for this function, so there is guaranteed to 486275793eaSopenharmony_ci be state->size bytes available after the current contents */ 487275793eaSopenharmony_ci if (strm->avail_in == 0) 488275793eaSopenharmony_ci strm->next_in = state->in; 489275793eaSopenharmony_ci next = (char *)(strm->next_in + strm->avail_in); 490275793eaSopenharmony_ci next[state->size - 1] = 0; 491275793eaSopenharmony_ci#ifdef NO_snprintf 492275793eaSopenharmony_ci# ifdef HAS_sprintf_void 493275793eaSopenharmony_ci sprintf(next, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, 494275793eaSopenharmony_ci a13, a14, a15, a16, a17, a18, a19, a20); 495275793eaSopenharmony_ci for (len = 0; len < size; len++) 496275793eaSopenharmony_ci if (next[len] == 0) 497275793eaSopenharmony_ci break; 498275793eaSopenharmony_ci# else 499275793eaSopenharmony_ci len = sprintf(next, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, 500275793eaSopenharmony_ci a12, a13, a14, a15, a16, a17, a18, a19, a20); 501275793eaSopenharmony_ci# endif 502275793eaSopenharmony_ci#else 503275793eaSopenharmony_ci# ifdef HAS_snprintf_void 504275793eaSopenharmony_ci snprintf(next, state->size, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, 505275793eaSopenharmony_ci a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); 506275793eaSopenharmony_ci len = strlen(next); 507275793eaSopenharmony_ci# else 508275793eaSopenharmony_ci len = snprintf(next, state->size, format, a1, a2, a3, a4, a5, a6, a7, a8, 509275793eaSopenharmony_ci a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); 510275793eaSopenharmony_ci# endif 511275793eaSopenharmony_ci#endif 512275793eaSopenharmony_ci 513275793eaSopenharmony_ci /* check that printf() results fit in buffer */ 514275793eaSopenharmony_ci if (len == 0 || len >= state->size || next[state->size - 1] != 0) 515275793eaSopenharmony_ci return 0; 516275793eaSopenharmony_ci 517275793eaSopenharmony_ci /* update buffer and position, compress first half if past that */ 518275793eaSopenharmony_ci strm->avail_in += len; 519275793eaSopenharmony_ci state->x.pos += len; 520275793eaSopenharmony_ci if (strm->avail_in >= state->size) { 521275793eaSopenharmony_ci left = strm->avail_in - state->size; 522275793eaSopenharmony_ci strm->avail_in = state->size; 523275793eaSopenharmony_ci if (gz_comp(state, Z_NO_FLUSH) == -1) 524275793eaSopenharmony_ci return state->err; 525275793eaSopenharmony_ci memmove(state->in, state->in + state->size, left); 526275793eaSopenharmony_ci strm->next_in = state->in; 527275793eaSopenharmony_ci strm->avail_in = left; 528275793eaSopenharmony_ci } 529275793eaSopenharmony_ci return (int)len; 530275793eaSopenharmony_ci} 531275793eaSopenharmony_ci 532275793eaSopenharmony_ci#endif 533275793eaSopenharmony_ci 534275793eaSopenharmony_ci/* -- see zlib.h -- */ 535275793eaSopenharmony_ciint ZEXPORT gzflush(gzFile file, int flush) { 536275793eaSopenharmony_ci gz_statep state; 537275793eaSopenharmony_ci 538275793eaSopenharmony_ci /* get internal structure */ 539275793eaSopenharmony_ci if (file == NULL) 540275793eaSopenharmony_ci return Z_STREAM_ERROR; 541275793eaSopenharmony_ci state = (gz_statep)file; 542275793eaSopenharmony_ci 543275793eaSopenharmony_ci /* check that we're writing and that there's no error */ 544275793eaSopenharmony_ci if (state->mode != GZ_WRITE || state->err != Z_OK) 545275793eaSopenharmony_ci return Z_STREAM_ERROR; 546275793eaSopenharmony_ci 547275793eaSopenharmony_ci /* check flush parameter */ 548275793eaSopenharmony_ci if (flush < 0 || flush > Z_FINISH) 549275793eaSopenharmony_ci return Z_STREAM_ERROR; 550275793eaSopenharmony_ci 551275793eaSopenharmony_ci /* check for seek request */ 552275793eaSopenharmony_ci if (state->seek) { 553275793eaSopenharmony_ci state->seek = 0; 554275793eaSopenharmony_ci if (gz_zero(state, state->skip) == -1) 555275793eaSopenharmony_ci return state->err; 556275793eaSopenharmony_ci } 557275793eaSopenharmony_ci 558275793eaSopenharmony_ci /* compress remaining data with requested flush */ 559275793eaSopenharmony_ci (void)gz_comp(state, flush); 560275793eaSopenharmony_ci return state->err; 561275793eaSopenharmony_ci} 562275793eaSopenharmony_ci 563275793eaSopenharmony_ci/* -- see zlib.h -- */ 564275793eaSopenharmony_ciint ZEXPORT gzsetparams(gzFile file, int level, int strategy) { 565275793eaSopenharmony_ci gz_statep state; 566275793eaSopenharmony_ci z_streamp strm; 567275793eaSopenharmony_ci 568275793eaSopenharmony_ci /* get internal structure */ 569275793eaSopenharmony_ci if (file == NULL) 570275793eaSopenharmony_ci return Z_STREAM_ERROR; 571275793eaSopenharmony_ci state = (gz_statep)file; 572275793eaSopenharmony_ci strm = &(state->strm); 573275793eaSopenharmony_ci 574275793eaSopenharmony_ci /* check that we're writing and that there's no error */ 575275793eaSopenharmony_ci if (state->mode != GZ_WRITE || state->err != Z_OK || state->direct) 576275793eaSopenharmony_ci return Z_STREAM_ERROR; 577275793eaSopenharmony_ci 578275793eaSopenharmony_ci /* if no change is requested, then do nothing */ 579275793eaSopenharmony_ci if (level == state->level && strategy == state->strategy) 580275793eaSopenharmony_ci return Z_OK; 581275793eaSopenharmony_ci 582275793eaSopenharmony_ci /* check for seek request */ 583275793eaSopenharmony_ci if (state->seek) { 584275793eaSopenharmony_ci state->seek = 0; 585275793eaSopenharmony_ci if (gz_zero(state, state->skip) == -1) 586275793eaSopenharmony_ci return state->err; 587275793eaSopenharmony_ci } 588275793eaSopenharmony_ci 589275793eaSopenharmony_ci /* change compression parameters for subsequent input */ 590275793eaSopenharmony_ci if (state->size) { 591275793eaSopenharmony_ci /* flush previous input with previous parameters before changing */ 592275793eaSopenharmony_ci if (strm->avail_in && gz_comp(state, Z_BLOCK) == -1) 593275793eaSopenharmony_ci return state->err; 594275793eaSopenharmony_ci deflateParams(strm, level, strategy); 595275793eaSopenharmony_ci } 596275793eaSopenharmony_ci state->level = level; 597275793eaSopenharmony_ci state->strategy = strategy; 598275793eaSopenharmony_ci return Z_OK; 599275793eaSopenharmony_ci} 600275793eaSopenharmony_ci 601275793eaSopenharmony_ci/* -- see zlib.h -- */ 602275793eaSopenharmony_ciint ZEXPORT gzclose_w(gzFile file) { 603275793eaSopenharmony_ci int ret = Z_OK; 604275793eaSopenharmony_ci gz_statep state; 605275793eaSopenharmony_ci 606275793eaSopenharmony_ci /* get internal structure */ 607275793eaSopenharmony_ci if (file == NULL) 608275793eaSopenharmony_ci return Z_STREAM_ERROR; 609275793eaSopenharmony_ci state = (gz_statep)file; 610275793eaSopenharmony_ci 611275793eaSopenharmony_ci /* check that we're writing */ 612275793eaSopenharmony_ci if (state->mode != GZ_WRITE) 613275793eaSopenharmony_ci return Z_STREAM_ERROR; 614275793eaSopenharmony_ci 615275793eaSopenharmony_ci /* check for seek request */ 616275793eaSopenharmony_ci if (state->seek) { 617275793eaSopenharmony_ci state->seek = 0; 618275793eaSopenharmony_ci if (gz_zero(state, state->skip) == -1) 619275793eaSopenharmony_ci ret = state->err; 620275793eaSopenharmony_ci } 621275793eaSopenharmony_ci 622275793eaSopenharmony_ci /* flush, free memory, and close file */ 623275793eaSopenharmony_ci if (gz_comp(state, Z_FINISH) == -1) 624275793eaSopenharmony_ci ret = state->err; 625275793eaSopenharmony_ci if (state->size) { 626275793eaSopenharmony_ci if (!state->direct) { 627275793eaSopenharmony_ci (void)deflateEnd(&(state->strm)); 628275793eaSopenharmony_ci free(state->out); 629275793eaSopenharmony_ci } 630275793eaSopenharmony_ci free(state->in); 631275793eaSopenharmony_ci } 632275793eaSopenharmony_ci gz_error(state, Z_OK, NULL); 633275793eaSopenharmony_ci free(state->path); 634275793eaSopenharmony_ci if (close(state->fd) == -1) 635275793eaSopenharmony_ci ret = Z_ERRNO; 636275793eaSopenharmony_ci free(state); 637275793eaSopenharmony_ci return ret; 638275793eaSopenharmony_ci} 639