📄 qpak.c
字号:
return(thisFile->entry); thisFile = thisFile->next; } /* while */ BAIL_MACRO(ERR_NO_SUCH_FILE, 0);} /* qpak_findEntry */static int qpak_populateDirectories(QPAKentry *entries, int numEntries, QPAKdirectory *root){ PHYSFS_sint32 i; QPAKentry *entry = entries; for (i = 0; i < numEntries; i++, entry++) { if (qpak_addEntry(root, entry->name, entry) == 0) return(0); } /* for */ return(1);} /* qpak_populateDirectories */static void qpak_deletePakInfo(QPAKinfo *pakInfo){ if (pakInfo->handle != NULL) __PHYSFS_platformClose(pakInfo->handle); if (pakInfo->filename != NULL) free(pakInfo->filename); if (pakInfo->entries != NULL) free(pakInfo->entries); qpak_deleteDirectory(pakInfo->root); free(pakInfo);} /* qpak_deletePakInfo */static int qpak_entry_cmp(void *_a, PHYSFS_uint32 one, PHYSFS_uint32 two){ QPAKentry *a = (QPAKentry *) _a; return(strcmp(a[one].name, a[two].name));} /* qpak_entry_cmp */static void qpak_entry_swap(void *_a, PHYSFS_uint32 one, PHYSFS_uint32 two){ QPAKentry tmp; QPAKentry *first = &(((QPAKentry *) _a)[one]); QPAKentry *second = &(((QPAKentry *) _a)[two]); memcpy(&tmp, first, sizeof (QPAKentry)); memcpy(first, second, sizeof (QPAKentry)); memcpy(second, &tmp, sizeof (QPAKentry));} /* qpak_entry_swap */static DirHandle *QPAK_openArchive(const char *name, int forWriting){ void *fh = NULL; PHYSFS_uint32 dirOffset, dirLength; QPAKinfo *pi; DirHandle *retval; retval = (DirHandle *) malloc(sizeof (DirHandle)); BAIL_IF_MACRO(retval == NULL, ERR_OUT_OF_MEMORY, NULL); pi = (QPAKinfo *) malloc(sizeof (QPAKinfo)); if (pi == NULL) { free(retval); BAIL_MACRO(ERR_OUT_OF_MEMORY, NULL); } /* if */ retval->opaque = pi; pi->filename = (char *) malloc(strlen(name) + 1); if (pi->filename == NULL) { __PHYSFS_setError(ERR_OUT_OF_MEMORY); goto QPAK_openArchive_failed; } /* if */ if (!openQPak(name, forWriting, &fh)) goto QPAK_openArchive_failed; if (!readui32(fh, &dirOffset)) goto QPAK_openArchive_failed; if (!readui32(fh, &dirLength)) goto QPAK_openArchive_failed; if (__PHYSFS_platformFileLength(fh) < dirOffset + dirLength) goto QPAK_openArchive_failed; strcpy(pi->filename, name); pi->handle = fh; pi->dirOffset = dirOffset; pi->totalEntries = dirLength / 64; pi->entries = (QPAKentry *) malloc(pi->totalEntries * sizeof (QPAKentry)); if (pi->entries == NULL) { __PHYSFS_setError(ERR_OUT_OF_MEMORY); goto QPAK_openArchive_failed; } /* if */ if (qpak_loadEntries(fh, dirOffset, pi->totalEntries, pi->entries) == 0) goto QPAK_openArchive_failed; __PHYSFS_sort(pi->entries, pi->totalEntries, qpak_entry_cmp, qpak_entry_swap); pi->root = qpak_newDirectory(""); if (pi->root == NULL) goto QPAK_openArchive_failed; if (qpak_populateDirectories(pi->entries, pi->totalEntries, pi->root) == 0) goto QPAK_openArchive_failed; retval->funcs = &__PHYSFS_DirFunctions_QPAK; return(retval);QPAK_openArchive_failed: if (retval != NULL) { if (retval->opaque != NULL) qpak_deletePakInfo((QPAKinfo *) retval->opaque); free(retval); } /* if */ if (fh != NULL) __PHYSFS_platformClose(fh); return(0);} /* QPAK_openArchive */static void QPAK_dirClose(DirHandle *dirHandle){ qpak_deletePakInfo((QPAKinfo *) dirHandle->opaque); free(dirHandle);} /* QPAK_dirClose */static LinkedStringList *QPAK_enumerateFiles(DirHandle *h, const char *dirname, int omitSymLinks){ LinkedStringList *retval = NULL, *p = NULL; QPAKdirectory *dir; QPAKinfo *info = (QPAKinfo *) h->opaque; if ((dirname == NULL) || (*dirname == '\0')) dir = info->root; else dir = qpak_findDirectory(info->root, dirname); if (dir != NULL) { QPAKdirectory *child = dir->dirs; QPAKdirentry *file = dir->files; while (child != NULL) { retval = __PHYSFS_addToLinkedStringList(retval, &p, child->name, -1); child = child->next; } /* while */ while (file != NULL) { retval = __PHYSFS_addToLinkedStringList(retval, &p, file->name, -1); file = file->next; } /* while */ } /* if */ return(retval);} /* QPAK_enumerateFiles */static int QPAK_exists(DirHandle *h, const char *name){ QPAKinfo *driver = (QPAKinfo *) h->opaque; if ((name == NULL) || (*name == '\0')) return(0); if (qpak_findDirectory(driver->root, name) != 0) return(1); if (qpak_findEntry(driver->root, name) != 0) return(1); return(0);} /* QPAK_exists */static int QPAK_isDirectory(DirHandle *h, const char *name, int *fileExists){ QPAKinfo *info = (QPAKinfo *) h->opaque; *fileExists = (qpak_findDirectory(info->root, name) != 0); return(*fileExists);} /* QPAK_isDirectory */static int QPAK_isSymLink(DirHandle *h, const char *name, int *fileExists){ *fileExists = QPAK_exists(h, name); return(0); /* we don't support symlinks for now */} /* QPAK_isSymlink */static int QPAK_remove(DirHandle *h, const char *name){ BAIL_MACRO(ERR_NOT_SUPPORTED, 0);} /* QPAK_remove */static int QPAK_mkdir(DirHandle *h, const char *name){ BAIL_MACRO(ERR_NOT_SUPPORTED, 0);} /* QPAK_mkdir */static PHYSFS_sint64 QPAK_getLastModTime(DirHandle *h, const char *name, int *fileExists){ QPAKinfo *info = (QPAKinfo *) h->opaque; PHYSFS_sint64 retval = -1; *fileExists = QPAK_exists(h, name); if (*fileExists) retval = __PHYSFS_platformGetLastModTime(info->filename); return(retval);} /* QPAK_getLastModTime */static void *qpak_getFileHandle(const char *name, QPAKentry *entry){ void *retval = __PHYSFS_platformOpenRead(name); if (retval == NULL) return(NULL); if (!__PHYSFS_platformSeek(retval, entry->offset)) { __PHYSFS_platformClose(retval); return(NULL); } /* if */ return(retval);} /* qpak_getFileHandle */static FileHandle *QPAK_openRead(DirHandle *h, const char *fnm, int *fileExists){ QPAKinfo *driver = (QPAKinfo *) h->opaque; QPAKentry *entry = qpak_findEntry(driver->root, fnm); QPAKfileinfo *fileDriver = 0; FileHandle *result = 0; *fileExists = (entry != NULL); if (entry == NULL) return(NULL); fileDriver = (QPAKfileinfo *) malloc(sizeof (QPAKfileinfo)); BAIL_IF_MACRO(fileDriver == NULL, ERR_OUT_OF_MEMORY, NULL); fileDriver->handle = qpak_getFileHandle(driver->filename, entry); if (fileDriver->handle == NULL) { free(fileDriver); return(NULL); } /* if */ fileDriver->entry = entry; fileDriver->curPos = 0; result = (FileHandle *)malloc(sizeof (FileHandle)); if (result == NULL) { __PHYSFS_platformClose(fileDriver->handle); free(fileDriver); BAIL_MACRO(ERR_OUT_OF_MEMORY, NULL); } /* if */ result->opaque = fileDriver; result->dirHandle = h; result->funcs = &__PHYSFS_FileFunctions_QPAK; return(result);} /* QPAK_openRead */static FileHandle *QPAK_openWrite(DirHandle *h, const char *name){ BAIL_MACRO(ERR_NOT_SUPPORTED, NULL);} /* QPAK_openWrite */static FileHandle *QPAK_openAppend(DirHandle *h, const char *name){ BAIL_MACRO(ERR_NOT_SUPPORTED, NULL);} /* QPAK_openAppend */static PHYSFS_sint64 QPAK_read(FileHandle *handle, void *buffer, PHYSFS_uint32 objSize, PHYSFS_uint32 objCount){ QPAKfileinfo *finfo = (QPAKfileinfo *) (handle->opaque); QPAKentry *entry = finfo->entry; PHYSFS_uint64 bytesLeft = entry->size - finfo->curPos; PHYSFS_uint64 objsLeft = (bytesLeft / objSize); PHYSFS_sint64 rc; if (objsLeft < objCount) objCount = (PHYSFS_uint32) objsLeft; rc = __PHYSFS_platformRead(finfo->handle, buffer, objSize, objCount); if (rc > 0) finfo->curPos += (rc * objSize); return(rc);} /* QPAK_read */static PHYSFS_sint64 QPAK_write(FileHandle *handle, const void *buffer, PHYSFS_uint32 objSize, PHYSFS_uint32 objCount){ BAIL_MACRO(ERR_NOT_SUPPORTED, -1);} /* QPAK_write */static int QPAK_eof(FileHandle *handle){ QPAKfileinfo *finfo = (QPAKfileinfo *) (handle->opaque); QPAKentry *entry = finfo->entry; return(finfo->curPos >= (PHYSFS_sint64) entry->size);} /* QPAK_eof */static PHYSFS_sint64 QPAK_tell(FileHandle *handle){ return(((QPAKfileinfo *) handle->opaque)->curPos);} /* QPAK_tell */static int QPAK_seek(FileHandle *handle, PHYSFS_uint64 offset){ QPAKfileinfo *finfo = (QPAKfileinfo *) handle->opaque; QPAKentry *entry = finfo->entry; PHYSFS_uint64 newPos = entry->offset + offset; int rc; BAIL_IF_MACRO(offset < 0, ERR_INVALID_ARGUMENT, 0); BAIL_IF_MACRO(newPos > entry->offset + entry->size, ERR_PAST_EOF, 0); rc = __PHYSFS_platformSeek(finfo->handle, newPos); if (rc) finfo->curPos = offset; return(rc);} /* QPAK_seek */static PHYSFS_sint64 QPAK_fileLength(FileHandle *handle){ return ((QPAKfileinfo *) handle->opaque)->entry->size;} /* QPAK_fileLength */static int QPAK_fileClose(FileHandle *handle){ QPAKfileinfo *finfo = (QPAKfileinfo *) handle->opaque; BAIL_IF_MACRO(!__PHYSFS_platformClose(finfo->handle), NULL, 0); free(finfo); free(handle); return(1);} /* QPAK_fileClose */#endif /* defined PHYSFS_SUPPORTS_QPAK *//* end of qpak.c ... */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -