| 1086 | } |
| 1087 | |
| 1088 | String MakeUniquePath( const char *path, const char *fileName, const char *ext ) |
| 1089 | { |
| 1090 | Path filePath; |
| 1091 | |
| 1092 | filePath.setPath( path ); |
| 1093 | filePath.setFileName( fileName ); |
| 1094 | filePath.setExtension( ext ); |
| 1095 | |
| 1096 | // First get an upper bound on the range of filenames to search. This lets us |
| 1097 | // quickly skip past a large number of existing filenames. |
| 1098 | // Note: upper limit of 2^31 added to handle the degenerate case of a folder |
| 1099 | // with files named using the powers of 2, but plenty of space in between! |
| 1100 | U32 high = 1; |
| 1101 | while ( IsFile( filePath ) && ( high < 0x80000000 ) ) |
| 1102 | { |
| 1103 | high = high * 2; |
| 1104 | filePath.setFileName( String::ToString( "%s%d", fileName, high ) ); |
| 1105 | } |
| 1106 | |
| 1107 | // Now perform binary search for first filename in the range that doesn't exist |
| 1108 | // Note that the returned name will not be strictly numerically *first* if the |
| 1109 | // existing filenames are non-sequential (eg. 4,6,7), but it will still be unique. |
| 1110 | if ( high > 1 ) |
| 1111 | { |
| 1112 | U32 low = high / 2; |
| 1113 | while ( high - low > 1 ) |
| 1114 | { |
| 1115 | U32 probe = low + ( high - low ) / 2; |
| 1116 | filePath.setFileName( String::ToString( "%s%d", fileName, probe ) ); |
| 1117 | if ( IsFile( filePath ) ) |
| 1118 | low = probe; |
| 1119 | else |
| 1120 | high = probe; |
| 1121 | } |
| 1122 | |
| 1123 | // The 'high' index is guaranteed not to exist |
| 1124 | filePath.setFileName( String::ToString( "%s%d", fileName, high ) ); |
| 1125 | } |
| 1126 | |
| 1127 | return filePath.getFullPath(); |
| 1128 | } |
| 1129 | |
| 1130 | void StartFileChangeNotifications() { sgMountSystem.startFileChangeNotifications(); } |
| 1131 | void StopFileChangeNotifications() { sgMountSystem.stopFileChangeNotifications(); } |
no test coverage detected