* Opens a file for reading in a library, given the library id * @param filename * @param libhandle * @return */
| 234 | * @return |
| 235 | */ |
| 236 | CFILE *cf_OpenFileInLibrary(const std::filesystem::path &filename, int libhandle) { |
| 237 | if (libhandle <= 0) |
| 238 | return nullptr; |
| 239 | |
| 240 | std::shared_ptr<library> lib = Libraries; |
| 241 | |
| 242 | // find the library that we want to use |
| 243 | while (lib) { |
| 244 | if (lib->handle == libhandle) |
| 245 | break; |
| 246 | lib = lib->next; |
| 247 | } |
| 248 | |
| 249 | if (nullptr == lib) { |
| 250 | // couldn't find the library handle |
| 251 | return nullptr; |
| 252 | } |
| 253 | |
| 254 | // now do a binary search for the file entry |
| 255 | int i, first = 0, last = lib->nfiles - 1, c; |
| 256 | bool found = false; |
| 257 | |
| 258 | do { |
| 259 | i = (first + last) / 2; |
| 260 | c = stricmp(filename.u8string().c_str(), lib->entries[i]->name); // compare to current |
| 261 | if (c == 0) { |
| 262 | found = true; |
| 263 | break; |
| 264 | } |
| 265 | if (first >= last) // exhausted search |
| 266 | break; |
| 267 | if (c > 0) // search key after check key |
| 268 | first = i + 1; |
| 269 | else // search key before check key |
| 270 | last = i - 1; |
| 271 | } while (true); |
| 272 | |
| 273 | if (!found) |
| 274 | return nullptr; // file not in library |
| 275 | |
| 276 | // open the file for reading |
| 277 | FILE *fp; |
| 278 | int r; |
| 279 | // See if there's an available FILE |
| 280 | if (lib->file) { |
| 281 | fp = lib->file; |
| 282 | lib->file = nullptr; |
| 283 | } else { |
| 284 | fp = fopen(lib->name.u8string().c_str(), "rb"); |
| 285 | if (!fp) { |
| 286 | mprintf(1, "Error opening library <%s> when opening file <%s>; errno=%d.", |
| 287 | lib->name.u8string().c_str(), filename.u8string().c_str(), errno); |
| 288 | Int3(); |
| 289 | return nullptr; |
| 290 | } |
| 291 | } |
| 292 | CFILE *cfile = (CFILE *)mem_malloc(sizeof(*cfile)); |
| 293 | if (!cfile) |