#include "utils/Utils.h" #include #include #include #include #include #include #include #include #include #include #include #include #ifdef __ANDROID__ #include #endif namespace ZL { std::string readTextFile(const std::string &filename) { #ifdef __ANDROID__ SDL_RWops* file = SDL_RWFromFile(filename.c_str(), "rb"); if (!file) { #ifdef DEBUG __android_log_print(ANDROID_LOG_ERROR, "Utils", "Failed to open: %s", filename.c_str()); #endif return ""; } Sint64 size = SDL_RWsize(file); if (size <= 0) { SDL_RWclose(file); return ""; } std::string content(size, '\0'); if (SDL_RWread(file, &content[0], size, 1) != 1) { SDL_RWclose(file); return ""; } SDL_RWclose(file); return content; #else std::ifstream f(filename); if (!f.is_open()) { return ""; } return std::string((std::istreambuf_iterator(f)), std::istreambuf_iterator()); #endif } std::vector readFile(const std::string &filename) { #ifdef __ANDROID__ SDL_RWops* file = SDL_RWFromFile(filename.c_str(), "rb"); if (!file) { return {}; } Sint64 size = SDL_RWsize(file); if (size <= 0) { SDL_RWclose(file); return {}; } std::vector data(size); if (SDL_RWread(file, data.data(), size, 1) != 1) { SDL_RWclose(file); return {}; } SDL_RWclose(file); return data; #else std::ifstream file(filename, std::ios::binary | std::ios::ate); if (!file) { return {}; } std::streamsize size = file.tellg(); if (size <= 0) { return {}; } file.seekg(0, std::ios::beg); std::vector buffer(size); if (!file.read(buffer.data(), size)) { return {}; } return buffer; #endif } std::vector readFileFromZIP(const std::string& filename, const std::string& zipfilename) { #ifdef EMSCRIPTEN int zipErr = 0; zip_t* archive = zip_open(zipfilename.c_str(), ZIP_RDONLY, &zipErr); if (!archive) { std::cout << "Failed to open ZIP: " << zipfilename << " (error code " << zipErr << ")" << std::endl; throw std::runtime_error("Failed to open ZIP: " + zipfilename); } std::string cleanFilename = filename; if (cleanFilename.rfind("./", 0) == 0) cleanFilename = cleanFilename.substr(2); zip_stat_t fileStat; zip_stat_init(&fileStat); if (zip_stat(archive, cleanFilename.c_str(), 0, &fileStat) != 0 || !(fileStat.valid & ZIP_STAT_SIZE)) { zip_close(archive); std::cout << "Failed to stat file in ZIP: " << cleanFilename << " in " << zipfilename << std::endl; throw std::runtime_error("Can't stat file in ZIP: " + cleanFilename); } zip_file_t* zipFile = zip_fopen(archive, cleanFilename.c_str(), 0); if (!zipFile) { zip_close(archive); std::cout << "Failed to open file in ZIP: " << cleanFilename << std::endl; throw std::runtime_error("Can't open file in ZIP: " + cleanFilename); } std::vector fileData(static_cast(fileStat.size)); zip_int64_t bytesRead = zip_fread(zipFile, fileData.data(), fileStat.size); // Обязательно закрываем всё перед проверкой результата или throw zip_fclose(zipFile); zip_close(archive); if (bytesRead < 0 || static_cast(bytesRead) != fileStat.size) { std::cout << "Failed to read file from ZIP: " << cleanFilename << " (bytes read: " << bytesRead << ", expected: " << fileStat.size << ")" << std::endl; throw std::runtime_error("Error reading data from ZIP: " + cleanFilename); } return fileData; #else if (zipfilename.empty()) { std::cerr << "readFileFromZIP: zipfilename empty" << std::endl; return {}; } int zipErr = 0; zip_t* archive = zip_open(zipfilename.c_str(), ZIP_RDONLY, &zipErr); if (!archive) { std::cerr << "readFileFromZIP: zip_open failed for: " << zipfilename << " (error code " << zipErr << ")" << std::endl; return {}; } std::string cleanFilename = filename; if (cleanFilename.rfind("./", 0) == 0) { cleanFilename = cleanFilename.substr(2); } zip_stat_t fileStat; if (zip_stat(archive, cleanFilename.c_str(), 0, &fileStat) != 0) { std::cerr << "readFileFromZIP: file not found in ZIP: " << cleanFilename << " in " << zipfilename << std::endl; zip_close(archive); return {}; } zip_file_t* zipFile = zip_fopen(archive, cleanFilename.c_str(), 0); if (!zipFile) { std::cerr << "readFileFromZIP: zip_fopen failed for " << cleanFilename << std::endl; zip_close(archive); return {}; } std::vector fileData; fileData.resize(static_cast(fileStat.size)); zip_int64_t readBytes = zip_fread(zipFile, fileData.data(), static_cast(fileData.size())); if (readBytes < 0) { std::cerr << "readFileFromZIP: zip_fread failed for " << cleanFilename << std::endl; zip_fclose(zipFile); zip_close(archive); return {}; } zip_fclose(zipFile); zip_close(archive); return fileData; #endif } bool findString(const char* in, char* list) { size_t thisLength = strlen(in); while (*list != 0) { size_t length = strcspn(list, " "); if (thisLength == length) if (!strncmp(in, list, length)) return true; list += length; list += 1; } return false; } };