| 1014 | } |
| 1015 | |
| 1016 | static int32_t CopyEntryToWriter(MappedZipFile& mapped_zip, const ZipEntry* entry, |
| 1017 | zip_archive_lkchan::Writer* writer, uint64_t* crc_out) { |
| 1018 | static const uint32_t kBufSize = 32768; |
| 1019 | std::vector<uint8_t> buf(kBufSize); |
| 1020 | |
| 1021 | const uint32_t length = entry->uncompressed_length; |
| 1022 | uint32_t count = 0; |
| 1023 | uint64_t crc = 0; |
| 1024 | while (count < length) { |
| 1025 | uint32_t remaining = length - count; |
| 1026 | off64_t offset = entry->offset + count; |
| 1027 | |
| 1028 | // Safe conversion because kBufSize is narrow enough for a 32 bit signed value. |
| 1029 | const size_t block_size = (remaining > kBufSize) ? kBufSize : remaining; |
| 1030 | |
| 1031 | // Make sure to read at offset to ensure concurrent access to the fd. |
| 1032 | if (!mapped_zip.ReadAtOffset(buf.data(), block_size, offset)) { |
| 1033 | //chensenhua ALOGW("CopyFileToFile: copy read failed, block_size = %zu, offset = %" PRId64 ": %s", |
| 1034 | //chensenhua block_size, static_cast<int64_t>(offset), strerror(errno)); |
| 1035 | return kIoError; |
| 1036 | } |
| 1037 | |
| 1038 | if (!writer->Append(&buf[0], block_size)) { |
| 1039 | return kIoError; |
| 1040 | } |
| 1041 | crc = crc32(crc, &buf[0], block_size); |
| 1042 | count += block_size; |
| 1043 | } |
| 1044 | |
| 1045 | *crc_out = crc; |
| 1046 | |
| 1047 | return 0; |
| 1048 | } |
| 1049 | |
| 1050 | int32_t ExtractToWriter(ZipArchiveHandle handle, ZipEntry* entry, zip_archive_lkchan::Writer* writer) { |
| 1051 | ZipArchive* archive = reinterpret_cast<ZipArchive*>(handle); |
no test coverage detected