| 90 | }; |
| 91 | |
| 92 | void WriteStoredZip(const fs::path& path, |
| 93 | std::vector<std::pair<std::string, std::string>> entries) { |
| 94 | std::ofstream output(path, std::ios::binary); |
| 95 | std::vector<ZipTestEntry> writtenEntries; |
| 96 | for (const auto& entry : entries) { |
| 97 | const std::string& name = entry.first; |
| 98 | const std::string& content = entry.second; |
| 99 | const uint32_t localHeaderOffset = |
| 100 | static_cast<uint32_t>(output.tellp()); |
| 101 | WriteLe32(output, 0x04034b50); |
| 102 | WriteLe16(output, 20); |
| 103 | WriteLe16(output, 0); |
| 104 | WriteLe16(output, 0); |
| 105 | WriteLe16(output, 0); |
| 106 | WriteLe16(output, 0); |
| 107 | WriteLe32(output, 0); |
| 108 | WriteLe32(output, static_cast<uint32_t>(content.size())); |
| 109 | WriteLe32(output, static_cast<uint32_t>(content.size())); |
| 110 | WriteLe16(output, static_cast<uint16_t>(name.size())); |
| 111 | WriteLe16(output, 0); |
| 112 | output.write(name.data(), static_cast<std::streamsize>(name.size())); |
| 113 | output.write(content.data(), static_cast<std::streamsize>(content.size())); |
| 114 | writtenEntries.push_back(ZipTestEntry{name, content, localHeaderOffset}); |
| 115 | } |
| 116 | |
| 117 | const uint32_t centralDirectoryOffset = |
| 118 | static_cast<uint32_t>(output.tellp()); |
| 119 | for (const ZipTestEntry& entry : writtenEntries) { |
| 120 | WriteLe32(output, 0x02014b50); |
| 121 | WriteLe16(output, 20); |
| 122 | WriteLe16(output, 20); |
| 123 | WriteLe16(output, 0); |
| 124 | WriteLe16(output, 0); |
| 125 | WriteLe16(output, 0); |
| 126 | WriteLe16(output, 0); |
| 127 | WriteLe32(output, 0); |
| 128 | WriteLe32(output, static_cast<uint32_t>(entry.content.size())); |
| 129 | WriteLe32(output, static_cast<uint32_t>(entry.content.size())); |
| 130 | WriteLe16(output, static_cast<uint16_t>(entry.name.size())); |
| 131 | WriteLe16(output, 0); |
| 132 | WriteLe16(output, 0); |
| 133 | WriteLe16(output, 0); |
| 134 | WriteLe16(output, 0); |
| 135 | WriteLe32(output, 0); |
| 136 | WriteLe32(output, entry.localHeaderOffset); |
| 137 | output.write(entry.name.data(), |
| 138 | static_cast<std::streamsize>(entry.name.size())); |
| 139 | } |
| 140 | const uint32_t centralDirectorySize = |
| 141 | static_cast<uint32_t>(output.tellp()) - centralDirectoryOffset; |
| 142 | |
| 143 | WriteLe32(output, 0x06054b50); |
| 144 | WriteLe16(output, 0); |
| 145 | WriteLe16(output, 0); |
| 146 | WriteLe16(output, static_cast<uint16_t>(writtenEntries.size())); |
| 147 | WriteLe16(output, static_cast<uint16_t>(writtenEntries.size())); |
| 148 | WriteLe32(output, centralDirectorySize); |
| 149 | WriteLe32(output, centralDirectoryOffset); |