PatcherError FileUtils::mzArchiveStats(const std::string &path, FileUtils::ArchiveStats *stats, std::vector<std::string> ignore) { assert(stats != nullptr); unzFile uf = mzOpenInputFile(path); if (!uf) { FLOGE("minizip: Failed to open for reading: {}", path); return PatcherError::createArchiveError( ErrorCode::ArchiveReadOpenError, path); } uint64_t count = 0; uint64_t totalSize = 0; std::string name; unz_file_info64 fi; memset(&fi, 0, sizeof(fi)); int ret = unzGoToFirstFile(uf); if (ret != UNZ_OK) { mzCloseInputFile(uf); return PatcherError::createArchiveError( ErrorCode::ArchiveReadHeaderError, std::string()); } do { if (!mzGetInfo(uf, &fi, &name)) { mzCloseInputFile(uf); return PatcherError::createArchiveError( ErrorCode::ArchiveReadHeaderError, std::string()); } if (std::find(ignore.begin(), ignore.end(), name) == ignore.end()) { ++count; totalSize += fi.uncompressed_size; } } while ((ret = unzGoToNextFile(uf)) == UNZ_OK); if (ret != UNZ_END_OF_LIST_OF_FILE) { mzCloseInputFile(uf); return PatcherError::createArchiveError( ErrorCode::ArchiveReadHeaderError, std::string()); } mzCloseInputFile(uf); stats->files = count; stats->totalSize = totalSize; return PatcherError(); }
PatcherError FileUtils::writeFromString(const std::string &path, const std::string &contents) { std::ofstream file(path, std::ios::binary); if (file.fail()) { return PatcherError::createIOError(ErrorCode::FileOpenError, path); } file.write(contents.data(), contents.size()); return PatcherError(); }
PatcherError FileUtils::writeFromMemory(const std::string &path, const std::vector<unsigned char> &contents) { std::ofstream file(path, std::ios::binary); if (file.fail()) { return PatcherError::createIOError(ErrorCode::FileOpenError, path); } file.write(reinterpret_cast<const char *>(contents.data()), contents.size()); return PatcherError(); }
PatcherError FileUtils::mzAddFile(zipFile zf, const std::string &name, const std::vector<unsigned char> &contents) { // Obviously never true, but we'll keep it here just in case bool zip64 = (uint64_t) contents.size() >= ((1ull << 32) - 1); zip_fileinfo zi; memset(&zi, 0, sizeof(zi)); int ret = zipOpenNewFileInZip2_64( zf, // file name.c_str(), // filename &zi, // zip_fileinfo nullptr, // extrafield_local 0, // size_extrafield_local nullptr, // extrafield_global 0, // size_extrafield_global nullptr, // comment Z_DEFLATED, // method Z_DEFAULT_COMPRESSION, // level 0, // raw zip64 // zip64 ); if (ret != ZIP_OK) { FLOGW("minizip: Failed to add file (error code: {}): [memory]", ret); return PatcherError::createArchiveError( ErrorCode::ArchiveWriteDataError, name); } // Write data to file ret = zipWriteInFileInZip(zf, contents.data(), contents.size()); if (ret != ZIP_OK) { FLOGW("minizip: Failed to write data (error code: {}): [memory]", ret); zipCloseFileInZip(zf); return PatcherError::createArchiveError( ErrorCode::ArchiveWriteDataError, name); } zipCloseFileInZip(zf); return PatcherError(); }
/*! \brief Read contents of a file into memory \param path Path to file \param contents Output vector (not modified unless reading succeeds) \return Success or not */ PatcherError FileUtils::readToMemory(const std::string &path, std::vector<unsigned char> *contents) { std::ifstream file(path, std::ios::binary); if (file.fail()) { return PatcherError::createIOError(ErrorCode::FileOpenError, path); } file.seekg(0, std::ios::end); auto size = file.tellg(); file.seekg(0, std::ios::beg); std::vector<unsigned char> data(size); if (!file.read(reinterpret_cast<char *>(data.data()), size)) { return PatcherError::createIOError(ErrorCode::FileReadError, path); } data.swap(*contents); return PatcherError(); }
/*! \brief Read contents of a file into a string \param path Path to file \param contents Output string (not modified unless reading succeeds) \return Success or not */ PatcherError FileUtils::readToString(const std::string &path, std::string *contents) { std::ifstream file(path, std::ios::binary); if (file.fail()) { return PatcherError::createIOError(ErrorCode::FileOpenError, path); } file.seekg(0, std::ios::end); auto size = file.tellg(); file.seekg(0, std::ios::beg); std::string data; data.resize(size); if (!file.read(&data[0], size)) { return PatcherError::createIOError(ErrorCode::FileReadError, path); } data.swap(*contents); return PatcherError(); }
PatcherError StandardPatcher::error() const { return PatcherError(); }
PatcherError FileUtils::mzAddFile(zipFile zf, const std::string &name, const std::string &path) { // Copy file into archive std::ifstream file(path, std::ios::binary); if (file.fail()) { return PatcherError::createIOError( ErrorCode::FileOpenError, path); } file.seekg(0, std::ios::end); auto size = file.tellg(); file.seekg(0, std::ios::beg); bool zip64 = (uint64_t) size >= ((1ull << 32) - 1); zip_fileinfo zi; memset(&zi, 0, sizeof(zi)); mzGetFileTime(path, &zi.tmz_date, &zi.dosDate); int ret = zipOpenNewFileInZip2_64( zf, // file name.c_str(), // filename &zi, // zip_fileinfo nullptr, // extrafield_local 0, // size_extrafield_local nullptr, // extrafield_global 0, // size_extrafield_global nullptr, // comment Z_DEFLATED, // method Z_DEFAULT_COMPRESSION, // level 0, // raw zip64 // zip64 ); if (ret != ZIP_OK) { FLOGW("minizip: Failed to add file (error code: {}): {}", ret, path); return PatcherError::createArchiveError( ErrorCode::ArchiveWriteDataError, name); } // Write data to file char buf[32768]; std::streamsize n; while (!file.eof()) { file.read(buf, 32768); n = file.gcount(); ret = zipWriteInFileInZip(zf, buf, n); if (ret != ZIP_OK) { FLOGW("minizip: Failed to write data (error code: {}): {}", ret, path); zipCloseFileInZip(zf); return PatcherError::createArchiveError( ErrorCode::ArchiveWriteDataError, name); } } if (file.bad()) { zipCloseFileInZip(zf); return PatcherError::createIOError( ErrorCode::FileReadError, path); } zipCloseFileInZip(zf); return PatcherError(); }