25int zu_can_read_file(
const char *fname) {
27 f = zu_open(fname,
"rb");
37ZUFILE *zu_open(
const char *fname,
const char *mode,
int type) {
40 if (!fname || strlen(fname) == 0) {
50 f->fname = strdup(fname);
52 if (type == ZU_COMPRESS_AUTO) {
53 char *p = strrchr(f->fname,
'.');
55 while (p !=
nullptr && *p !=
'\0' && i < 4) {
61 if (!strcmp(buf,
".gz")) {
62 f->type = ZU_COMPRESS_GZIP;
64 }
else if (!strcmp(buf,
".bz2") || !strcmp(buf,
".bz")) {
65 f->type = ZU_COMPRESS_BZIP;
68 f->type = ZU_COMPRESS_NONE;
76 case ZU_COMPRESS_NONE:
77 f->zfile = (
void *)fopen(f->fname, mode);
79 case ZU_COMPRESS_GZIP:
80 f->zfile = (
void *)gzopen(f->fname, mode);
82 case ZU_COMPRESS_BZIP:
83 f->faux = fopen(f->fname, mode);
86 f->zfile = (
void *)BZ2_bzReadOpen(&bzerror, f->faux, 0, 0,
nullptr, 0);
87 if (bzerror != BZ_OK) {
88 BZ2_bzReadClose(&bzerror, (BZFILE *)(f->zfile));
100 if (f->zfile ==
nullptr) {
109int zu_read(
ZUFILE *f,
void *buf,
long len) {
113 case ZU_COMPRESS_NONE:
114 nb = fread(buf, 1, len, (FILE *)(f->zfile));
116 case ZU_COMPRESS_GZIP:
117 nb = gzread((gzFile)(f->zfile), buf, len);
119 case ZU_COMPRESS_BZIP:
120 nb = BZ2_bzRead(&bzerror, (BZFILE *)(f->zfile), buf, len);
136 case ZU_COMPRESS_NONE:
137 fclose((FILE *)(f->zfile));
139 case ZU_COMPRESS_GZIP:
140 gzclose((gzFile)(f->zfile));
142 case ZU_COMPRESS_BZIP:
143 BZ2_bzReadClose(&bzerror, (BZFILE *)(f->zfile));
156long zu_tell(
ZUFILE *f) {
return f->pos; }
159long zu_filesize(
ZUFILE *f) {
161 FILE *ftmp = fopen(f->fname,
"rb");
163 fseek(ftmp, 0, SEEK_END);
171int zu_seek(
ZUFILE *f,
long offset,
int whence) {
174 if (whence == SEEK_END) {
179 case ZU_COMPRESS_NONE:
180 res = fseek((FILE *)(f->zfile), offset, whence);
181 f->pos = ftell((FILE *)(f->zfile));
183 case ZU_COMPRESS_GZIP:
184 if (whence == SEEK_SET) {
185 res = gzseek((gzFile)(f->zfile), offset, whence);
187 int p1 = gztell((gzFile)(f->zfile));
188 res = gzseek((gzFile)(f->zfile), p1 + offset, SEEK_SET);
190 f->pos = gztell((gzFile)(f->zfile));
191 if (res >= 0) res = 0;
193 case ZU_COMPRESS_BZIP:
194 if (whence == SEEK_SET && offset >= f->pos) {
195 res = zu_bzSeekForward(f, offset - f->pos);
196 }
else if (whence == SEEK_CUR) {
197 res = zu_bzSeekForward(f, offset);
199 BZ2_bzReadClose(&bzerror, (BZFILE *)(f->zfile));
203 f->zfile = (
void *)BZ2_bzReadOpen(&bzerror, f->faux, 0, 0,
nullptr, 0);
204 if (bzerror != BZ_OK) {
205 BZ2_bzReadClose(&bzerror, (BZFILE *)(f->zfile));
210 res = zu_bzSeekForward(f, offset);
218int zu_bzSeekForward(
ZUFILE *f,
unsigned long nbytes_)
221 unsigned long nbytes = nbytes_;
222 char buf[ZU_BUFREADSIZE];
223 unsigned long nbread = 0;
226 while (bzerror == BZ_OK && nbytes >= ZU_BUFREADSIZE) {
227 nb = BZ2_bzRead(&bzerror, (BZFILE *)(f->zfile), buf, ZU_BUFREADSIZE);
231 if (bzerror == BZ_OK && nbytes > 0) {
232 nb = BZ2_bzRead(&bzerror, (BZFILE *)(f->zfile), buf, nbytes);
237 return nbread == nbytes_ ? 0 : -1;
241void zu_rewind(
ZUFILE *f) { zu_seek(f, 0, SEEK_SET); }
Unified Compressed File Access System.