Code for supporting direct usage of file streams (FILE *)
Closed this issue · 1 comments
crudelios commented
I've changed my version of the lib to add support to use already opened file streams, which is also already supported by miniz.
The reason I did this is because my app uses android, which gets the streams from the java side (so no fopen
) and storing everything on ram would take up way too much useless space (the app also runs on old hardware and psvita which doesn't have much ram available).
Anyway, feel free to add this if you want.
Also, sorry for not providing a PR, but I didn't clone the repo, I just directly added the changes to my own app.
Thanks for the amazing library!
/**
* Opens zip archive from existing FILE stream with compression level using the given mode.
* The stream will not be closed when calling zip_close.
*
* @param cstream C File stream.
* @param level compression level (0-9 are the standard zlib-style levels).
* @param mode file access mode. This mode should be equivalent to the mode provided when opening the file.
* - 'r': opens a file for reading/extracting (the file must exists).
* - 'w': creates an empty file for writing.
* - 'a': appends to an existing archive.
*
* @return the zip archive handler or NULL on error
*/
struct zip_t *zip_cstream_open(FILE *cstream, int level, char mode) {
int errnum = 0;
return zip_cstream_openwitherror(cstream, level, mode, &errnum);
}
/**
* Opens zip archive from existing FILE stream with compression level using the given mode.
* The function additionally returns @param errnum -
* The stream will not be closed when calling zip_close.
*
* @param cstream C File stream.
* @param level compression level (0-9 are the standard zlib-style levels).
* @param mode file access mode.
* - 'r': opens a file for reading/extracting (the file must exists).
* - 'w': creates an empty file for writing.
* - 'a': appends to an existing archive.
* @param errnum 0 on success, negative number (< 0) on error.
*
* @return the zip archive handler or NULL on error
*/
struct zip_t *zip_cstream_openwitherror(FILE *cstream, int level, char mode,
int *errnum) {
struct zip_t *zip = NULL;
*errnum = 0;
if (!cstream) {
// cstream not valid
*errnum = ZIP_ENOFILE;
goto cleanup;
}
if (level < 0)
level = MZ_DEFAULT_LEVEL;
if ((level & 0xF) > MZ_UBER_COMPRESSION) {
// Wrong compression level
*errnum = ZIP_EINVLVL;
goto cleanup;
}
zip = (struct zip_t *)calloc((size_t)1, sizeof(struct zip_t));
if (!zip) {
// out of memory
*errnum = ZIP_EOOMEM;
goto cleanup;
}
zip->level = (mz_uint) level;
switch (mode) {
case 'w':
// Create a new archive.
if (!mz_zip_writer_init_cfile(&(zip->archive), cstream,
MZ_ZIP_FLAG_WRITE_ZIP64)) {
// Cannot initialize zip_archive writer
*errnum = ZIP_EWINIT;
goto cleanup;
}
break;
case 'r':
if (!mz_zip_reader_init_cfile(
&(zip->archive), cstream, 0,
zip->level | MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY)) {
// An archive file does not exist or cannot initialize
// zip_archive reader
*errnum = ZIP_ERINIT;
goto cleanup;
}
break;
case 'a':
case 'd':
if (!mz_zip_reader_init_cfile(
&(zip->archive), cstream, 0,
zip->level | MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY)) {
// An archive file does not exist or cannot initialize
// zip_archive reader
*errnum = ZIP_ERINIT;
goto cleanup;
}
if ((mode == 'a' || mode == 'd')) {
if (!mz_zip_writer_init_from_reader_v2_noreopen(&(zip->archive), 0,
0)) {
*errnum = ZIP_EWRINIT;
mz_zip_reader_end(&(zip->archive));
goto cleanup;
}
}
break;
default:
*errnum = ZIP_EINVMODE;
goto cleanup;
}
return zip;
cleanup:
CLEANUP(zip);
return NULL;
}
kuba-- commented
Thanks, here is a PR: https://github.com/kuba--/zip/pull/338
I suppose it should work for you :)