static void* unzip_file(ZipArchiveHandle zip, const char* entry_name, unsigned* sz) { ZipEntryName zip_entry_name(entry_name); ZipEntry zip_entry; if (FindEntry(zip, zip_entry_name, &zip_entry) != 0) { fprintf(stderr, "archive does not contain '%s'\n", entry_name); return 0; } *sz = zip_entry.uncompressed_length; uint8_t* data = reinterpret_cast<uint8_t*>(malloc(zip_entry.uncompressed_length)); if (data == NULL) { fprintf(stderr, "failed to allocate %u bytes for '%s'\n", *sz, entry_name); return 0; } int error = ExtractToMemory(zip, &zip_entry, data, zip_entry.uncompressed_length); if (error != 0) { fprintf(stderr, "failed to extract '%s': %s\n", entry_name, ErrorCodeString(error)); free(data); return 0; } return data; }
static void ExtractToPipe(ZipArchiveHandle zah, ZipEntry& entry, const std::string& name) { // We need to extract to memory because ExtractEntryToFile insists on // being able to seek and truncate, and you can't do that with stdout. uint8_t* buffer = new uint8_t[entry.uncompressed_length]; int err = ExtractToMemory(zah, &entry, buffer, entry.uncompressed_length); if (err < 0) { error(1, 0, "failed to extract %s: %s", name.c_str(), ErrorCodeString(err)); } if (!android::base::WriteFully(1, buffer, entry.uncompressed_length)) { error(1, errno, "failed to write %s to stdout", name.c_str()); } delete[] buffer; }
std::unique_ptr<IData> ZipFile::openAsData() { if (mZipEntry.method == kCompressStored) { int fd = GetFileDescriptor(mZipHandle); android::FileMap fileMap; bool result = fileMap.create(nullptr, fd, mZipEntry.offset, mZipEntry.uncompressed_length, true); if (!result) { return {}; } return util::make_unique<MmappedData>(std::move(fileMap)); } else { std::unique_ptr<uint8_t[]> data = std::unique_ptr<uint8_t[]>( new uint8_t[mZipEntry.uncompressed_length]); int32_t result = ExtractToMemory(mZipHandle, &mZipEntry, data.get(), static_cast<uint32_t>(mZipEntry.uncompressed_length)); if (result != 0) { return {}; } return util::make_unique<MallocData>(std::move(data), mZipEntry.uncompressed_length); } }