ZIP_EXTERN zip_source_t * zip_source_buffer_create(const void *data, zip_uint64_t len, int freep, zip_error_t *error) { struct read_data *ctx; zip_source_t *zs; if (data == NULL && len > 0) { zip_error_set(error, ZIP_ER_INVAL, 0); return NULL; } if ((ctx=(struct read_data *)malloc(sizeof(*ctx))) == NULL) { zip_error_set(error, ZIP_ER_MEMORY, 0); return NULL; } if ((ctx->in = buffer_new_read(data, len, freep)) == NULL) { zip_error_set(error, ZIP_ER_MEMORY, 0); free(ctx); return NULL; } ctx->out = NULL; ctx->mtime = time(NULL); zip_error_init(&ctx->error); if ((zs=zip_source_function_create(read_data, ctx, error)) == NULL) { buffer_free(ctx->in); free(ctx); return NULL; } return zs; }
VFSZipFileTLS* vfs_zipfile_get_tls(VFSNode *node, bool create) { VFSZipFileData *zdata = node->data1; VFSZipFileTLS *tls = SDL_TLSGet(zdata->tls_id); if(tls || !create) { return tls; } tls = calloc(1, sizeof(VFSZipFileTLS)); SDL_TLSSet(zdata->tls_id, tls, (void(*)(void*))vfs_zipfile_free_tls); zip_source_t *src = zip_source_function_create(vfs_zipfile_srcfunc, node, &tls->error); zip_t *zip = tls->zip = zip_open_from_source(src, ZIP_RDONLY, &tls->error); // FIXME: Taisei currently doesn't handle zip files without explicit directory entries correctly (file listing will not work) if(!zip) { char *r = vfs_node_repr(zdata->source, true); vfs_set_error("Failed to open zip archive '%s': %s", r, zip_error_strerror(&tls->error)); free(r); vfs_zipfile_free_tls(tls); SDL_TLSSet(zdata->tls_id, 0, NULL); zip_source_free(src); return NULL; } return tls; }
zip_source_t *source_hole_create(const char *fname, int flags, zip_error_t *error) { hole_t *ud = hole_new(fname, flags, error); if (ud == NULL) { return NULL; } return zip_source_function_create(source_hole_cb, ud, error); }
ZIP_EXTERN zip_source_t * zip_source_function(zip_t *za, zip_source_callback zcb, void *ud) { if (za == NULL) { return NULL; } return zip_source_function_create(zcb, ud, &za->error); }
zip_source_t * _zip_source_win32_handle_or_name(const void *fname, HANDLE h, zip_uint64_t start, zip_int64_t len, int closep, const zip_stat_t *st, _zip_source_win32_file_ops_t *ops, zip_error_t *error) { _zip_source_win32_read_file_t *ctx; zip_source_t *zs; if (h == INVALID_HANDLE_VALUE && fname == NULL) { zip_error_set(error, ZIP_ER_INVAL, 0); return NULL; } if ((ctx = (_zip_source_win32_read_file_t *)malloc(sizeof(_zip_source_win32_read_file_t))) == NULL) { zip_error_set(error, ZIP_ER_MEMORY, 0); return NULL; } ctx->fname = NULL; if (fname) { if ((ctx->fname = ops->op_strdup(fname)) == NULL) { zip_error_set(error, ZIP_ER_MEMORY, 0); free(ctx); return NULL; } } ctx->ops = ops; ctx->h = h; ctx->start = start; ctx->end = (len < 0 ? 0 : start + (zip_uint64_t)len); ctx->closep = ctx->fname ? 1 : closep; if (st) { memcpy(&ctx->st, st, sizeof(ctx->st)); ctx->st.name = NULL; ctx->st.valid &= ~ZIP_STAT_NAME; } else { zip_stat_init(&ctx->st); } ctx->tmpname = NULL; ctx->hout = INVALID_HANDLE_VALUE; zip_error_init(&ctx->error); ctx->supports = ZIP_SOURCE_SUPPORTS_READABLE | zip_source_make_command_bitmap(ZIP_SOURCE_SUPPORTS, ZIP_SOURCE_TELL, -1); if (ctx->fname) { HANDLE th; th = ops->op_open(ctx); if (th == INVALID_HANDLE_VALUE || GetFileType(th) == FILE_TYPE_DISK) { ctx->supports = ZIP_SOURCE_SUPPORTS_WRITABLE; } if (th != INVALID_HANDLE_VALUE) { CloseHandle(th); } } else if (GetFileType(ctx->h) == FILE_TYPE_DISK) { ctx->supports = ZIP_SOURCE_SUPPORTS_SEEKABLE; } if ((zs = zip_source_function_create(_win32_read_file, ctx, error)) == NULL) { free(ctx->fname); free(ctx); return NULL; } return zs; }
zip_source_t * _zip_source_file_or_p(const char *fname, FILE *file, zip_uint64_t start, zip_int64_t len, const zip_stat_t *st, zip_error_t *error) { struct read_file *ctx; zip_source_t *zs; if (file == NULL && fname == NULL) { zip_error_set(error, ZIP_ER_INVAL, 0); return NULL; } if ((ctx=(struct read_file *)malloc(sizeof(struct read_file))) == NULL) { zip_error_set(error, ZIP_ER_MEMORY, 0); return NULL; } ctx->fname = NULL; if (fname) { if ((ctx->fname=strdup(fname)) == NULL) { zip_error_set(error, ZIP_ER_MEMORY, 0); free(ctx); return NULL; } } ctx->f = file; ctx->start = start; ctx->end = (len < 0 ? 0 : start+(zip_uint64_t)len); if (st) { memcpy(&ctx->st, st, sizeof(ctx->st)); ctx->st.name = NULL; ctx->st.valid &= ~ZIP_STAT_NAME; } else { zip_stat_init(&ctx->st); } ctx->tmpname = NULL; ctx->fout = NULL; zip_error_init(&ctx->error); ctx->supports = ZIP_SOURCE_SUPPORTS_READABLE | zip_source_make_command_bitmap(ZIP_SOURCE_SUPPORTS, ZIP_SOURCE_TELL, -1); if (ctx->fname) { struct stat sb; if (stat(ctx->fname, &sb) < 0 || S_ISREG(sb.st_mode)) { ctx->supports = ZIP_SOURCE_SUPPORTS_WRITABLE; } } else if (fseeko(ctx->f, 0, SEEK_CUR) == 0) { ctx->supports = ZIP_SOURCE_SUPPORTS_SEEKABLE; } if ((zs=zip_source_function_create(read_file, ctx, error)) == NULL) { free(ctx->fname); free(ctx); return NULL; } return zs; }