diff --git a/Engine/source/platformMac/macFileIO.mm b/Engine/source/platformMac/macFileIO.mm index 90efbd303..7c9b68eda 100644 --- a/Engine/source/platformMac/macFileIO.mm +++ b/Engine/source/platformMac/macFileIO.mm @@ -46,114 +46,114 @@ bool dFileDelete(const char * name) { - if(!name ) - return(false); - - if (dStrlen(name) > MAX_MAC_PATH_LONG) - Con::warnf("dFileDelete: Filename length is pretty long..."); - - return(remove(name) == 0); // remove returns 0 on success + if(!name ) + return(false); + + if (dStrlen(name) > MAX_MAC_PATH_LONG) + Con::warnf("dFileDelete: Filename length is pretty long..."); + + return(remove(name) == 0); // remove returns 0 on success } //----------------------------------------------------------------------------- bool dFileTouch(const char *path) { - if (!path || !*path) - return false; - - // set file at path's modification and access times to now. - return( utimes( path, NULL) == 0); // utimes returns 0 on success. + if (!path || !*path) + return false; + + // set file at path's modification and access times to now. + return( utimes( path, NULL) == 0); // utimes returns 0 on success. } //----------------------------------------------------------------------------- bool dPathCopy(const char* source, const char* dest, bool nooverwrite) { - if(source == NULL || dest == NULL) - return false; - - @autoreleasepool { - NSFileManager *manager = [NSFileManager defaultManager]; - - NSString *nsource = [manager stringWithFileSystemRepresentation:source length:dStrlen(source)]; - NSString *ndest = [manager stringWithFileSystemRepresentation:dest length:dStrlen(dest)]; - NSString *ndestFolder = [ndest stringByDeletingLastPathComponent]; - - if(! [manager fileExistsAtPath:nsource]) - { - Con::errorf("dPathCopy: no file exists at %s",source); - return false; - } - - if( [manager fileExistsAtPath:ndest] ) - { - if(nooverwrite) - { - Con::errorf("dPathCopy: file already exists at %s",dest); - return false; - } - Con::warnf("Deleting files at path: %s", dest); - if(![manager removeItemAtPath:ndest error:nil] || [manager fileExistsAtPath:ndest]) - { - Con::errorf("Copy failed! Could not delete files at path: %s", dest); - return false; - } - } - - if([manager fileExistsAtPath:ndestFolder] == NO) - { - ndestFolder = [ndestFolder stringByAppendingString:@"/"]; // createpath requires a trailing slash - Platform::createPath([ndestFolder UTF8String]); - } - - bool ret = [manager copyItemAtPath:nsource toPath:ndest error:nil]; - // n.b.: The "success" semantics don't guarantee a copy actually took place, so we'll verify - // because this is surprising behavior for a method called copy. - if( ![manager fileExistsAtPath:ndest] ) - { - Con::warnf("The filemanager returned success, but the file was not copied. Something strange is happening"); - ret = false; - } - return ret; - } - + if(source == NULL || dest == NULL) + return false; + + @autoreleasepool { + NSFileManager *manager = [NSFileManager defaultManager]; + + NSString *nsource = [manager stringWithFileSystemRepresentation:source length:dStrlen(source)]; + NSString *ndest = [manager stringWithFileSystemRepresentation:dest length:dStrlen(dest)]; + NSString *ndestFolder = [ndest stringByDeletingLastPathComponent]; + + if(! [manager fileExistsAtPath:nsource]) + { + Con::errorf("dPathCopy: no file exists at %s",source); + return false; + } + + if( [manager fileExistsAtPath:ndest] ) + { + if(nooverwrite) + { + Con::errorf("dPathCopy: file already exists at %s",dest); + return false; + } + Con::warnf("Deleting files at path: %s", dest); + if(![manager removeItemAtPath:ndest error:nil] || [manager fileExistsAtPath:ndest]) + { + Con::errorf("Copy failed! Could not delete files at path: %s", dest); + return false; + } + } + + if([manager fileExistsAtPath:ndestFolder] == NO) + { + ndestFolder = [ndestFolder stringByAppendingString:@"/"]; // createpath requires a trailing slash + Platform::createPath([ndestFolder UTF8String]); + } + + bool ret = [manager copyItemAtPath:nsource toPath:ndest error:nil]; + // n.b.: The "success" semantics don't guarantee a copy actually took place, so we'll verify + // because this is surprising behavior for a method called copy. + if( ![manager fileExistsAtPath:ndest] ) + { + Con::warnf("The filemanager returned success, but the file was not copied. Something strange is happening"); + ret = false; + } + return ret; + } + } //----------------------------------------------------------------------------- bool dFileRename(const char *source, const char *dest) { - if(source == NULL || dest == NULL) - return false; - - @autoreleasepool { - NSFileManager *manager = [NSFileManager defaultManager]; - - NSString *nsource = [manager stringWithFileSystemRepresentation:source length:dStrlen(source)]; - NSString *ndest = [manager stringWithFileSystemRepresentation:dest length:dStrlen(dest)]; - - if(! [manager fileExistsAtPath:nsource]) - { - Con::errorf("dFileRename: no file exists at %s",source); - return false; - } - - if( [manager fileExistsAtPath:ndest] ) - { - Con::warnf("dFileRename: Deleting files at path: %s", dest); - } - - bool ret = [manager moveItemAtPath:nsource toPath:ndest error:nil]; - // n.b.: The "success" semantics don't guarantee a move actually took place, so we'll verify - // because this is surprising behavior for a method called rename. - - if( ![manager fileExistsAtPath:ndest] ) - { - Con::warnf("The filemanager returned success, but the file was not moved. Something strange is happening"); - ret = false; - } - - return ret; - } + if(source == NULL || dest == NULL) + return false; + + @autoreleasepool { + NSFileManager *manager = [NSFileManager defaultManager]; + + NSString *nsource = [manager stringWithFileSystemRepresentation:source length:dStrlen(source)]; + NSString *ndest = [manager stringWithFileSystemRepresentation:dest length:dStrlen(dest)]; + + if(! [manager fileExistsAtPath:nsource]) + { + Con::errorf("dFileRename: no file exists at %s",source); + return false; + } + + if( [manager fileExistsAtPath:ndest] ) + { + Con::warnf("dFileRename: Deleting files at path: %s", dest); + } + + bool ret = [manager moveItemAtPath:nsource toPath:ndest error:nil]; + // n.b.: The "success" semantics don't guarantee a move actually took place, so we'll verify + // because this is surprising behavior for a method called rename. + + if( ![manager fileExistsAtPath:ndest] ) + { + Con::warnf("The filemanager returned success, but the file was not moved. Something strange is happening"); + ret = false; + } + + return ret; + } } //----------------------------------------------------------------------------- @@ -167,7 +167,7 @@ bool dFileRename(const char *source, const char *dest) File::File() : currentStatus(Closed), capability(0) { - handle = NULL; + handle = NULL; } //----------------------------------------------------------------------------- @@ -179,8 +179,8 @@ File::File() //----------------------------------------------------------------------------- File::~File() { - close(); - handle = NULL; + close(); + handle = NULL; } @@ -194,61 +194,61 @@ File::~File() //----------------------------------------------------------------------------- File::FileStatus File::open(const char *filename, const AccessMode openMode) { - if (dStrlen(filename) > MAX_MAC_PATH_LONG) - Con::warnf("File::open: Filename length is pretty long..."); - - // Close the file if it was already open... - if (currentStatus != Closed) - close(); - - // create the appropriate type of file... - switch (openMode) - { - case Read: - handle = (void *)fopen(filename, "rb"); // read only - break; - case Write: - handle = (void *)fopen(filename, "wb"); // write only - break; - case ReadWrite: - handle = (void *)fopen(filename, "ab+"); // write(append) and read - break; - case WriteAppend: - handle = (void *)fopen(filename, "ab"); // write(append) only - break; - default: - AssertFatal(false, "File::open: bad access mode"); - } - - // handle not created successfully - if (handle == NULL) - return setStatus(); - - // successfully created file, so set the file capabilities... - switch (openMode) - { - case Read: - capability = FileRead; - break; - case Write: - case WriteAppend: - capability = FileWrite; - break; - case ReadWrite: - capability = FileRead | FileWrite; - break; - default: - AssertFatal(false, "File::open: bad access mode"); - } - - // must set the file status before setting the position. - currentStatus = Ok; - - if (openMode == ReadWrite) - setPosition(0); - - // success! - return currentStatus; + if (dStrlen(filename) > MAX_MAC_PATH_LONG) + Con::warnf("File::open: Filename length is pretty long..."); + + // Close the file if it was already open... + if (currentStatus != Closed) + close(); + + // create the appropriate type of file... + switch (openMode) + { + case Read: + handle = (void *)fopen(filename, "rb"); // read only + break; + case Write: + handle = (void *)fopen(filename, "wb"); // write only + break; + case ReadWrite: + handle = (void *)fopen(filename, "ab+"); // write(append) and read + break; + case WriteAppend: + handle = (void *)fopen(filename, "ab"); // write(append) only + break; + default: + AssertFatal(false, "File::open: bad access mode"); + } + + // handle not created successfully + if (handle == NULL) + return setStatus(); + + // successfully created file, so set the file capabilities... + switch (openMode) + { + case Read: + capability = FileRead; + break; + case Write: + case WriteAppend: + capability = FileWrite; + break; + case ReadWrite: + capability = FileRead | FileWrite; + break; + default: + AssertFatal(false, "File::open: bad access mode"); + } + + // must set the file status before setting the position. + currentStatus = Ok; + + if (openMode == ReadWrite) + setPosition(0); + + // success! + return currentStatus; } //----------------------------------------------------------------------------- @@ -256,10 +256,10 @@ File::FileStatus File::open(const char *filename, const AccessMode openMode) //----------------------------------------------------------------------------- U32 File::getPosition() const { - AssertFatal(currentStatus != Closed , "File::getPosition: file closed"); - AssertFatal(handle != NULL, "File::getPosition: invalid file handle"); - - return ftell((FILE*)handle); + AssertFatal(currentStatus != Closed , "File::getPosition: file closed"); + AssertFatal(handle != NULL, "File::getPosition: invalid file handle"); + + return ftell((FILE*)handle); } //----------------------------------------------------------------------------- @@ -276,41 +276,41 @@ U32 File::getPosition() const //----------------------------------------------------------------------------- File::FileStatus File::setPosition(S32 position, bool absolutePos) { - AssertFatal(Closed != currentStatus, "File::setPosition: file closed"); - AssertFatal(handle != NULL, "File::setPosition: invalid file handle"); - - if (currentStatus != Ok && currentStatus != EOS ) - return currentStatus; - - U32 finalPos; - if(absolutePos) - { - // absolute position - AssertFatal(0 <= position, "File::setPosition: negative absolute position"); - // position beyond EOS is OK - fseek((FILE*)handle, position, SEEK_SET); - finalPos = ftell((FILE*)handle); - } - else - { - // relative position - AssertFatal((getPosition() + position) >= 0, "File::setPosition: negative relative position"); - // position beyond EOS is OK - fseek((FILE*)handle, position, SEEK_CUR); - finalPos = ftell((FILE*)handle); - } - - // ftell returns -1 on error. set error status - if (0xffffffff == finalPos) - return setStatus(); - - // success, at end of file - else if (finalPos >= getSize()) - return currentStatus = EOS; - - // success! - else - return currentStatus = Ok; + AssertFatal(Closed != currentStatus, "File::setPosition: file closed"); + AssertFatal(handle != NULL, "File::setPosition: invalid file handle"); + + if (currentStatus != Ok && currentStatus != EOS ) + return currentStatus; + + U32 finalPos; + if(absolutePos) + { + // absolute position + AssertFatal(0 <= position, "File::setPosition: negative absolute position"); + // position beyond EOS is OK + fseek((FILE*)handle, position, SEEK_SET); + finalPos = ftell((FILE*)handle); + } + else + { + // relative position + AssertFatal((getPosition() + position) >= 0, "File::setPosition: negative relative position"); + // position beyond EOS is OK + fseek((FILE*)handle, position, SEEK_CUR); + finalPos = ftell((FILE*)handle); + } + + // ftell returns -1 on error. set error status + if (0xffffffff == finalPos) + return setStatus(); + + // success, at end of file + else if (finalPos >= getSize()) + return currentStatus = EOS; + + // success! + else + return currentStatus = Ok; } //----------------------------------------------------------------------------- @@ -320,21 +320,21 @@ File::FileStatus File::setPosition(S32 position, bool absolutePos) //----------------------------------------------------------------------------- U32 File::getSize() const { - AssertWarn(Closed != currentStatus, "File::getSize: file closed"); - AssertFatal(handle != NULL, "File::getSize: invalid file handle"); - - if (Ok == currentStatus || EOS == currentStatus) - { - struct stat statData; - - if(fstat(fileno((FILE*)handle), &statData) != 0) - return 0; - - // return the size in bytes - return statData.st_size; - } - - return 0; + AssertWarn(Closed != currentStatus, "File::getSize: file closed"); + AssertFatal(handle != NULL, "File::getSize: invalid file handle"); + + if (Ok == currentStatus || EOS == currentStatus) + { + struct stat statData; + + if(fstat(fileno((FILE*)handle), &statData) != 0) + return 0; + + // return the size in bytes + return statData.st_size; + } + + return 0; } //----------------------------------------------------------------------------- @@ -344,14 +344,14 @@ U32 File::getSize() const //----------------------------------------------------------------------------- File::FileStatus File::flush() { - AssertFatal(Closed != currentStatus, "File::flush: file closed"); - AssertFatal(handle != NULL, "File::flush: invalid file handle"); - AssertFatal(true == hasCapability(FileWrite), "File::flush: cannot flush a read-only file"); - - if (fflush((FILE*)handle) != 0) - return setStatus(); - else - return currentStatus = Ok; + AssertFatal(Closed != currentStatus, "File::flush: file closed"); + AssertFatal(handle != NULL, "File::flush: invalid file handle"); + AssertFatal(true == hasCapability(FileWrite), "File::flush: cannot flush a read-only file"); + + if (fflush((FILE*)handle) != 0) + return setStatus(); + else + return currentStatus = Ok; } //----------------------------------------------------------------------------- @@ -361,18 +361,18 @@ File::FileStatus File::flush() //----------------------------------------------------------------------------- File::FileStatus File::close() { - // check if it's already closed... - if (Closed == currentStatus) - return currentStatus; - - // it's not, so close it... - if (handle != NULL) - { - if (fclose((FILE*)handle) != 0) - return setStatus(); - } - handle = NULL; - return currentStatus = Closed; + // check if it's already closed... + if (Closed == currentStatus) + return currentStatus; + + // it's not, so close it... + if (handle != NULL) + { + if (fclose((FILE*)handle) != 0) + return setStatus(); + } + handle = NULL; + return currentStatus = Closed; } //----------------------------------------------------------------------------- @@ -380,7 +380,7 @@ File::FileStatus File::close() //----------------------------------------------------------------------------- File::FileStatus File::getStatus() const { - return currentStatus; + return currentStatus; } //----------------------------------------------------------------------------- @@ -388,20 +388,20 @@ File::FileStatus File::getStatus() const //----------------------------------------------------------------------------- File::FileStatus File::setStatus() { - switch (errno) - { - case EACCES: // permission denied - currentStatus = IOError; - break; - case EBADF: // Bad File Pointer - case EINVAL: // Invalid argument - case ENOENT: // file not found - case ENAMETOOLONG: - default: - currentStatus = UnknownError; - } - - return currentStatus; + switch (errno) + { + case EACCES: // permission denied + currentStatus = IOError; + break; + case EBADF: // Bad File Pointer + case EINVAL: // Invalid argument + case ENOENT: // file not found + case ENAMETOOLONG: + default: + currentStatus = UnknownError; + } + + return currentStatus; } //----------------------------------------------------------------------------- @@ -409,7 +409,7 @@ File::FileStatus File::setStatus() //----------------------------------------------------------------------------- File::FileStatus File::setStatus(File::FileStatus status) { - return currentStatus = status; + return currentStatus = status; } //----------------------------------------------------------------------------- @@ -420,28 +420,28 @@ File::FileStatus File::setStatus(File::FileStatus status) //----------------------------------------------------------------------------- File::FileStatus File::read(U32 size, char *dst, U32 *bytesRead) { - AssertFatal(Closed != currentStatus, "File::read: file closed"); - AssertFatal(handle != NULL, "File::read: invalid file handle"); - AssertFatal(NULL != dst, "File::read: NULL destination pointer"); - AssertFatal(true == hasCapability(FileRead), "File::read: file lacks capability"); - AssertWarn(0 != size, "File::read: size of zero"); - - if (Ok != currentStatus || 0 == size) - return currentStatus; - - // read from stream - U32 nBytes = fread(dst, 1, size, (FILE*)handle); - - // did we hit the end of the stream? - if( nBytes != size) - currentStatus = EOS; - - // if bytesRead is a valid pointer, send number of bytes read there. - if(bytesRead) - *bytesRead = nBytes; - - // successfully read size bytes - return currentStatus; + AssertFatal(Closed != currentStatus, "File::read: file closed"); + AssertFatal(handle != NULL, "File::read: invalid file handle"); + AssertFatal(NULL != dst, "File::read: NULL destination pointer"); + AssertFatal(true == hasCapability(FileRead), "File::read: file lacks capability"); + AssertWarn(0 != size, "File::read: size of zero"); + + if (Ok != currentStatus || 0 == size) + return currentStatus; + + // read from stream + U32 nBytes = fread(dst, 1, size, (FILE*)handle); + + // did we hit the end of the stream? + if( nBytes != size) + currentStatus = EOS; + + // if bytesRead is a valid pointer, send number of bytes read there. + if(bytesRead) + *bytesRead = nBytes; + + // successfully read size bytes + return currentStatus; } //----------------------------------------------------------------------------- @@ -452,28 +452,28 @@ File::FileStatus File::read(U32 size, char *dst, U32 *bytesRead) //----------------------------------------------------------------------------- File::FileStatus File::write(U32 size, const char *src, U32 *bytesWritten) { - AssertFatal(Closed != currentStatus, "File::write: file closed"); - AssertFatal(handle != NULL, "File::write: invalid file handle"); - AssertFatal(NULL != src, "File::write: NULL source pointer"); - AssertFatal(true == hasCapability(FileWrite), "File::write: file lacks capability"); - AssertWarn(0 != size, "File::write: size of zero"); - - if ((Ok != currentStatus && EOS != currentStatus) || 0 == size) - return currentStatus; - - // write bytes to the stream - U32 nBytes = fwrite(src, 1, size,(FILE*)handle); - - // if we couldn't write everything, we've got a problem. set error status. - if(nBytes != size) - setStatus(); - - // if bytesWritten is a valid pointer, put number of bytes read there. - if(bytesWritten) - *bytesWritten = nBytes; - - // return current File status, whether good or ill. - return currentStatus; + AssertFatal(Closed != currentStatus, "File::write: file closed"); + AssertFatal(handle != NULL, "File::write: invalid file handle"); + AssertFatal(NULL != src, "File::write: NULL source pointer"); + AssertFatal(true == hasCapability(FileWrite), "File::write: file lacks capability"); + AssertWarn(0 != size, "File::write: size of zero"); + + if ((Ok != currentStatus && EOS != currentStatus) || 0 == size) + return currentStatus; + + // write bytes to the stream + U32 nBytes = fwrite(src, 1, size,(FILE*)handle); + + // if we couldn't write everything, we've got a problem. set error status. + if(nBytes != size) + setStatus(); + + // if bytesWritten is a valid pointer, put number of bytes read there. + if(bytesWritten) + *bytesWritten = nBytes; + + // return current File status, whether good or ill. + return currentStatus; } @@ -482,17 +482,17 @@ File::FileStatus File::write(U32 size, const char *src, U32 *bytesWritten) //----------------------------------------------------------------------------- bool File::hasCapability(Capability cap) const { - return (0 != (U32(cap) & capability)); + return (0 != (U32(cap) & capability)); } //----------------------------------------------------------------------------- S32 Platform::compareFileTimes(const FileTime &a, const FileTime &b) { - if(a > b) - return 1; - if(a < b) - return -1; - return 0; + if(a > b) + return 1; + if(a < b) + return -1; + return 0; } @@ -501,100 +501,100 @@ S32 Platform::compareFileTimes(const FileTime &a, const FileTime &b) //----------------------------------------------------------------------------- bool Platform::getFileTimes(const char *path, FileTime *createTime, FileTime *modifyTime) { - // MacOSX is NOT guaranteed to be running off a HFS volume, - // and UNIX does not keep a record of a file's creation time anywhere. - // So instead of creation time we return changed time, - // just like the Linux platform impl does. - - if (!path || !*path) - return false; - - struct stat statData; - - if (stat(path, &statData) == -1) - return false; - - if(createTime) - *createTime = statData.st_ctime; - - if(modifyTime) - *modifyTime = statData.st_mtime; - - return true; + // MacOSX is NOT guaranteed to be running off a HFS volume, + // and UNIX does not keep a record of a file's creation time anywhere. + // So instead of creation time we return changed time, + // just like the Linux platform impl does. + + if (!path || !*path) + return false; + + struct stat statData; + + if (stat(path, &statData) == -1) + return false; + + if(createTime) + *createTime = statData.st_ctime; + + if(modifyTime) + *modifyTime = statData.st_mtime; + + return true; } //----------------------------------------------------------------------------- bool Platform::createPath(const char *file) { - // if the path exists, we're done. - struct stat statData; - if( stat(file, &statData) == 0 ) - { - return true; // exists, rejoice. - } - - Con::warnf( "creating path %s", file ); - - // get the parent path. - // we're not using basename because it's not thread safe. - U32 len = dStrlen(file); - char parent[len]; - bool isDirPath = false; - - dStrncpy(parent,file,len); - parent[len] = '\0'; - if(parent[len - 1] == '/') - { - parent[len - 1] = '\0'; // cut off the trailing slash, if there is one - isDirPath = true; // we got a trailing slash, so file is a directory. - } - - // recusively create the parent path. - // only recurse if newpath has a slash that isn't a leading slash. - char *slash = dStrrchr(parent,'/'); - if( slash && slash != parent) - { - // snip the path just after the last slash. - slash[1] = '\0'; - // recusively create the parent path. fail if parent path creation failed. - if(!Platform::createPath(parent)) - return false; - } - - // create *file if it is a directory path. - if(isDirPath) - { - // try to create the directory - if( mkdir(file, 0777) != 0) // app may reside in global apps dir, and so must be writable to all. - return false; - } - - return true; + // if the path exists, we're done. + struct stat statData; + if( stat(file, &statData) == 0 ) + { + return true; // exists, rejoice. + } + + Con::warnf( "creating path %s", file ); + + // get the parent path. + // we're not using basename because it's not thread safe. + U32 len = dStrlen(file); + char parent[len]; + bool isDirPath = false; + + dStrncpy(parent,file,len); + parent[len] = '\0'; + if(parent[len - 1] == '/') + { + parent[len - 1] = '\0'; // cut off the trailing slash, if there is one + isDirPath = true; // we got a trailing slash, so file is a directory. + } + + // recusively create the parent path. + // only recurse if newpath has a slash that isn't a leading slash. + char *slash = dStrrchr(parent,'/'); + if( slash && slash != parent) + { + // snip the path just after the last slash. + slash[1] = '\0'; + // recusively create the parent path. fail if parent path creation failed. + if(!Platform::createPath(parent)) + return false; + } + + // create *file if it is a directory path. + if(isDirPath) + { + // try to create the directory + if( mkdir(file, 0777) != 0) // app may reside in global apps dir, and so must be writable to all. + return false; + } + + return true; } //----------------------------------------------------------------------------- bool Platform::cdFileExists(const char *filePath, const char *volumeName, S32 serialNum) { - return true; + return true; } #pragma mark ---- Directories ---- //----------------------------------------------------------------------------- StringTableEntry Platform::getCurrentDirectory() { - // get the current directory, the one that would be opened if we did a fopen(".") - char* cwd = getcwd(NULL, 0); - StringTableEntry ret = StringTable->insert(cwd); - free(cwd); - return ret; + // get the current directory, the one that would be opened if we did a fopen(".") + char* cwd = getcwd(NULL, 0); + StringTableEntry ret = StringTable->insert(cwd); + free(cwd); + return ret; } //----------------------------------------------------------------------------- bool Platform::setCurrentDirectory(StringTableEntry newDir) { - return (chdir(newDir) == 0); + return (chdir(newDir) == 0); } //----------------------------------------------------------------------------- @@ -602,7 +602,7 @@ bool Platform::setCurrentDirectory(StringTableEntry newDir) // helper func for getWorkingDirectory bool isMainDotCsPresent(NSString* dir) { - return [[NSFileManager defaultManager] fileExistsAtPath:[dir stringByAppendingPathComponent:@"main.cs"]] == YES; + return [[NSFileManager defaultManager] fileExistsAtPath:[dir stringByAppendingPathComponent:@"main.cs"]] == YES; } //----------------------------------------------------------------------------- @@ -619,119 +619,119 @@ bool isMainDotCsPresent(NSString* dir) /// experience when you distribute your app. StringTableEntry Platform::getExecutablePath() { - static const char* cwd = NULL; - - // this isn't actually being used due to some static constructors at bundle load time - // calling this method (before there is a chance to set it) - // for instance, FMOD sound provider (this should be fixed in FMOD as it is with windows) - if (!cwd && torque_getexecutablepath()) - { - // we're in a plugin using the cinterface - cwd = torque_getexecutablepath(); - chdir(cwd); - } - else if(!cwd) - { - NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; - - //first check the cwd for main.cs - static char buf[4096]; - NSString* currentDir = [[NSString alloc ] initWithUTF8String:getcwd(buf,(4096 * sizeof(char))) ]; - - if (isMainDotCsPresent(currentDir)) - { - cwd = buf; - [pool release]; - [currentDir release]; - return cwd; - } - - NSString* string = [[NSBundle mainBundle] pathForResource:@"main" ofType:@"cs"]; - if(!string) - string = [[NSBundle mainBundle] bundlePath]; - - string = [string stringByDeletingLastPathComponent]; - AssertISV(isMainDotCsPresent(string), "Platform::getExecutablePath - Failed to find main.cs!"); - cwd = dStrdup([string UTF8String]); - chdir(cwd); - [pool release]; - [currentDir release]; - } - - return cwd; + static const char* cwd = NULL; + + // this isn't actually being used due to some static constructors at bundle load time + // calling this method (before there is a chance to set it) + // for instance, FMOD sound provider (this should be fixed in FMOD as it is with windows) + if (!cwd && torque_getexecutablepath()) + { + // we're in a plugin using the cinterface + cwd = torque_getexecutablepath(); + chdir(cwd); + } + else if(!cwd) + { + NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; + + //first check the cwd for main.cs + static char buf[4096]; + NSString* currentDir = [[NSString alloc ] initWithUTF8String:getcwd(buf,(4096 * sizeof(char))) ]; + + if (isMainDotCsPresent(currentDir)) + { + cwd = buf; + [pool release]; + [currentDir release]; + return cwd; + } + + NSString* string = [[NSBundle mainBundle] pathForResource:@"main" ofType:@"cs"]; + if(!string) + string = [[NSBundle mainBundle] bundlePath]; + + string = [string stringByDeletingLastPathComponent]; + AssertISV(isMainDotCsPresent(string), "Platform::getExecutablePath - Failed to find main.cs!"); + cwd = dStrdup([string UTF8String]); + chdir(cwd); + [pool release]; + [currentDir release]; + } + + return cwd; } //----------------------------------------------------------------------------- StringTableEntry Platform::getExecutableName() { - static const char* name = NULL; - if(!name) - name = [[[[NSBundle mainBundle] bundlePath] lastPathComponent] UTF8String]; - - return name; + static const char* name = NULL; + if(!name) + name = [[[[NSBundle mainBundle] bundlePath] lastPathComponent] UTF8String]; + + return name; } //----------------------------------------------------------------------------- bool Platform::isFile(const char *path) { - if (!path || !*path) - return false; - - // make sure we can stat the file - struct stat statData; - if( stat(path, &statData) < 0 ) - { - // Since file does not exist on disk see if it exists in a zip file loaded - return Torque::FS::IsFile(path); - } - - // now see if it's a regular file - if( (statData.st_mode & S_IFMT) == S_IFREG) - return true; - - return false; + if (!path || !*path) + return false; + + // make sure we can stat the file + struct stat statData; + if( stat(path, &statData) < 0 ) + { + // Since file does not exist on disk see if it exists in a zip file loaded + return Torque::FS::IsFile(path); + } + + // now see if it's a regular file + if( (statData.st_mode & S_IFMT) == S_IFREG) + return true; + + return false; } //----------------------------------------------------------------------------- bool Platform::isDirectory(const char *path) { - if (!path || !*path) - return false; - - // make sure we can stat the file - struct stat statData; - if( stat(path, &statData) < 0 ) - return false; - - // now see if it's a directory - if( (statData.st_mode & S_IFMT) == S_IFDIR) - return true; - - return false; + if (!path || !*path) + return false; + + // make sure we can stat the file + struct stat statData; + if( stat(path, &statData) < 0 ) + return false; + + // now see if it's a directory + if( (statData.st_mode & S_IFMT) == S_IFDIR) + return true; + + return false; } S32 Platform::getFileSize(const char* pFilePath) { - if (!pFilePath || !*pFilePath) - return 0; - - struct stat statData; - if( stat(pFilePath, &statData) < 0 ) - return 0; - - // and return it's size in bytes - return (S32)statData.st_size; + if (!pFilePath || !*pFilePath) + return 0; + + struct stat statData; + if( stat(pFilePath, &statData) < 0 ) + return 0; + + // and return it's size in bytes + return (S32)statData.st_size; } //----------------------------------------------------------------------------- bool Platform::isSubDirectory(const char *pathParent, const char *pathSub) { - char fullpath[MAX_MAC_PATH_LONG]; - dStrcpyl(fullpath, MAX_MAC_PATH_LONG, pathParent, "/", pathSub, NULL); - return isDirectory((const char *)fullpath); + char fullpath[MAX_MAC_PATH_LONG]; + dStrcpyl(fullpath, MAX_MAC_PATH_LONG, pathParent, "/", pathSub, NULL); + return isDirectory((const char *)fullpath); } //----------------------------------------------------------------------------- @@ -739,250 +739,250 @@ bool Platform::isSubDirectory(const char *pathParent, const char *pathSub) // ensures that the entry is a directory, and isnt on the ignore lists. inline bool isGoodDirectory(dirent* entry) { - return (entry->d_type == DT_DIR // is a dir - && dStrcmp(entry->d_name,".") != 0 // not here - && dStrcmp(entry->d_name,"..") != 0 // not parent - && !Platform::isExcludedDirectory(entry->d_name)); // not excluded + return (entry->d_type == DT_DIR // is a dir + && dStrcmp(entry->d_name,".") != 0 // not here + && dStrcmp(entry->d_name,"..") != 0 // not parent + && !Platform::isExcludedDirectory(entry->d_name)); // not excluded } //----------------------------------------------------------------------------- bool Platform::hasSubDirectory(const char *path) { - DIR *dir; - dirent *entry; - - dir = opendir(path); - if(!dir) - return false; // we got a bad path, so no, it has no subdirectory. - - while( (entry = readdir(dir)) ) - { - if(isGoodDirectory(entry) ) - { - closedir(dir); - return true; // we have a subdirectory, that isnt on the exclude list. - } - } - - closedir(dir); - return false; // either this dir had no subdirectories, or they were all on the exclude list. + DIR *dir; + dirent *entry; + + dir = opendir(path); + if(!dir) + return false; // we got a bad path, so no, it has no subdirectory. + + while( (entry = readdir(dir)) ) + { + if(isGoodDirectory(entry) ) + { + closedir(dir); + return true; // we have a subdirectory, that isnt on the exclude list. + } + } + + closedir(dir); + return false; // either this dir had no subdirectories, or they were all on the exclude list. } bool Platform::fileDelete(const char * name) { - return dFileDelete(name); + return dFileDelete(name); } static bool recurseDumpDirectories(const char *basePath, const char *subPath, Vector &directoryVector, S32 currentDepth, S32 recurseDepth, bool noBasePath) { - char Path[1024]; - DIR *dip; - struct dirent *d; - - dsize_t trLen = basePath ? dStrlen(basePath) : 0; - dsize_t subtrLen = subPath ? dStrlen(subPath) : 0; - char trail = trLen > 0 ? basePath[trLen - 1] : '\0'; - char subTrail = subtrLen > 0 ? subPath[subtrLen - 1] : '\0'; - - if (trail == '/') - { - if (subPath && (dStrncmp(subPath, "", 1) != 0)) - { - if (subTrail == '/') - dSprintf(Path, 1024, "%s%s", basePath, subPath); - else - dSprintf(Path, 1024, "%s%s/", basePath, subPath); - } - else - dSprintf(Path, 1024, "%s", basePath); - } - else - { - if (subPath && (dStrncmp(subPath, "", 1) != 0)) - { - if (subTrail == '/') - dSprintf(Path, 1024, "%s%s", basePath, subPath); - else - dSprintf(Path, 1024, "%s%s/", basePath, subPath); - } - else - dSprintf(Path, 1024, "%s/", basePath); - } - - dip = opendir(Path); - if (dip == NULL) - return false; - - ////////////////////////////////////////////////////////////////////////// - // add path to our return list ( provided it is valid ) - ////////////////////////////////////////////////////////////////////////// - if (!Platform::isExcludedDirectory(subPath)) - { - if (noBasePath) - { - // We have a path and it's not an empty string or an excluded directory - if ( (subPath && (dStrncmp (subPath, "", 1) != 0)) ) - directoryVector.push_back(StringTable->insert(subPath)); - } - else - { - if ( (subPath && (dStrncmp(subPath, "", 1) != 0)) ) - { - char szPath[1024]; - dMemset(szPath, 0, 1024); - if (trail == '/') - { - if ((basePath[dStrlen(basePath) - 1]) != '/') - dSprintf(szPath, 1024, "%s%s", basePath, &subPath[1]); - else - dSprintf(szPath, 1024, "%s%s", basePath, subPath); - } - else - { - if ((basePath[dStrlen(basePath) - 1]) != '/') - dSprintf(szPath, 1024, "%s%s", basePath, subPath); - else - dSprintf(szPath, 1024, "%s/%s", basePath, subPath); - } - - directoryVector.push_back(StringTable->insert(szPath)); - } - else - directoryVector.push_back(StringTable->insert(basePath)); - } - } - ////////////////////////////////////////////////////////////////////////// - // Iterate through and grab valid directories - ////////////////////////////////////////////////////////////////////////// - - while (d = readdir(dip)) - { - bool isDir; - isDir = false; - if (d->d_type == DT_UNKNOWN) - { - char child [1024]; - if ((Path[dStrlen(Path) - 1] == '/')) - dSprintf(child, 1024, "%s%s", Path, d->d_name); - else - dSprintf(child, 1024, "%s/%s", Path, d->d_name); - isDir = Platform::isDirectory (child); - } - else if (d->d_type & DT_DIR) - isDir = true; - - if ( isDir ) - { - if (dStrcmp(d->d_name, ".") == 0 || - dStrcmp(d->d_name, "..") == 0) - continue; - if (Platform::isExcludedDirectory(d->d_name)) - continue; - if ( (subPath && (dStrncmp(subPath, "", 1) != 0)) ) - { - char child[1024]; - if ((subPath[dStrlen(subPath) - 1] == '/')) - dSprintf(child, 1024, "%s%s", subPath, d->d_name); - else - dSprintf(child, 1024, "%s/%s", subPath, d->d_name); - if (currentDepth < recurseDepth || recurseDepth == -1 ) - recurseDumpDirectories(basePath, child, directoryVector, - currentDepth + 1, recurseDepth, - noBasePath); - } - else - { - char child[1024]; - if ( (basePath[dStrlen(basePath) - 1]) == '/') - dStrcpy (child, d->d_name); - else - dSprintf(child, 1024, "/%s", d->d_name); - if (currentDepth < recurseDepth || recurseDepth == -1) - recurseDumpDirectories(basePath, child, directoryVector, - currentDepth + 1, recurseDepth, - noBasePath); - } - } - } - closedir(dip); - return true; + char Path[1024]; + DIR *dip; + struct dirent *d; + + dsize_t trLen = basePath ? dStrlen(basePath) : 0; + dsize_t subtrLen = subPath ? dStrlen(subPath) : 0; + char trail = trLen > 0 ? basePath[trLen - 1] : '\0'; + char subTrail = subtrLen > 0 ? subPath[subtrLen - 1] : '\0'; + + if (trail == '/') + { + if (subPath && (dStrncmp(subPath, "", 1) != 0)) + { + if (subTrail == '/') + dSprintf(Path, 1024, "%s%s", basePath, subPath); + else + dSprintf(Path, 1024, "%s%s/", basePath, subPath); + } + else + dSprintf(Path, 1024, "%s", basePath); + } + else + { + if (subPath && (dStrncmp(subPath, "", 1) != 0)) + { + if (subTrail == '/') + dSprintf(Path, 1024, "%s%s", basePath, subPath); + else + dSprintf(Path, 1024, "%s%s/", basePath, subPath); + } + else + dSprintf(Path, 1024, "%s/", basePath); + } + + dip = opendir(Path); + if (dip == NULL) + return false; + + ////////////////////////////////////////////////////////////////////////// + // add path to our return list ( provided it is valid ) + ////////////////////////////////////////////////////////////////////////// + if (!Platform::isExcludedDirectory(subPath)) + { + if (noBasePath) + { + // We have a path and it's not an empty string or an excluded directory + if ( (subPath && (dStrncmp (subPath, "", 1) != 0)) ) + directoryVector.push_back(StringTable->insert(subPath)); + } + else + { + if ( (subPath && (dStrncmp(subPath, "", 1) != 0)) ) + { + char szPath[1024]; + dMemset(szPath, 0, 1024); + if (trail == '/') + { + if ((basePath[dStrlen(basePath) - 1]) != '/') + dSprintf(szPath, 1024, "%s%s", basePath, &subPath[1]); + else + dSprintf(szPath, 1024, "%s%s", basePath, subPath); + } + else + { + if ((basePath[dStrlen(basePath) - 1]) != '/') + dSprintf(szPath, 1024, "%s%s", basePath, subPath); + else + dSprintf(szPath, 1024, "%s/%s", basePath, subPath); + } + + directoryVector.push_back(StringTable->insert(szPath)); + } + else + directoryVector.push_back(StringTable->insert(basePath)); + } + } + ////////////////////////////////////////////////////////////////////////// + // Iterate through and grab valid directories + ////////////////////////////////////////////////////////////////////////// + + while (d = readdir(dip)) + { + bool isDir; + isDir = false; + if (d->d_type == DT_UNKNOWN) + { + char child [1024]; + if ((Path[dStrlen(Path) - 1] == '/')) + dSprintf(child, 1024, "%s%s", Path, d->d_name); + else + dSprintf(child, 1024, "%s/%s", Path, d->d_name); + isDir = Platform::isDirectory (child); + } + else if (d->d_type & DT_DIR) + isDir = true; + + if ( isDir ) + { + if (dStrcmp(d->d_name, ".") == 0 || + dStrcmp(d->d_name, "..") == 0) + continue; + if (Platform::isExcludedDirectory(d->d_name)) + continue; + if ( (subPath && (dStrncmp(subPath, "", 1) != 0)) ) + { + char child[1024]; + if ((subPath[dStrlen(subPath) - 1] == '/')) + dSprintf(child, 1024, "%s%s", subPath, d->d_name); + else + dSprintf(child, 1024, "%s/%s", subPath, d->d_name); + if (currentDepth < recurseDepth || recurseDepth == -1 ) + recurseDumpDirectories(basePath, child, directoryVector, + currentDepth + 1, recurseDepth, + noBasePath); + } + else + { + char child[1024]; + if ( (basePath[dStrlen(basePath) - 1]) == '/') + dStrcpy (child, d->d_name); + else + dSprintf(child, 1024, "/%s", d->d_name); + if (currentDepth < recurseDepth || recurseDepth == -1) + recurseDumpDirectories(basePath, child, directoryVector, + currentDepth + 1, recurseDepth, + noBasePath); + } + } + } + closedir(dip); + return true; } //----------------------------------------------------------------------------- bool Platform::dumpDirectories(const char *path, Vector &directoryVector, S32 depth, bool noBasePath) { - bool retVal = recurseDumpDirectories(path, "", directoryVector, 0, depth, noBasePath); - clearExcludedDirectories(); - return retVal; + bool retVal = recurseDumpDirectories(path, "", directoryVector, 0, depth, noBasePath); + clearExcludedDirectories(); + return retVal; } //----------------------------------------------------------------------------- static bool recurseDumpPath(const char* curPath, Vector& fileVector, U32 depth) { - DIR *dir; - dirent *entry; - - // be sure it opens. - dir = opendir(curPath); - if(!dir) - return false; - - // look inside the current directory - while( (entry = readdir(dir)) ) - { - // construct the full file path. we need this to get the file size and to recurse - U32 len = dStrlen(curPath) + entry->d_namlen + 2; - char pathbuf[len]; - dSprintf( pathbuf, len, "%s/%s", curPath, entry->d_name); - pathbuf[len] = '\0'; - - // ok, deal with directories and files seperately. - if( entry->d_type == DT_DIR ) - { - if( depth == 0) - continue; - - // filter out dirs we dont want. - if( !isGoodDirectory(entry) ) - continue; - - // recurse into the dir - recurseDumpPath( pathbuf, fileVector, depth-1); - } - else - { - //add the file entry to the list - // unlike recurseDumpDirectories(), we need to return more complex info here. - U32 fileSize = Platform::getFileSize(pathbuf); - fileVector.increment(); - Platform::FileInfo& rInfo = fileVector.last(); - rInfo.pFullPath = StringTable->insert(curPath); - rInfo.pFileName = StringTable->insert(entry->d_name); - rInfo.fileSize = fileSize; - } - } - closedir(dir); - return true; - + DIR *dir; + dirent *entry; + + // be sure it opens. + dir = opendir(curPath); + if(!dir) + return false; + + // look inside the current directory + while( (entry = readdir(dir)) ) + { + // construct the full file path. we need this to get the file size and to recurse + U32 len = dStrlen(curPath) + entry->d_namlen + 2; + char pathbuf[len]; + dSprintf( pathbuf, len, "%s/%s", curPath, entry->d_name); + pathbuf[len] = '\0'; + + // ok, deal with directories and files seperately. + if( entry->d_type == DT_DIR ) + { + if( depth == 0) + continue; + + // filter out dirs we dont want. + if( !isGoodDirectory(entry) ) + continue; + + // recurse into the dir + recurseDumpPath( pathbuf, fileVector, depth-1); + } + else + { + //add the file entry to the list + // unlike recurseDumpDirectories(), we need to return more complex info here. + U32 fileSize = Platform::getFileSize(pathbuf); + fileVector.increment(); + Platform::FileInfo& rInfo = fileVector.last(); + rInfo.pFullPath = StringTable->insert(curPath); + rInfo.pFileName = StringTable->insert(entry->d_name); + rInfo.fileSize = fileSize; + } + } + closedir(dir); + return true; + } //----------------------------------------------------------------------------- bool Platform::dumpPath(const char *path, Vector& fileVector, S32 depth) { - PROFILE_START(dumpPath); - int len = dStrlen(path); - char newpath[len+1]; - - dStrncpy(newpath,path,len); - newpath[len] = '\0'; // null terminate - if(newpath[len - 1] == '/') - newpath[len - 1] = '\0'; // cut off the trailing slash, if there is one - - bool ret = recurseDumpPath( newpath, fileVector, depth); - PROFILE_END(); - - return ret; + PROFILE_START(dumpPath); + int len = dStrlen(path); + char newpath[len+1]; + + dStrncpy(newpath,path,len); + newpath[len] = '\0'; // null terminate + if(newpath[len - 1] == '/') + newpath[len - 1] = '\0'; // cut off the trailing slash, if there is one + + bool ret = recurseDumpPath( newpath, fileVector, depth); + PROFILE_END(); + + return ret; } // TODO: implement stringToFileTime() @@ -993,57 +993,57 @@ bool Platform::fileTimeToString(FileTime * time, char * string, U32 strLen) { re //----------------------------------------------------------------------------- #if defined(TORQUE_DEBUG) ConsoleFunction(testHasSubdir,void,2,2,"tests platform::hasSubDirectory") { - Con::printf("testing %s",(const char*)argv[1]); - Platform::addExcludedDirectory(".svn"); - if(Platform::hasSubDirectory(argv[1])) - Con::printf(" has subdir"); - else - Con::printf(" does not have subdir"); + Con::printf("testing %s",(const char*)argv[1]); + Platform::addExcludedDirectory(".svn"); + if(Platform::hasSubDirectory(argv[1])) + Con::printf(" has subdir"); + else + Con::printf(" does not have subdir"); } ConsoleFunction(testDumpDirectories,void,4,4,"testDumpDirectories('path', int depth, bool noBasePath)") { - Vector paths; - const S32 depth = dAtoi(argv[2]); - const bool noBasePath = dAtob(argv[3]); - - Platform::addExcludedDirectory(".svn"); - - Platform::dumpDirectories(argv[1], paths, depth, noBasePath); - - Con::printf("Dumping directories starting from %s with depth %i", (const char*)argv[1],depth); - - for(Vector::iterator itr = paths.begin(); itr != paths.end(); itr++) { - Con::printf(*itr); - } - + Vector paths; + const S32 depth = dAtoi(argv[2]); + const bool noBasePath = dAtob(argv[3]); + + Platform::addExcludedDirectory(".svn"); + + Platform::dumpDirectories(argv[1], paths, depth, noBasePath); + + Con::printf("Dumping directories starting from %s with depth %i", (const char*)argv[1],depth); + + for(Vector::iterator itr = paths.begin(); itr != paths.end(); itr++) { + Con::printf(*itr); + } + } ConsoleFunction(testDumpPaths, void, 3, 3, "testDumpPaths('path', int depth)") { - Vector files; - S32 depth = dAtoi(argv[2]); - - Platform::addExcludedDirectory(".svn"); - - Platform::dumpPath(argv[1], files, depth); - - for(Vector::iterator itr = files.begin(); itr != files.end(); itr++) { - Con::printf("%s/%s",itr->pFullPath, itr->pFileName); - } + Vector files; + S32 depth = dAtoi(argv[2]); + + Platform::addExcludedDirectory(".svn"); + + Platform::dumpPath(argv[1], files, depth); + + for(Vector::iterator itr = files.begin(); itr != files.end(); itr++) { + Con::printf("%s/%s",itr->pFullPath, itr->pFileName); + } } //----------------------------------------------------------------------------- ConsoleFunction(testFileTouch, bool , 2,2, "testFileTouch('path')") { - return dFileTouch(argv[1]); + return dFileTouch(argv[1]); } ConsoleFunction(testGetFileTimes, bool, 2,2, "testGetFileTimes('path')") { - FileTime create, modify; - bool ok = Platform::getFileTimes(argv[1], &create, &modify); - Con::printf("%s Platform::getFileTimes %i, %i", ok ? "+OK" : "-FAIL", create, modify); - return ok; + FileTime create, modify; + bool ok = Platform::getFileTimes(argv[1], &create, &modify); + Con::printf("%s Platform::getFileTimes %i, %i", ok ? "+OK" : "-FAIL", create, modify); + return ok; } #endif