bool ThemeEngine::themeConfigUsable(const Common::FSNode &node, Common::String &themeName) { Common::File stream; bool foundHeader = false; if (node.getName().matchString("*.zip", true) && !node.isDirectory()) { Common::Archive *zipArchive = Common::makeZipArchive(node); if (zipArchive && zipArchive->hasFile("THEMERC")) { // Open THEMERC from the ZIP file. stream.open("THEMERC", *zipArchive); } // Delete the ZIP archive again. Note: This only works because // stream.open() only uses ZipArchive::createReadStreamForMember, // and that in turn happens to read all the data for a given // archive member into a memory block. So there will be no dangling // reference to zipArchive anywhere. This could change if we // ever modify ZipArchive::createReadStreamForMember. delete zipArchive; } else if (node.isDirectory()) { Common::FSNode headerfile = node.getChild("THEMERC"); if (!headerfile.exists() || !headerfile.isReadable() || headerfile.isDirectory()) return false; stream.open(headerfile); } if (stream.isOpen()) { Common::String stxHeader = stream.readLine(); foundHeader = themeConfigParseHeader(stxHeader, themeName); } return foundHeader; }
bool BaseFileManager::initPaths() { // Removed: Config-based file-path choice. // package files paths const Common::FSNode gameData(ConfMan.get("path")); addPath(PATH_PACKAGE, gameData); Common::FSNode dataSubFolder = gameData.getChild("data"); if (dataSubFolder.exists()) { addPath(PATH_PACKAGE, dataSubFolder); } Common::FSNode languageSubFolder = gameData.getChild("language"); if (languageSubFolder.exists()) { addPath(PATH_PACKAGE, languageSubFolder); } return STATUS_OK; }
// Parse a relative path in the game-folder, and if it exists, return a FSNode to it. static Common::FSNode getNodeForRelativePath(const Common::String &filename) { // The filename can be an explicit path, thus we need to chop it up, expecting the path the game // specifies to follow the Windows-convention of folder\subfolder\file (absolute paths should not happen) // Absolute path: These should have been handled in openDiskFile. if (filename.contains(':')) { // So just return an invalid node. return Common::FSNode(); } // Relative path: if (filename.contains('\\')) { Common::StringTokenizer path(filename, "\\"); // Start traversing relative to the game-data-dir const Common::FSNode gameDataDir(ConfMan.get("path")); Common::FSNode curNode = gameDataDir; // Parse all path-elements while (!path.empty()) { // Get the next path-component by slicing on '\\' Common::String pathPart = path.nextToken(); // Get the next FSNode in the chain, if it exists as a child from the previous. curNode = curNode.getChild(pathPart); if (!curNode.isReadable()) { // Return an invalid FSNode. return Common::FSNode(); } // Following the comments in common/fs.h, anything not a directory is a file. if (!curNode.isDirectory()) { if (!path.empty()) { error("Relative path %s reached a file before the end of the path", filename.c_str()); } return curNode; } } } // Return an invalid FSNode to mark that we didn't find the requested file. return Common::FSNode(); }