* Internal function to truly open a file. * * @param filename The name of the file to open. * @param mode The mode to open the file in. Bit 1 means reading, bit 2 means writing. * @return An index value refering to the opened file, or FILE_INVALID. */
| 250 | * @return An index value refering to the opened file, or FILE_INVALID. |
| 251 | */ |
| 252 | static uint8 _File_Open(enum SearchDirectory dir, const char *filename, uint8 mode) |
| 253 | { |
| 254 | uint8 fileIndex; |
| 255 | FileInfo *fileInfo; |
| 256 | FileInfo *pakInfo = NULL; |
| 257 | |
| 258 | if ((mode & FILE_MODE_READ_WRITE) == 0) return FILE_INVALID; |
| 259 | |
| 260 | /* Find a free spot in our limited array */ |
| 261 | for (fileIndex = 0; fileIndex < FILE_MAX; fileIndex++) { |
| 262 | if (s_file[fileIndex].fp == NULL) break; |
| 263 | } |
| 264 | if (fileIndex >= FILE_MAX) { |
| 265 | Warning("Limit of %d open files reached.\n", FILE_MAX); |
| 266 | return FILE_INVALID; |
| 267 | } |
| 268 | |
| 269 | if(mode == FILE_MODE_READ && dir != SEARCHDIR_PERSONAL_DATA_DIR) { |
| 270 | /* Look in PAK only for READ only files, and not Personnal files */ |
| 271 | fileInfo = FileInfo_Find_ByName(filename, &pakInfo); |
| 272 | if (fileInfo == NULL) return FILE_INVALID; |
| 273 | if (pakInfo == NULL) { |
| 274 | /* Check if we can find the file outside any PAK file */ |
| 275 | s_file[fileIndex].fp = fopendatadir(dir, filename, "rb"); |
| 276 | if (s_file[fileIndex].fp == NULL) return FILE_INVALID; |
| 277 | |
| 278 | s_file[fileIndex].start = 0; |
| 279 | s_file[fileIndex].position = 0; |
| 280 | fseek(s_file[fileIndex].fp, 0, SEEK_END); |
| 281 | s_file[fileIndex].size = ftell(s_file[fileIndex].fp); |
| 282 | fseek(s_file[fileIndex].fp, 0, SEEK_SET); |
| 283 | } else { |
| 284 | /* file is found in PAK */ |
| 285 | if (pakInfo != s_currentPakInfo) { |
| 286 | if (s_currentPakFp != NULL) fclose(s_currentPakFp); |
| 287 | s_currentPakFp = fopendatadir(dir, pakInfo->filename, "rb"); |
| 288 | s_currentPakInfo = pakInfo; |
| 289 | } |
| 290 | s_file[fileIndex].fp = s_currentPakFp; |
| 291 | if (s_file[fileIndex].fp == NULL) return FILE_INVALID; |
| 292 | |
| 293 | s_file[fileIndex].start = fileInfo->filePosition; |
| 294 | s_file[fileIndex].position = 0; |
| 295 | s_file[fileIndex].size = fileInfo->fileSize; |
| 296 | |
| 297 | /* Go to the start of the file now */ |
| 298 | fseek(s_file[fileIndex].fp, s_file[fileIndex].start, SEEK_SET); |
| 299 | } |
| 300 | s_file[fileIndex].pakInfo = pakInfo; |
| 301 | return fileIndex; |
| 302 | } |
| 303 | |
| 304 | /* Check if we can find the file outside any PAK file */ |
| 305 | s_file[fileIndex].fp = fopendatadir(dir, filename, (mode == FILE_MODE_WRITE) ? "wb" : ((mode == FILE_MODE_READ_WRITE) ? "wb+" : "rb")); |
| 306 | if (s_file[fileIndex].fp != NULL) { |
| 307 | s_file[fileIndex].start = 0; |
| 308 | s_file[fileIndex].position = 0; |
| 309 | s_file[fileIndex].size = 0; |
no test coverage detected