| #include "bsfile.h" | |
| #include "bsport.h" | |
| #include "bzlib.h" | |
| #include "bzlib_private.h" | |
| #include "Typedef.h" | |
| #define BZ_SETERR(eee) \ | |
| { \ | |
| if (bzerror != NULL) *bzerror = eee; \ | |
| if (bzf != NULL) bzf->lastErr = eee; \ | |
| } | |
| typedef | |
| struct { | |
| BFILE* handle; | |
| Char buf[BZ_MAX_UNUSED]; | |
| Int32 bufN; | |
| Bool writing; | |
| bz_stream strm; | |
| Int32 lastErr; | |
| Bool initialisedOk; | |
| } | |
| bzFile; | |
| /*---------------------------------------------*/ | |
| static Bool myfeof ( BFILE* f ) | |
| { | |
| if(f->ridx == f->size) return True; | |
| return False; | |
| } | |
| int bferror( BFILE *f ) | |
| { | |
| (void)f; | |
| return 0; | |
| } | |
| int bfread(void * buffer, int size, int count, BFILE* f) | |
| { | |
| int readsize = f->size - f->ridx; | |
| if ( (count * size) < readsize ) | |
| readsize = count * size; | |
| memcpy( buffer, f->buf + f->ridx, readsize ); | |
| f->ridx += readsize; | |
| return( readsize ); | |
| } | |
| BFILE * bfopen(char *buf, unsigned int size) | |
| { | |
| BFILE *f; | |
| f = malloc(sizeof(BFILE)); | |
| f->buf = buf; | |
| f->ridx = 0; | |
| f->size = size; | |
| } | |
| int bfclose(BFILE *f) | |
| { | |
| if(f) | |
| free(f); | |
| return 0; | |
| } | |
| /*---------------------------------------------------*/ | |
| BZFILE* BZ_API(BZ2_bzReadOpen) | |
| ( int* bzerror, | |
| BFILE* f, | |
| int verbosity, | |
| int small, | |
| void* unused, | |
| int nUnused ) | |
| { | |
| bzFile* bzf = NULL; | |
| int ret; | |
| BZ_SETERR(BZ_OK); | |
| if (f == NULL || | |
| (small != 0 && small != 1) || | |
| (verbosity < 0 || verbosity > 4) || | |
| (unused == NULL && nUnused != 0) || | |
| (unused != NULL && (nUnused < 0 || nUnused > BZ_MAX_UNUSED))) | |
| { BZ_SETERR(BZ_PARAM_ERROR); return NULL; }; | |
| if (bferror(f)) | |
| { BZ_SETERR(BZ_IO_ERROR); return NULL; }; | |
| bzf = malloc ( sizeof(bzFile) ); | |
| if (bzf == NULL) | |
| { BZ_SETERR(BZ_MEM_ERROR); return NULL; }; | |
| BZ_SETERR(BZ_OK); | |
| bzf->initialisedOk = False; | |
| bzf->handle = f; | |
| bzf->bufN = 0; | |
| bzf->writing = False; | |
| bzf->strm.bzalloc = NULL; | |
| bzf->strm.bzfree = NULL; | |
| bzf->strm.opaque = NULL; | |
| while (nUnused > 0) { | |
| bzf->buf[bzf->bufN] = *((UChar*)(unused)); bzf->bufN++; | |
| unused = ((void*)( 1 + ((UChar*)(unused)) )); | |
| nUnused--; | |
| } | |
| ret = BZ2_bzDecompressInit ( &(bzf->strm), verbosity, small ); | |
| if (ret != BZ_OK) | |
| { BZ_SETERR(ret); free(bzf); return NULL; }; | |
| bzf->strm.avail_in = bzf->bufN; | |
| bzf->strm.next_in = bzf->buf; | |
| bzf->initialisedOk = True; | |
| return bzf; | |
| } | |
| /*---------------------------------------------------*/ | |
| void BZ_API(BZ2_bzReadClose) ( int *bzerror, BZFILE *b ) | |
| { | |
| bzFile* bzf = (bzFile*)b; | |
| BZ_SETERR(BZ_OK); | |
| if (bzf == NULL) | |
| { BZ_SETERR(BZ_OK); return; }; | |
| if (bzf->writing) | |
| { BZ_SETERR(BZ_SEQUENCE_ERROR); return; }; | |
| if (bzf->initialisedOk) | |
| (void)BZ2_bzDecompressEnd ( &(bzf->strm) ); | |
| free ( bzf ); | |
| } | |
| /*---------------------------------------------------*/ | |
| int BZ_API(BZ2_bzRead) | |
| ( int* bzerror, | |
| BZFILE* b, | |
| void* buf, | |
| int len ) | |
| { | |
| Int32 n, ret; | |
| bzFile* bzf = (bzFile*)b; | |
| BZ_SETERR(BZ_OK); | |
| if (bzf == NULL || buf == NULL || len < 0) | |
| { BZ_SETERR(BZ_PARAM_ERROR); return 0; }; | |
| if (bzf->writing) | |
| { BZ_SETERR(BZ_SEQUENCE_ERROR); return 0; }; | |
| if (len == 0) | |
| { BZ_SETERR(BZ_OK); return 0; }; | |
| bzf->strm.avail_out = len; | |
| bzf->strm.next_out = buf; | |
| while (True) { | |
| if (bferror(bzf->handle)) | |
| { BZ_SETERR(BZ_IO_ERROR); return 0; }; | |
| if (bzf->strm.avail_in == 0 && !myfeof(bzf->handle)) { | |
| n = bfread ( bzf->buf, sizeof(UChar), | |
| BZ_MAX_UNUSED, bzf->handle ); | |
| if (bferror(bzf->handle)) | |
| { BZ_SETERR(BZ_IO_ERROR); return 0; }; | |
| bzf->bufN = n; | |
| bzf->strm.avail_in = bzf->bufN; | |
| bzf->strm.next_in = bzf->buf; | |
| } | |
| ret = BZ2_bzDecompress ( &(bzf->strm) ); | |
| if (ret != BZ_OK && ret != BZ_STREAM_END) | |
| { BZ_SETERR(ret); return 0; }; | |
| if (ret == BZ_OK && myfeof(bzf->handle) && | |
| bzf->strm.avail_in == 0 && bzf->strm.avail_out > 0) | |
| { BZ_SETERR(BZ_UNEXPECTED_EOF); return 0; }; | |
| if (ret == BZ_STREAM_END) | |
| { BZ_SETERR(BZ_STREAM_END); | |
| return len - bzf->strm.avail_out; }; | |
| if (bzf->strm.avail_out == 0) | |
| { BZ_SETERR(BZ_OK); return len; }; | |
| } | |
| return 0; /*not reached*/ | |
| } |