void mDirectorySetMapOptions(struct mDirectorySet* dirs, const struct mCoreOptions* opts) { if (opts->savegamePath) { struct VDir* dir = VDirOpen(opts->savegamePath); if (dir) { if (dirs->save && dirs->save != dirs->base) { dirs->save->close(dirs->save); } dirs->save = dir; } } if (opts->savestatePath) { struct VDir* dir = VDirOpen(opts->savestatePath); if (dir) { if (dirs->state && dirs->state != dirs->base) { dirs->state->close(dirs->state); } dirs->state = dir; } } if (opts->screenshotPath) { struct VDir* dir = VDirOpen(opts->screenshotPath); if (dir) { if (dirs->screenshot && dirs->screenshot != dirs->base) { dirs->screenshot->close(dirs->screenshot); } dirs->screenshot = dir; } } if (opts->patchPath) { struct VDir* dir = VDirOpen(opts->patchPath); if (dir) { if (dirs->patch && dirs->patch != dirs->base) { dirs->patch->close(dirs->patch); } dirs->patch = dir; } } }
struct VDir* _vdwOpenDir(struct VDir* vd, const char* path) { struct VDirW32* vdw = (struct VDirW32*) vd; if (!path) { return 0; } const char* dir = vdw->path; char* combined = malloc(sizeof(char) * (strlen(path) + strlen(dir) + 2)); sprintf(combined, "%s\\%s", dir, path); struct VDir* vd2 = VDirOpen(combined); if (!vd2) { vd2 = VDirOpenArchive(combined); } free(combined); return vd2; }
struct VDir* _vdsceOpenDir(struct VDir* vd, const char* path) { struct VDirSce* vdsce = (struct VDirSce*) vd; if (!path) { return 0; } const char* dir = vdsce->path; char* combined = malloc(sizeof(char) * (strlen(path) + strlen(dir) + strlen(PATH_SEP) + 1)); sprintf(combined, "%s%s%s", dir, PATH_SEP, path); struct VDir* vd2 = VDirOpen(combined); if (!vd2) { vd2 = VDirOpenArchive(combined); } free(combined); return vd2; }
void mLibraryLoadDirectory(struct mLibrary* library, const char* base) { struct VDir* dir = VDirOpenArchive(base); if (!dir) { dir = VDirOpen(base); } sqlite3_exec(library->db, "BEGIN TRANSACTION;", NULL, NULL, NULL); if (!dir) { sqlite3_clear_bindings(library->deleteRoot); sqlite3_reset(library->deleteRoot); sqlite3_bind_text(library->deleteRoot, 1, base, -1, SQLITE_TRANSIENT); sqlite3_step(library->deleteRoot); sqlite3_exec(library->db, "COMMIT;", NULL, NULL, NULL); return; } struct mLibraryEntry entry; memset(&entry, 0, sizeof(entry)); entry.base = base; struct mLibraryListing entries; mLibraryListingInit(&entries, 0); mLibraryGetEntries(library, &entries, 0, 0, &entry); size_t i; for (i = 0; i < mLibraryListingSize(&entries); ++i) { struct mLibraryEntry* current = mLibraryListingGetPointer(&entries, i); struct VFile* vf = dir->openFile(dir, current->filename, O_RDONLY); _mLibraryDeleteEntry(library, current); if (!vf) { continue; } _mLibraryAddEntry(library, current->filename, base, vf); } mLibraryListingDeinit(&entries); dir->rewind(dir); struct VDirEntry* dirent = dir->listNext(dir); while (dirent) { struct VFile* vf = dir->openFile(dir, dirent->name(dirent), O_RDONLY); if (!vf) { dirent = dir->listNext(dir); continue; } _mLibraryAddEntry(library, dirent->name(dirent), base, vf); dirent = dir->listNext(dir); } dir->close(dir); sqlite3_exec(library->db, "COMMIT;", NULL, NULL, NULL); }
struct VFile* mLibraryOpenVFile(struct mLibrary* library, const struct mLibraryEntry* entry) { struct mLibraryListing entries; mLibraryListingInit(&entries, 0); if (!mLibraryGetEntries(library, &entries, 0, 0, entry)) { mLibraryListingDeinit(&entries); return NULL; } struct VFile* vf = NULL; size_t i; for (i = 0; i < mLibraryListingSize(&entries); ++i) { struct mLibraryEntry* e = mLibraryListingGetPointer(&entries, i); struct VDir* dir = VDirOpenArchive(e->base); bool isArchive = true; if (!dir) { dir = VDirOpen(e->base); isArchive = false; } if (!dir) { continue; } vf = dir->openFile(dir, e->filename, O_RDONLY); if (vf && isArchive) { struct VFile* vfclone = VFileMemChunk(NULL, vf->size(vf)); uint8_t buffer[2048]; ssize_t read; while ((read = vf->read(vf, buffer, sizeof(buffer))) > 0) { vfclone->write(vfclone, buffer, read); } vf->close(vf); vf = vfclone; } dir->close(dir); if (vf) { break; } } return vf; }
struct VFile* mDirectorySetOpenPath(struct mDirectorySet* dirs, const char* path, bool (*filter)(struct VFile*)) { dirs->archive = VDirOpenArchive(path); struct VFile* file; if (dirs->archive) { file = VDirFindFirst(dirs->archive, filter); if (!file) { dirs->archive->close(dirs->archive); dirs->archive = 0; } } else { file = VFileOpen(path, O_RDONLY); if (file && !filter(file)) { file->close(file); file = 0; } } if (file) { char dirname[PATH_MAX]; separatePath(path, dirname, dirs->baseName, 0); mDirectorySetAttachBase(dirs, VDirOpen(dirname)); } return file; }
struct VFile* VDirOptionalOpenIncrementFile(struct VDir* dir, const char* realPath, const char* prefix, const char* infix, const char* suffix, int mode) { char path[PATH_MAX]; path[PATH_MAX - 1] = '\0'; char realPrefix[PATH_MAX]; realPrefix[PATH_MAX - 1] = '\0'; if (!dir) { if (!realPath) { return 0; } const char* separatorPoint = strrchr(realPath, '/'); const char* dotPoint; size_t len; if (!separatorPoint) { strcpy(path, "./"); separatorPoint = realPath; dotPoint = strrchr(realPath, '.'); } else { path[0] = '\0'; dotPoint = strrchr(separatorPoint, '.'); if (separatorPoint - realPath + 1 >= PATH_MAX - 1) { return 0; } len = separatorPoint - realPath; strncat(path, realPath, len); path[len] = '\0'; ++separatorPoint; } if (dotPoint - realPath + 1 >= PATH_MAX - 1) { return 0; } if (dotPoint >= separatorPoint) { len = dotPoint - separatorPoint; } else { len = PATH_MAX - 1; } strncpy(realPrefix, separatorPoint, len); realPrefix[len] = '\0'; prefix = realPrefix; dir = VDirOpen(path); } if (!dir) { // This shouldn't be possible return 0; } dir->rewind(dir); struct VDirEntry* dirent; size_t prefixLen = strlen(prefix); size_t infixLen = strlen(infix); unsigned next = 0; while ((dirent = dir->listNext(dir))) { const char* filename = dirent->name(dirent); char* dotPoint = strrchr(filename, '.'); size_t len = strlen(filename); if (dotPoint) { len = (dotPoint - filename); } const char* separator = strnrstr(filename, infix, len); if (!separator) { continue; } len = separator - filename; if (len != prefixLen) { continue; } if (strncmp(filename, prefix, prefixLen) == 0) { int nlen; separator += infixLen; snprintf(path, PATH_MAX - 1, "%%u%s%%n", suffix); unsigned increment; if (sscanf(separator, path, &increment, &nlen) < 1) { continue; } len = strlen(separator); if (nlen < (ssize_t) len) { continue; } if (next <= increment) { next = increment + 1; } } } snprintf(path, PATH_MAX - 1, "%s%s%u%s", prefix, infix, next, suffix); path[PATH_MAX - 1] = '\0'; return dir->openFile(dir, path, mode); }