TTKMusicPlayer  3.7.0.0
TTKMusicPlayer imitates Kugou UI, the music player uses of qmmp core library based on Qt for windows and linux
gzlib.c
Go to the documentation of this file.
1 /* gzlib.c -- zlib functions common to reading and writing gzip files
2  * Copyright (C) 2004-2024 Mark Adler
3  * For conditions of distribution and use, see copyright notice in zlib.h
4  */
5 
6 #include "gzguts.h"
7 
8 #if defined(_WIN32) && !defined(__BORLANDC__)
9 # define LSEEK _lseeki64
10 #else
11 #if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0
12 # define LSEEK lseek64
13 #else
14 # define LSEEK lseek
15 #endif
16 #endif
17 
18 #if defined UNDER_CE
19 
20 /* Map the Windows error number in ERROR to a locale-dependent error message
21  string and return a pointer to it. Typically, the values for ERROR come
22  from GetLastError.
23 
24  The string pointed to shall not be modified by the application, but may be
25  overwritten by a subsequent call to gz_strwinerror
26 
27  The gz_strwinerror function does not change the current setting of
28  GetLastError. */
29 char ZLIB_INTERNAL *gz_strwinerror(DWORD error) {
30  static char buf[1024];
31 
32  wchar_t *msgbuf;
33  DWORD lasterr = GetLastError();
34  DWORD chars = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM
35  | FORMAT_MESSAGE_ALLOCATE_BUFFER,
36  NULL,
37  error,
38  0, /* Default language */
39  (LPVOID)&msgbuf,
40  0,
41  NULL);
42  if (chars != 0) {
43  /* If there is an \r\n appended, zap it. */
44  if (chars >= 2
45  && msgbuf[chars - 2] == '\r' && msgbuf[chars - 1] == '\n') {
46  chars -= 2;
47  msgbuf[chars] = 0;
48  }
49 
50  if (chars > sizeof (buf) - 1) {
51  chars = sizeof (buf) - 1;
52  msgbuf[chars] = 0;
53  }
54 
55  wcstombs(buf, msgbuf, chars + 1);
56  LocalFree(msgbuf);
57  }
58  else {
59  sprintf(buf, "unknown win32 error (%ld)", error);
60  }
61 
62  SetLastError(lasterr);
63  return buf;
64 }
65 
66 #endif /* UNDER_CE */
67 
68 /* Reset gzip file state */
70  state->x.have = 0; /* no output data available */
71  if (state->mode == GZ_READ) { /* for reading ... */
72  state->eof = 0; /* not at end of file */
73  state->past = 0; /* have not read past end yet */
74  state->how = LOOK; /* look for gzip header */
75  }
76  else /* for writing ... */
77  state->reset = 0; /* no deflateReset pending */
78  state->seek = 0; /* no seek request pending */
79  gz_error(state, Z_OK, NULL); /* clear error */
80  state->x.pos = 0; /* no uncompressed data yet */
81  state->strm.avail_in = 0; /* no input data yet */
82 }
83 
84 /* Open a gzip file either by name or file descriptor. */
85 local gzFile gz_open(const void *path, int fd, const char *mode) {
87  z_size_t len;
88  int oflag;
89 #ifdef O_CLOEXEC
90  int cloexec = 0;
91 #endif
92 #ifdef O_EXCL
93  int exclusive = 0;
94 #endif
95 
96  /* check input */
97  if (path == NULL)
98  return NULL;
99 
100  /* allocate gzFile structure to return */
101  state = (gz_statep)malloc(sizeof(gz_state));
102  if (state == NULL)
103  return NULL;
104  state->size = 0; /* no buffers allocated yet */
105  state->want = GZBUFSIZE; /* requested buffer size */
106  state->msg = NULL; /* no error message yet */
107 
108  /* interpret mode */
109  state->mode = GZ_NONE;
110  state->level = Z_DEFAULT_COMPRESSION;
111  state->strategy = Z_DEFAULT_STRATEGY;
112  state->direct = 0;
113  while (*mode) {
114  if (*mode >= '0' && *mode <= '9')
115  state->level = *mode - '0';
116  else
117  switch (*mode) {
118  case 'r':
119  state->mode = GZ_READ;
120  break;
121 #ifndef NO_GZCOMPRESS
122  case 'w':
123  state->mode = GZ_WRITE;
124  break;
125  case 'a':
126  state->mode = GZ_APPEND;
127  break;
128 #endif
129  case '+': /* can't read and write at the same time */
130  free(state);
131  return NULL;
132  case 'b': /* ignore -- will request binary anyway */
133  break;
134 #ifdef O_CLOEXEC
135  case 'e':
136  cloexec = 1;
137  break;
138 #endif
139 #ifdef O_EXCL
140  case 'x':
141  exclusive = 1;
142  break;
143 #endif
144  case 'f':
145  state->strategy = Z_FILTERED;
146  break;
147  case 'h':
148  state->strategy = Z_HUFFMAN_ONLY;
149  break;
150  case 'R':
151  state->strategy = Z_RLE;
152  break;
153  case 'F':
154  state->strategy = Z_FIXED;
155  break;
156  case 'T':
157  state->direct = 1;
158  break;
159  default: /* could consider as an error, but just ignore */
160  ;
161  }
162  mode++;
163  }
164 
165  /* must provide an "r", "w", or "a" */
166  if (state->mode == GZ_NONE) {
167  free(state);
168  return NULL;
169  }
170 
171  /* can't force transparent read */
172  if (state->mode == GZ_READ) {
173  if (state->direct) {
174  free(state);
175  return NULL;
176  }
177  state->direct = 1; /* for empty file */
178  }
179 
180  /* save the path name for error messages */
181 #ifdef WIDECHAR
182  if (fd == -2) {
183  len = wcstombs(NULL, path, 0);
184  if (len == (z_size_t)-1)
185  len = 0;
186  }
187  else
188 #endif
189  len = strlen((const char *)path);
190  state->path = (char *)malloc(len + 1);
191  if (state->path == NULL) {
192  free(state);
193  return NULL;
194  }
195 #ifdef WIDECHAR
196  if (fd == -2)
197  if (len)
198  wcstombs(state->path, path, len + 1);
199  else
200  *(state->path) = 0;
201  else
202 #endif
203 #if !defined(NO_snprintf) && !defined(NO_vsnprintf)
204  (void)snprintf(state->path, len + 1, "%s", (const char *)path);
205 #else
206  strcpy(state->path, path);
207 #endif
208 
209  /* compute the flags for open() */
210  oflag =
211 #ifdef O_LARGEFILE
212  O_LARGEFILE |
213 #endif
214 #ifdef O_BINARY
215  O_BINARY |
216 #endif
217 #ifdef O_CLOEXEC
218  (cloexec ? O_CLOEXEC : 0) |
219 #endif
220  (state->mode == GZ_READ ?
221  O_RDONLY :
222  (O_WRONLY | O_CREAT |
223 #ifdef O_EXCL
224  (exclusive ? O_EXCL : 0) |
225 #endif
226  (state->mode == GZ_WRITE ?
227  O_TRUNC :
228  O_APPEND)));
229 
230  /* open the file with the appropriate flags (or just use fd) */
231  state->fd = fd > -1 ? fd : (
232 #ifdef WIDECHAR
233  fd == -2 ? _wopen(path, oflag, 0666) :
234 #endif
235  open((const char *)path, oflag, 0666));
236  if (state->fd == -1) {
237  free(state->path);
238  free(state);
239  return NULL;
240  }
241  if (state->mode == GZ_APPEND) {
242  LSEEK(state->fd, 0, SEEK_END); /* so gzoffset() is correct */
243  state->mode = GZ_WRITE; /* simplify later checks */
244  }
245 
246  /* save the current position for rewinding (only if reading) */
247  if (state->mode == GZ_READ) {
248  state->start = LSEEK(state->fd, 0, SEEK_CUR);
249  if (state->start == -1) state->start = 0;
250  }
251 
252  /* initialize stream */
253  gz_reset(state);
254 
255  /* return stream */
256  return (gzFile)state;
257 }
258 
259 /* -- see zlib.h -- */
260 gzFile ZEXPORT gzopen(const char *path, const char *mode) {
261  return gz_open(path, -1, mode);
262 }
263 
264 /* -- see zlib.h -- */
265 gzFile ZEXPORT gzopen64(const char *path, const char *mode) {
266  return gz_open(path, -1, mode);
267 }
268 
269 /* -- see zlib.h -- */
270 gzFile ZEXPORT gzdopen(int fd, const char *mode) {
271  char *path; /* identifier for error messages */
272  gzFile gz;
273 
274  if (fd == -1 || (path = (char *)malloc(7 + 3 * sizeof(int))) == NULL)
275  return NULL;
276 #if !defined(NO_snprintf) && !defined(NO_vsnprintf)
277  (void)snprintf(path, 7 + 3 * sizeof(int), "<fd:%d>", fd);
278 #else
279  sprintf(path, "<fd:%d>", fd); /* for debugging */
280 #endif
281  gz = gz_open(path, fd, mode);
282  free(path);
283  return gz;
284 }
285 
286 /* -- see zlib.h -- */
287 #ifdef WIDECHAR
288 gzFile ZEXPORT gzopen_w(const wchar_t *path, const char *mode) {
289  return gz_open(path, -2, mode);
290 }
291 #endif
292 
293 /* -- see zlib.h -- */
294 int ZEXPORT gzbuffer(gzFile file, unsigned size) {
296 
297  /* get internal structure and check integrity */
298  if (file == NULL)
299  return -1;
300  state = (gz_statep)file;
301  if (state->mode != GZ_READ && state->mode != GZ_WRITE)
302  return -1;
303 
304  /* make sure we haven't already allocated memory */
305  if (state->size != 0)
306  return -1;
307 
308  /* check and set requested size */
309  if ((size << 1) < size)
310  return -1; /* need to be able to double it */
311  if (size < 8)
312  size = 8; /* needed to behave well with flushing */
313  state->want = size;
314  return 0;
315 }
316 
317 /* -- see zlib.h -- */
320 
321  /* get internal structure */
322  if (file == NULL)
323  return -1;
324  state = (gz_statep)file;
325 
326  /* check that we're reading and that there's no error */
327  if (state->mode != GZ_READ ||
328  (state->err != Z_OK && state->err != Z_BUF_ERROR))
329  return -1;
330 
331  /* back up and start over */
332  if (LSEEK(state->fd, state->start, SEEK_SET) == -1)
333  return -1;
334  gz_reset(state);
335  return 0;
336 }
337 
338 /* -- see zlib.h -- */
340  unsigned n;
341  z_off64_t ret;
343 
344  /* get internal structure and check integrity */
345  if (file == NULL)
346  return -1;
347  state = (gz_statep)file;
348  if (state->mode != GZ_READ && state->mode != GZ_WRITE)
349  return -1;
350 
351  /* check that there's no error */
352  if (state->err != Z_OK && state->err != Z_BUF_ERROR)
353  return -1;
354 
355  /* can only seek from start or relative to current position */
356  if (whence != SEEK_SET && whence != SEEK_CUR)
357  return -1;
358 
359  /* normalize offset to a SEEK_CUR specification */
360  if (whence == SEEK_SET)
361  offset -= state->x.pos;
362  else if (state->seek)
363  offset += state->skip;
364  state->seek = 0;
365 
366  /* if within raw area while reading, just go there */
367  if (state->mode == GZ_READ && state->how == COPY &&
368  state->x.pos + offset >= 0) {
369  ret = LSEEK(state->fd, offset - (z_off64_t)state->x.have, SEEK_CUR);
370  if (ret == -1)
371  return -1;
372  state->x.have = 0;
373  state->eof = 0;
374  state->past = 0;
375  state->seek = 0;
376  gz_error(state, Z_OK, NULL);
377  state->strm.avail_in = 0;
378  state->x.pos += offset;
379  return state->x.pos;
380  }
381 
382  /* calculate skip amount, rewinding if needed for back seek when reading */
383  if (offset < 0) {
384  if (state->mode != GZ_READ) /* writing -- can't go backwards */
385  return -1;
386  offset += state->x.pos;
387  if (offset < 0) /* before start of file! */
388  return -1;
389  if (gzrewind(file) == -1) /* rewind, then skip to offset */
390  return -1;
391  }
392 
393  /* if reading, skip what's in output buffer (one less gzgetc() check) */
394  if (state->mode == GZ_READ) {
395  n = GT_OFF(state->x.have) || (z_off64_t)state->x.have > offset ?
396  (unsigned)offset : state->x.have;
397  state->x.have -= n;
398  state->x.next += n;
399  state->x.pos += n;
400  offset -= n;
401  }
402 
403  /* request skip (if not zero) */
404  if (offset) {
405  state->seek = 1;
406  state->skip = offset;
407  }
408  return state->x.pos + offset;
409 }
410 
411 /* -- see zlib.h -- */
413  z_off64_t ret;
414 
415  ret = gzseek64(file, (z_off64_t)offset, whence);
416  return ret == (z_off_t)ret ? (z_off_t)ret : -1;
417 }
418 
419 /* -- see zlib.h -- */
422 
423  /* get internal structure and check integrity */
424  if (file == NULL)
425  return -1;
426  state = (gz_statep)file;
427  if (state->mode != GZ_READ && state->mode != GZ_WRITE)
428  return -1;
429 
430  /* return position */
431  return state->x.pos + (state->seek ? state->skip : 0);
432 }
433 
434 /* -- see zlib.h -- */
436  z_off64_t ret;
437 
438  ret = gztell64(file);
439  return ret == (z_off_t)ret ? (z_off_t)ret : -1;
440 }
441 
442 /* -- see zlib.h -- */
446 
447  /* get internal structure and check integrity */
448  if (file == NULL)
449  return -1;
450  state = (gz_statep)file;
451  if (state->mode != GZ_READ && state->mode != GZ_WRITE)
452  return -1;
453 
454  /* compute and return effective offset in file */
455  offset = LSEEK(state->fd, 0, SEEK_CUR);
456  if (offset == -1)
457  return -1;
458  if (state->mode == GZ_READ) /* reading */
459  offset -= state->strm.avail_in; /* don't count buffered input */
460  return offset;
461 }
462 
463 /* -- see zlib.h -- */
465  z_off64_t ret;
466 
467  ret = gzoffset64(file);
468  return ret == (z_off_t)ret ? (z_off_t)ret : -1;
469 }
470 
471 /* -- see zlib.h -- */
472 int ZEXPORT gzeof(gzFile file) {
474 
475  /* get internal structure and check integrity */
476  if (file == NULL)
477  return 0;
478  state = (gz_statep)file;
479  if (state->mode != GZ_READ && state->mode != GZ_WRITE)
480  return 0;
481 
482  /* return end-of-file state */
483  return state->mode == GZ_READ ? state->past : 0;
484 }
485 
486 /* -- see zlib.h -- */
487 const char * ZEXPORT gzerror(gzFile file, int *errnum) {
489 
490  /* get internal structure and check integrity */
491  if (file == NULL)
492  return NULL;
493  state = (gz_statep)file;
494  if (state->mode != GZ_READ && state->mode != GZ_WRITE)
495  return NULL;
496 
497  /* return error information */
498  if (errnum != NULL)
499  *errnum = state->err;
500  return state->err == Z_MEM_ERROR ? "out of memory" :
501  (state->msg == NULL ? "" : state->msg);
502 }
503 
504 /* -- see zlib.h -- */
507 
508  /* get internal structure and check integrity */
509  if (file == NULL)
510  return;
511  state = (gz_statep)file;
512  if (state->mode != GZ_READ && state->mode != GZ_WRITE)
513  return;
514 
515  /* clear error and end-of-file */
516  if (state->mode == GZ_READ) {
517  state->eof = 0;
518  state->past = 0;
519  }
520  gz_error(state, Z_OK, NULL);
521 }
522 
523 /* Create an error message in allocated memory and set state->err and
524  state->msg accordingly. Free any previous error message already there. Do
525  not try to free or allocate space if the error is Z_MEM_ERROR (out of
526  memory). Simply save the error message as a static string. If there is an
527  allocation failure constructing the error message, then convert the error to
528  out of memory. */
529 void ZLIB_INTERNAL gz_error(gz_statep state, int err, const char *msg) {
530  /* free previously allocated message and clear */
531  if (state->msg != NULL) {
532  if (state->err != Z_MEM_ERROR)
533  free(state->msg);
534  state->msg = NULL;
535  }
536 
537  /* if fatal, set state->x.have to 0 so that the gzgetc() macro fails */
538  if (err != Z_OK && err != Z_BUF_ERROR)
539  state->x.have = 0;
540 
541  /* set error code, and if no message, then done */
542  state->err = err;
543  if (msg == NULL)
544  return;
545 
546  /* for an out of memory error, return literal string when requested */
547  if (err == Z_MEM_ERROR)
548  return;
549 
550  /* construct error message with path */
551  if ((state->msg = (char *)malloc(strlen(state->path) + strlen(msg) + 3)) ==
552  NULL) {
553  state->err = Z_MEM_ERROR;
554  return;
555  }
556 #if !defined(NO_snprintf) && !defined(NO_vsnprintf)
557  (void)snprintf(state->msg, strlen(state->path) + strlen(msg) + 3,
558  "%s%s%s", state->path, ": ", msg);
559 #else
560  strcpy(state->msg, state->path);
561  strcat(state->msg, ": ");
562  strcat(state->msg, msg);
563 #endif
564 }
565 
566 /* portably return maximum value for an int (when limits.h presumed not
567  available) -- we need to do this to cover cases where 2's complement not
568  used, since C standard permits 1's complement and sign-bit representations,
569  otherwise we could just use ((unsigned)-1) >> 1 */
570 unsigned ZLIB_INTERNAL gz_intmax(void) {
571 #ifdef INT_MAX
572  return INT_MAX;
573 #else
574  unsigned p = 1, q;
575  do {
576  q = p;
577  p <<= 1;
578  p++;
579  } while (p > q);
580  return q >> 1;
581 #endif
582 }
unsigned long z_size_t
Definition: zconf.h:257
Definition: inflate.h:36
#define GZ_NONE
Definition: gzguts.h:158
int ZEXPORT gzeof(gzFile file)
Definition: gzlib.c:472
#define z_off_t
Definition: zconf.h:513
#define GT_OFF(x)
Definition: gzguts.h:214
z_off64_t ZEXPORT gzoffset64(gzFile file)
Definition: gzlib.c:443
#define GZ_APPEND
Definition: gzguts.h:161
#define GZ_READ
Definition: gzguts.h:159
#define z_off64_t
Definition: zconf.h:522
voidpf void uLong size
Definition: ioapi.h:136
z_off_t ZEXPORT gztell(gzFile file)
Definition: gzlib.c:435
#define ZLIB_INTERNAL
Definition: compress.c:8
#define Z_FILTERED
Definition: zlib.h:196
z_off64_t pos
Definition: zlib.h:1840
#define Z_FIXED
Definition: zlib.h:199
unsigned ZLIB_INTERNAL gz_intmax(void)
Definition: gzlib.c:570
voidpf void * buf
Definition: ioapi.h:136
int ZEXPORT gzrewind(gzFile file)
Definition: gzlib.c:318
z_off64_t ZEXPORT gztell64(gzFile file)
Definition: gzlib.c:420
z_off_t ZEXPORT gzseek(gzFile file, z_off_t offset, int whence)
Definition: gzlib.c:412
voidpf uLong offset
Definition: ioapi.h:142
void ZLIB_INTERNAL gz_error(gz_statep state, int err, const char *msg)
Definition: gzlib.c:529
local gzFile gz_open(const void *path, int fd, const char *mode)
Definition: gzlib.c:85
#define SEEK_END
Definition: zip.c:84
int ZEXPORT gzbuffer(gzFile file, unsigned size)
Definition: gzlib.c:294
#define GZ_WRITE
Definition: gzguts.h:160
#define LSEEK
Definition: gzlib.c:14
#define SEEK_CUR
Definition: zip.c:80
gzFile ZEXPORT gzdopen(int fd, const char *mode)
Definition: gzlib.c:270
#define local
Definition: unzip.c:91
#define Z_MEM_ERROR
Definition: zlib.h:183
#define SEEK_SET
Definition: zip.c:88
z_off_t ZEXPORT gzoffset(gzFile file)
Definition: gzlib.c:464
#define Z_HUFFMAN_ONLY
Definition: zlib.h:197
gzFile ZEXPORT gzopen(const char *path, const char *mode)
Definition: gzlib.c:260
const char *ZEXPORT gzerror(gzFile file, int *errnum)
Definition: gzlib.c:487
#define LOOK
Definition: gzguts.h:164
local void gz_reset(gz_statep state)
Definition: gzlib.c:69
#define GZBUFSIZE
Definition: gzguts.h:155
void ZEXPORT gzclearerr(gzFile file)
Definition: gzlib.c:505
#define Z_BUF_ERROR
Definition: zlib.h:184
#define Z_OK
Definition: zlib.h:177
void free(voidpf ptr)
const char int mode
Definition: ioapi.h:135
gz_state FAR * gz_statep
Definition: gzguts.h:202
#define Z_DEFAULT_STRATEGY
Definition: zlib.h:200
gzFile ZEXPORT gzopen64(const char *path, const char *mode)
Definition: gzlib.c:265
voidp malloc(uInt size)
z_off64_t ZEXPORT gzseek64(gzFile file, z_off64_t offset, int whence)
Definition: gzlib.c:339
#define ZEXPORT
Definition: zconf.h:382
state
Definition: http_parser.c:279
#define Z_DEFAULT_COMPRESSION
Definition: zlib.h:193
#define Z_RLE
Definition: zlib.h:198