Merge pull request #55 from mathewv/master
NFD filename translation on OS X
This commit is contained in:
		
						commit
						9c3d40de5e
					
				
					 1 changed files with 57 additions and 3 deletions
				
			
		| 
						 | 
					@ -37,6 +37,10 @@
 | 
				
			||||||
#include <algorithm>
 | 
					#include <algorithm>
 | 
				
			||||||
#include <vector>
 | 
					#include <vector>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef __APPLE__
 | 
				
			||||||
 | 
					#include <iconv.h>
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline PHYSFS_File *sdlPHYS(SDL_RWops *ops)
 | 
					static inline PHYSFS_File *sdlPHYS(SDL_RWops *ops)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	return static_cast<PHYSFS_File*>(ops->hidden.unknown.data1);
 | 
						return static_cast<PHYSFS_File*>(ops->hidden.unknown.data1);
 | 
				
			||||||
| 
						 | 
					@ -364,10 +368,48 @@ void FileSystem::addPath(const char *path)
 | 
				
			||||||
	PHYSFS_mount(path, 0, 1);
 | 
						PHYSFS_mount(path, 0, 1);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef __APPLE__
 | 
				
			||||||
 | 
					struct CacheEnumCBData
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						FileSystemPrivate *p;
 | 
				
			||||||
 | 
						iconv_t nfd2nfc;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						CacheEnumCBData(FileSystemPrivate *fsp)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							p = fsp;
 | 
				
			||||||
 | 
							nfd2nfc = iconv_open("utf-8", "utf-8-mac");
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						~CacheEnumCBData()
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							iconv_close(nfd2nfc);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						void nfcFromNfd(char *dst, const char *src, size_t dstSize)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							size_t srcSize = strlen(src);
 | 
				
			||||||
 | 
							/* Reserve room for null terminator */
 | 
				
			||||||
 | 
							--dstSize;
 | 
				
			||||||
 | 
							/* iconv takes a char** instead of a const char**, even though
 | 
				
			||||||
 | 
							 * the string data isn't written to. */
 | 
				
			||||||
 | 
							iconv(nfd2nfc,
 | 
				
			||||||
 | 
								  const_cast<char**>(&src), &srcSize,
 | 
				
			||||||
 | 
								  &dst, &dstSize);
 | 
				
			||||||
 | 
							/* Null-terminate */
 | 
				
			||||||
 | 
							*dst = 0;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void cacheEnumCB(void *d, const char *origdir,
 | 
					static void cacheEnumCB(void *d, const char *origdir,
 | 
				
			||||||
                        const char *fname)
 | 
					                        const char *fname)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					#ifdef __APPLE__
 | 
				
			||||||
 | 
						CacheEnumCBData *data = static_cast<CacheEnumCBData*>(d);
 | 
				
			||||||
 | 
						FileSystemPrivate *p = data->p;
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
	FileSystemPrivate *p = static_cast<FileSystemPrivate*>(d);
 | 
						FileSystemPrivate *p = static_cast<FileSystemPrivate*>(d);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	char buf[512];
 | 
						char buf[512];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -376,7 +418,14 @@ static void cacheEnumCB(void *d, const char *origdir,
 | 
				
			||||||
	else
 | 
						else
 | 
				
			||||||
		snprintf(buf, sizeof(buf), "%s/%s", origdir, fname);
 | 
							snprintf(buf, sizeof(buf), "%s/%s", origdir, fname);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	char *ptr = buf;
 | 
					#ifdef __APPLE__
 | 
				
			||||||
 | 
						char bufNfc[sizeof(buf)];
 | 
				
			||||||
 | 
						data->nfcFromNfd(bufNfc, buf, sizeof(bufNfc));
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
						char *const bufNfc = buf;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						char *ptr = bufNfc;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Trim leading slash */
 | 
						/* Trim leading slash */
 | 
				
			||||||
	if (*ptr == '/')
 | 
						if (*ptr == '/')
 | 
				
			||||||
| 
						 | 
					@ -384,19 +433,24 @@ static void cacheEnumCB(void *d, const char *origdir,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	std::string mixedCase(ptr);
 | 
						std::string mixedCase(ptr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for (char *p = buf; *p; ++p)
 | 
						for (char *p = bufNfc; *p; ++p)
 | 
				
			||||||
		*p = tolower(*p);
 | 
							*p = tolower(*p);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	std::string lowerCase(ptr);
 | 
						std::string lowerCase(ptr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	p->pathCache.insert(lowerCase, mixedCase);
 | 
						p->pathCache.insert(lowerCase, mixedCase);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	PHYSFS_enumerateFilesCallback(mixedCase.c_str(), cacheEnumCB, p);
 | 
						PHYSFS_enumerateFilesCallback(mixedCase.c_str(), cacheEnumCB, d);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void FileSystem::createPathCache()
 | 
					void FileSystem::createPathCache()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					#ifdef __APPLE__
 | 
				
			||||||
 | 
						CacheEnumCBData data(p);
 | 
				
			||||||
 | 
						PHYSFS_enumerateFilesCallback("", cacheEnumCB, &data);
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
	PHYSFS_enumerateFilesCallback("", cacheEnumCB, p);
 | 
						PHYSFS_enumerateFilesCallback("", cacheEnumCB, p);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	p->havePathCache = true;
 | 
						p->havePathCache = true;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue