zip_int64_t _zip_source_call(zip_source_t *src, void *data, zip_uint64_t length, zip_source_cmd_t command) { zip_int64_t ret; if ((src->supports & ZIP_SOURCE_MAKE_COMMAND_BITMASK(command)) == 0) { zip_error_set(&src->error, ZIP_ER_OPNOTSUPP, 0); return -1; } if (src->src == NULL) { ret = src->cb.f(src->ud, data, length, command); } else { ret = src->cb.l(src->src, src->ud, data, length, command); } if (ret < 0) { if (command != ZIP_SOURCE_ERROR && command != ZIP_SOURCE_SUPPORTS) { int e[2]; if (_zip_source_call(src, e, sizeof(e), ZIP_SOURCE_ERROR) < 0) { zip_error_set(&src->error, ZIP_ER_INTERNAL, 0); } else { zip_error_set(&src->error, e[0], e[1]); } } } return ret; }
ZIP_EXTERN zip_int64_t zip_source_make_command_bitmap(zip_source_cmd_t cmd0, ...) { zip_int64_t bitmap; va_list ap; bitmap = ZIP_SOURCE_MAKE_COMMAND_BITMASK(cmd0); va_start(ap, cmd0); for (;;) { int cmd = va_arg(ap, int); if (cmd < 0) { break; } bitmap |= ZIP_SOURCE_MAKE_COMMAND_BITMASK(cmd); } va_end(ap); return bitmap; }
zip_int8_t zip_source_get_compression_flags(zip_source_t *src) { while (src) { if ((src->supports & ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_GET_COMPRESSION_FLAGS))) { zip_int64_t ret = _zip_source_call(src, NULL, 0, ZIP_SOURCE_GET_COMPRESSION_FLAGS); if (ret < 0) { return -1; } if (ret > ZIP_COMPRESSION_BITFLAG_MAX) { zip_error_set(&src->error, ZIP_ER_INTERNAL, 0); return -1; } return (zip_int8_t)ret; } src = src->src; } return 0; }
ZIP_EXTERN int zip_source_open(zip_source_t *src) { if (src->source_closed) { return -1; } if (src->write_state == ZIP_SOURCE_WRITE_REMOVED) { zip_error_set(&src->error, ZIP_ER_DELETED, 0); return -1; } if (ZIP_SOURCE_IS_OPEN_READING(src)) { if ((zip_source_supports(src) & ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_SEEK)) == 0) { zip_error_set(&src->error, ZIP_ER_INUSE, 0); return -1; } } else { if (ZIP_SOURCE_IS_LAYERED(src)) { if (zip_source_open(src->src) < 0) { _zip_error_set_from_source(&src->error, src->src); return -1; } } if (_zip_source_call(src, NULL, 0, ZIP_SOURCE_OPEN) < 0) { if (ZIP_SOURCE_IS_LAYERED(src)) { zip_source_close(src->src); } return -1; } } src->eof = false; src->had_read_error = false; _zip_error_clear(&src->error); src->open_count++; return 0; }