Refactoring
This commit is contained in:
		
							parent
							
								
									91efcfa06d
								
							
						
					
					
						commit
						316457b988
					
				
					 1 changed files with 97 additions and 79 deletions
				
			
		| 
						 | 
					@ -500,21 +500,20 @@ static const PHYSFS_Archiver RGSS_Archiver =
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct FileSystemPrivate
 | 
					struct FileSystemPrivate
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	/* All keys are lower case */
 | 
						/* Maps: lower case filename, To: actual (mixed case) filename.
 | 
				
			||||||
 | 
						 * This is for compatibility with games that take Windows'
 | 
				
			||||||
 | 
						 * case insensitivity for granted */
 | 
				
			||||||
	BoostHash<std::string, std::string> pathCache;
 | 
						BoostHash<std::string, std::string> pathCache;
 | 
				
			||||||
 | 
						bool havePathCache;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	std::vector<std::string> extensions[FileSystem::Undefined+1];
 | 
						std::vector<std::string> extensions[FileSystem::Undefined+1];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// FIXME Need to find a better way to do this..
 | 
					 | 
				
			||||||
	char pathBuffer[512];
 | 
					 | 
				
			||||||
	bool havePathCache;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* Attempt to locate an extension string in a filename.
 | 
						/* Attempt to locate an extension string in a filename.
 | 
				
			||||||
	 * Either a pointer into the input string pointing at the
 | 
						 * Either a pointer into the input string pointing at the
 | 
				
			||||||
	 * extension, or null is returned */
 | 
						 * extension, or null is returned */
 | 
				
			||||||
	const char *findExt(const char *filename)
 | 
						const char *findExt(const char *filename)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		int len;
 | 
							size_t len;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		for (len = strlen(filename); len > 0; --len)
 | 
							for (len = strlen(filename); len > 0; --len)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
| 
						 | 
					@ -528,105 +527,124 @@ struct FileSystemPrivate
 | 
				
			||||||
		return 0;
 | 
							return 0;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	const char *completeFileName(const char *filename,
 | 
						/* Complete filename via regular physfs lookup */
 | 
				
			||||||
 | 
						bool completeFilenameReg(const char *filename,
 | 
				
			||||||
	                         FileSystem::FileType type,
 | 
						                         FileSystem::FileType type,
 | 
				
			||||||
 | 
						                         char *outBuffer,
 | 
				
			||||||
 | 
						                         size_t outN,
 | 
				
			||||||
	                         const char **foundExt)
 | 
						                         const char **foundExt)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		if (!havePathCache)
 | 
							/* Try supplementing extensions to find an existing path */
 | 
				
			||||||
 | 
							const std::vector<std::string> &extList = extensions[type];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							for (size_t i = 0; i < extList.size(); ++i)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
 | 
								const char *ext = extList[i].c_str();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								snprintf(outBuffer, outN, "%s.%s", filename, ext);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if (PHYSFS_exists(outBuffer))
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									if (foundExt)
 | 
				
			||||||
 | 
										*foundExt = ext;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									return true;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/* Doing the check without supplemented extension
 | 
				
			||||||
 | 
							 * fits the usage pattern of RMXP games */
 | 
				
			||||||
		if (PHYSFS_exists(filename))
 | 
							if (PHYSFS_exists(filename))
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
 | 
								strncpy(outBuffer, filename, outN);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if (foundExt)
 | 
								if (foundExt)
 | 
				
			||||||
				*foundExt = findExt(filename);
 | 
									*foundExt = findExt(filename);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				return filename;
 | 
								return true;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Complete filename via path cache */
 | 
				
			||||||
 | 
						bool completeFilenamePC(const char *filename,
 | 
				
			||||||
 | 
						                        FileSystem::FileType type,
 | 
				
			||||||
 | 
					                            char *outBuffer,
 | 
				
			||||||
 | 
					                            size_t outN,
 | 
				
			||||||
 | 
					                            const char **foundExt)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							size_t i;
 | 
				
			||||||
 | 
							char lowCase[512];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							for (i = 0; i < sizeof(lowCase)-1 && filename[i]; ++i)
 | 
				
			||||||
 | 
								lowCase[i] = tolower(filename[i]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							lowCase[i] = '\0';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							std::string key;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		const std::vector<std::string> &extList = extensions[type];
 | 
							const std::vector<std::string> &extList = extensions[type];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		for (size_t i = 0; i < extList.size(); ++i)
 | 
							for (size_t i = 0; i < extList.size(); ++i)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			const char *ext = extList[i].c_str();
 | 
								const char *ext = extList[i].c_str();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				snprintf(pathBuffer, sizeof(pathBuffer), "%s.%s", filename, ext);
 | 
								snprintf(outBuffer, outN, "%s.%s", lowCase, ext);
 | 
				
			||||||
 | 
								key = outBuffer;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				if (PHYSFS_exists(pathBuffer))
 | 
								if (pathCache.contains(key))
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
 | 
									strncpy(outBuffer, pathCache[key].c_str(), outN);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				if (foundExt)
 | 
									if (foundExt)
 | 
				
			||||||
					*foundExt = ext;
 | 
										*foundExt = ext;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
					return pathBuffer;
 | 
									return true;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			// Is this even necessary?
 | 
							key = lowCase;
 | 
				
			||||||
			if (foundExt)
 | 
					 | 
				
			||||||
				*foundExt = 0;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
			return 0;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		char buff[512];
 | 
					 | 
				
			||||||
		size_t i;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		for (i = 0; i < sizeof(buff) && filename[i]; ++i)
 | 
					 | 
				
			||||||
			buff[i] = tolower(filename[i]);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		buff[i] = '\0';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		std::string key(buff);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		/* If the path was already complete,
 | 
					 | 
				
			||||||
		 * we are done at this point */
 | 
					 | 
				
			||||||
		if (pathCache.contains(key))
 | 
							if (pathCache.contains(key))
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			/* The extension might already be included here,
 | 
								strncpy(outBuffer, pathCache[key].c_str(), outN);
 | 
				
			||||||
			 * so try to find it */
 | 
					
 | 
				
			||||||
			if (foundExt)
 | 
								if (foundExt)
 | 
				
			||||||
				*foundExt = findExt(filename);
 | 
									*foundExt = findExt(filename);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			return pathCache[key].c_str();
 | 
								return true;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		char buff2[512];
 | 
							return false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/* Try supplementing extensions
 | 
						/* Try to complete 'filename' with file extensions
 | 
				
			||||||
		 * to find an existing path */
 | 
						 * based on 'type'. If no combination could be found,
 | 
				
			||||||
		if (type != FileSystem::Undefined)
 | 
						 * returns false, and 'foundExt' is untouched */
 | 
				
			||||||
 | 
						bool completeFileName(const char *filename,
 | 
				
			||||||
 | 
						                      FileSystem::FileType type,
 | 
				
			||||||
 | 
					                          char *outBuffer,
 | 
				
			||||||
 | 
					                          size_t outN,
 | 
				
			||||||
 | 
					                          const char **foundExt)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
			std::vector<std::string> &extList = extensions[type];
 | 
							if (havePathCache)
 | 
				
			||||||
			for (size_t i = 0; i < extList.size(); ++i)
 | 
								return completeFilenamePC(filename, type, outBuffer, outN, foundExt);
 | 
				
			||||||
			{
 | 
							else
 | 
				
			||||||
				const char *ext = extList[i].c_str();
 | 
								return completeFilenameReg(filename, type, outBuffer, outN, foundExt);
 | 
				
			||||||
 | 
					 | 
				
			||||||
				snprintf(buff2, sizeof(buff2), "%s.%s", buff, ext);
 | 
					 | 
				
			||||||
				key = buff2;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
				if (pathCache.contains(key))
 | 
					 | 
				
			||||||
				{
 | 
					 | 
				
			||||||
					if (foundExt)
 | 
					 | 
				
			||||||
						*foundExt = ext;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
					return pathCache[key].c_str();
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (foundExt)
 | 
						PHYSFS_File *openReadHandle(const char *filename,
 | 
				
			||||||
			*foundExt = 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		return 0;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	PHYSFS_File *openReadInt(const char *filename,
 | 
					 | 
				
			||||||
	                            FileSystem::FileType type,
 | 
						                            FileSystem::FileType type,
 | 
				
			||||||
	                            const char **foundExt)
 | 
						                            const char **foundExt)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		const char *foundName = completeFileName(filename, type, foundExt);
 | 
							char found[512];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (!foundName)
 | 
							if (!completeFileName(filename, type, found, sizeof(found), foundExt))
 | 
				
			||||||
			throw Exception(Exception::NoFileError, "%s", filename);
 | 
								throw Exception(Exception::NoFileError, "%s", filename);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		PHYSFS_File *handle = PHYSFS_openRead(foundName);
 | 
							PHYSFS_File *handle = PHYSFS_openRead(found);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (!handle)
 | 
							if (!handle)
 | 
				
			||||||
			throw Exception(Exception::PHYSFSError, "PhysFS: %s", PHYSFS_getLastError());
 | 
								throw Exception(Exception::PHYSFSError, "PhysFS: %s", PHYSFS_getLastError());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -826,7 +844,7 @@ void FileSystem::openRead(SDL_RWops &ops,
 | 
				
			||||||
                          bool freeOnClose,
 | 
					                          bool freeOnClose,
 | 
				
			||||||
                          const char **foundExt)
 | 
					                          const char **foundExt)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	PHYSFS_File *handle = p->openReadInt(filename, type, foundExt);
 | 
						PHYSFS_File *handle = p->openReadHandle(filename, type, foundExt);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ops.size  = SDL_RWopsSize;
 | 
						ops.size  = SDL_RWopsSize;
 | 
				
			||||||
	ops.seek  = SDL_RWopsSeek;
 | 
						ops.seek  = SDL_RWopsSeek;
 | 
				
			||||||
| 
						 | 
					@ -844,7 +862,7 @@ void FileSystem::openRead(SDL_RWops &ops,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool FileSystem::exists(const char *filename, FileType type)
 | 
					bool FileSystem::exists(const char *filename, FileType type)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	const char *foundName = p->completeFileName(filename, type, 0);
 | 
						char found[512];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return (foundName != 0);
 | 
						return p->completeFileName(filename, type, found, sizeof(found), 0);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue