25'ten fazla konu seçemezsiniz Konular bir harf veya rakamla başlamalı, kısa çizgiler ('-') içerebilir ve en fazla 35 karakter uzunluğunda olabilir.
 
 
 
 
 
 

228 satır
4.6 KiB

  1. /*
  2. * libcucul Canvas for ultrafast compositing of Unicode letters
  3. * Copyright (c) 2006-2007 Sam Hocevar <sam@zoy.org>
  4. * All Rights Reserved
  5. *
  6. * $Id$
  7. *
  8. * This library is free software. It comes without any warranty, to
  9. * the extent permitted by applicable law. You can redistribute it
  10. * and/or modify it under the terms of the Do What The Fuck You Want
  11. * To Public License, Version 2, as published by Sam Hocevar. See
  12. * http://sam.zoy.org/wtfpl/COPYING for more details.
  13. */
  14. /*
  15. * This file contains functions for compressed file I/O.
  16. */
  17. #include "config.h"
  18. #include "common.h"
  19. #if !defined __KERNEL__
  20. # include <stdio.h>
  21. # include <stdlib.h>
  22. # include <string.h>
  23. # if defined HAVE_ZLIB_H
  24. # include <zlib.h>
  25. # define READSIZE 128 /* Read buffer size */
  26. # define WRITESIZE 128 /* Inflate buffer size */
  27. # endif
  28. #endif
  29. #include "cucul.h"
  30. #include "cucul_internals.h"
  31. #if !defined __KERNEL__ && defined HAVE_ZLIB_H
  32. static int zipread(cucul_file_t *, void *, unsigned int);
  33. #endif
  34. #if !defined __KERNEL__
  35. struct cucul_file
  36. {
  37. # if defined HAVE_ZLIB_H
  38. unsigned char read_buffer[READSIZE];
  39. z_stream stream;
  40. gzFile gz;
  41. int eof, zip;
  42. # endif
  43. FILE *f;
  44. };
  45. #endif
  46. cucul_file_t *_cucul_file_open(char const *path, const char *mode)
  47. {
  48. #if defined __KERNEL__
  49. return NULL;
  50. #else
  51. cucul_file_t *fp = malloc(sizeof(*fp));
  52. # if defined HAVE_ZLIB_H
  53. uint8_t buf[4];
  54. unsigned int skip_size = 0;
  55. fp->gz = gzopen(path, "rb");
  56. if(!fp->gz)
  57. {
  58. free(fp);
  59. return NULL;
  60. }
  61. fp->eof = 0;
  62. fp->zip = 0;
  63. /* Parse ZIP file and go to start of first file */
  64. gzread(fp->gz, buf, 4);
  65. if(memcmp(buf, "PK\3\4", 4))
  66. {
  67. gzseek(fp->gz, 0, SEEK_SET);
  68. return fp;
  69. }
  70. fp->zip = 1;
  71. gzseek(fp->gz, 22, SEEK_CUR);
  72. gzread(fp->gz, buf, 2); /* Filename size */
  73. skip_size += (uint16_t)buf[0] | ((uint16_t)buf[1] << 8);
  74. gzread(fp->gz, buf, 2); /* Extra field size */
  75. skip_size += (uint16_t)buf[0] | ((uint16_t)buf[1] << 8);
  76. gzseek(fp->gz, skip_size, SEEK_CUR);
  77. /* Initialise inflate stream */
  78. fp->stream.total_out = 0;
  79. fp->stream.zalloc = NULL;
  80. fp->stream.zfree = NULL;
  81. fp->stream.opaque = NULL;
  82. fp->stream.next_in = NULL;
  83. fp->stream.avail_in = 0;
  84. if(inflateInit2(&fp->stream, -MAX_WBITS))
  85. {
  86. free(fp);
  87. gzclose(fp->gz);
  88. return NULL;
  89. }
  90. # else
  91. fp->f = fopen(path, mode);
  92. if(!fp->f)
  93. {
  94. free(fp);
  95. return NULL;
  96. }
  97. # endif
  98. return fp;
  99. #endif
  100. }
  101. int _cucul_file_close(cucul_file_t *fp)
  102. {
  103. #if defined __KERNEL__
  104. return 0;
  105. #elif defined HAVE_ZLIB_H
  106. gzFile gz = fp->gz;
  107. if(fp->zip)
  108. inflateEnd(&fp->stream);
  109. free(fp);
  110. return gzclose(gz);
  111. #else
  112. FILE *f = fp->f;
  113. free(fp);
  114. return fclose(f);
  115. #endif
  116. }
  117. int _cucul_file_eof(cucul_file_t *fp)
  118. {
  119. #if defined __KERNEL__
  120. return 1;
  121. #elif defined HAVE_ZLIB_H
  122. return fp->zip ? fp->eof : gzeof(fp->gz);
  123. #else
  124. return feof(fp->f);
  125. #endif
  126. }
  127. char *_cucul_file_gets(char *s, int size, cucul_file_t *fp)
  128. {
  129. #if defined __KERNEL__
  130. return NULL;
  131. #elif defined HAVE_ZLIB_H
  132. if(fp->zip)
  133. {
  134. int i;
  135. for(i = 0; i < size; i++)
  136. {
  137. int ret = zipread(fp, s + i, 1);
  138. if(ret < 0)
  139. return NULL;
  140. if(ret == 0 || s[i] == '\n')
  141. {
  142. if(i + 1 < size)
  143. s[i + 1] = '\0';
  144. return s;
  145. }
  146. }
  147. return s;
  148. }
  149. return gzgets(fp->gz, s, size);
  150. #else
  151. return fgets(s, size, fp->f);
  152. #endif
  153. }
  154. #if !defined __KERNEL__ && defined HAVE_ZLIB_H
  155. static int zipread(cucul_file_t *fp, void *buf, unsigned int len)
  156. {
  157. unsigned int total_read = 0;
  158. if(len == 0)
  159. return 0;
  160. fp->stream.next_out = buf;
  161. fp->stream.avail_out = len;
  162. while(fp->stream.avail_out > 0)
  163. {
  164. unsigned int tmp;
  165. int ret = 0;
  166. if(fp->stream.avail_in == 0 && !gzeof(fp->gz))
  167. {
  168. int bytes_read;
  169. bytes_read = gzread(fp->gz, fp->read_buffer, READSIZE);
  170. if(bytes_read < 0)
  171. return -1;
  172. fp->stream.next_in = fp->read_buffer;
  173. fp->stream.avail_in = bytes_read;
  174. }
  175. tmp = fp->stream.total_out;
  176. ret = inflate(&fp->stream, Z_SYNC_FLUSH);
  177. total_read += fp->stream.total_out - tmp;
  178. if(ret == Z_STREAM_END)
  179. {
  180. fp->eof = 1;
  181. return total_read;
  182. }
  183. if(ret != Z_OK)
  184. return ret;
  185. }
  186. return total_read;
  187. }
  188. #endif