28int zu_can_read_file(
const char *fname) {
30 f = zu_open(fname,
"rb");
40ZUFILE *zu_open(
const char *fname,
const char *mode,
int type) {
43 if (!fname || strlen(fname) == 0) {
53 f->fname = strdup(fname);
55 if (type == ZU_COMPRESS_AUTO) {
56 char *p = strrchr(f->fname,
'.');
58 while (p !=
nullptr && *p !=
'\0' && i < 4) {
64 if (!strcmp(buf,
".gz")) {
65 f->type = ZU_COMPRESS_GZIP;
67 }
else if (!strcmp(buf,
".bz2") || !strcmp(buf,
".bz")) {
68 f->type = ZU_COMPRESS_BZIP;
71 f->type = ZU_COMPRESS_NONE;
79 case ZU_COMPRESS_NONE:
80 f->zfile = (
void *)fopen(f->fname, mode);
82 case ZU_COMPRESS_GZIP:
83 f->zfile = (
void *)gzopen(f->fname, mode);
85 case ZU_COMPRESS_BZIP:
86 f->faux = fopen(f->fname, mode);
89 f->zfile = (
void *)BZ2_bzReadOpen(&bzerror, f->faux, 0, 0,
nullptr, 0);
90 if (bzerror != BZ_OK) {
91 BZ2_bzReadClose(&bzerror, (BZFILE *)(f->zfile));
103 if (f->zfile ==
nullptr) {
112int zu_read(
ZUFILE *f,
void *buf,
long len) {
116 case ZU_COMPRESS_NONE:
117 nb = fread(buf, 1, len, (FILE *)(f->zfile));
119 case ZU_COMPRESS_GZIP:
120 nb = gzread((gzFile)(f->zfile), buf, len);
122 case ZU_COMPRESS_BZIP:
123 nb = BZ2_bzRead(&bzerror, (BZFILE *)(f->zfile), buf, len);
139 case ZU_COMPRESS_NONE:
140 fclose((FILE *)(f->zfile));
142 case ZU_COMPRESS_GZIP:
143 gzclose((gzFile)(f->zfile));
145 case ZU_COMPRESS_BZIP:
146 BZ2_bzReadClose(&bzerror, (BZFILE *)(f->zfile));
159long zu_tell(
ZUFILE *f) {
return f->pos; }
162long zu_filesize(
ZUFILE *f) {
164 FILE *ftmp = fopen(f->fname,
"rb");
166 fseek(ftmp, 0, SEEK_END);
174int zu_seek(
ZUFILE *f,
long offset,
int whence) {
177 if (whence == SEEK_END) {
182 case ZU_COMPRESS_NONE:
183 res = fseek((FILE *)(f->zfile), offset, whence);
184 f->pos = ftell((FILE *)(f->zfile));
186 case ZU_COMPRESS_GZIP:
187 if (whence == SEEK_SET) {
188 res = gzseek((gzFile)(f->zfile), offset, whence);
190 int p1 = gztell((gzFile)(f->zfile));
191 res = gzseek((gzFile)(f->zfile), p1 + offset, SEEK_SET);
193 f->pos = gztell((gzFile)(f->zfile));
194 if (res >= 0) res = 0;
196 case ZU_COMPRESS_BZIP:
197 if (whence == SEEK_SET && offset >= f->pos) {
198 res = zu_bzSeekForward(f, offset - f->pos);
199 }
else if (whence == SEEK_CUR) {
200 res = zu_bzSeekForward(f, offset);
202 BZ2_bzReadClose(&bzerror, (BZFILE *)(f->zfile));
206 f->zfile = (
void *)BZ2_bzReadOpen(&bzerror, f->faux, 0, 0,
nullptr, 0);
207 if (bzerror != BZ_OK) {
208 BZ2_bzReadClose(&bzerror, (BZFILE *)(f->zfile));
213 res = zu_bzSeekForward(f, offset);
221int zu_bzSeekForward(
ZUFILE *f,
unsigned long nbytes_)
224 unsigned long nbytes = nbytes_;
225 char buf[ZU_BUFREADSIZE];
226 unsigned long nbread = 0;
229 while (bzerror == BZ_OK && nbytes >= ZU_BUFREADSIZE) {
230 nb = BZ2_bzRead(&bzerror, (BZFILE *)(f->zfile), buf, ZU_BUFREADSIZE);
234 if (bzerror == BZ_OK && nbytes > 0) {
235 nb = BZ2_bzRead(&bzerror, (BZFILE *)(f->zfile), buf, nbytes);
240 return nbread == nbytes_ ? 0 : -1;
244void zu_rewind(
ZUFILE *f) { zu_seek(f, 0, SEEK_SET); }
std::string tolower(const std::string &input)
Return copy of s with all characters converted to lower case.
Unified Compressed File Access System.