Opens a HOG file. Future calls to cfopen(), etc. will look in this HOG. Parameters: libname - the path & filename of the HOG file NOTE: libname must be valid for the entire execution of the program. Therefore, it should either be a fully-specified path name, or the current directory must not change. Returns: 0 if error, else library handle that can be used to close the library
| 95 | // be a fully-specified path name, or the current directory must not change. |
| 96 | // Returns: 0 if error, else library handle that can be used to close the library |
| 97 | int cf_OpenLibrary(const std::filesystem::path &libname) { |
| 98 | FILE *fp; |
| 99 | int i; |
| 100 | uint32_t offset; |
| 101 | static int first_time = 1; |
| 102 | tHogHeader header{}; |
| 103 | tHogFileEntry entry{}; |
| 104 | |
| 105 | // allocation library structure |
| 106 | std::shared_ptr<library> lib = std::make_shared<library>(); |
| 107 | |
| 108 | // resolve library name |
| 109 | std::filesystem::path resolve_dir = libname.parent_path(); |
| 110 | std::filesystem::path resolve_name = libname; |
| 111 | |
| 112 | if (!resolve_dir.empty()) { |
| 113 | resolve_name = libname.filename(); |
| 114 | } |
| 115 | |
| 116 | std::filesystem::path t_out = cf_FindRealFileNameCaseInsensitive(resolve_name, resolve_dir); |
| 117 | if (t_out.empty()) { |
| 118 | return 0; // CF_NO_FILE |
| 119 | } |
| 120 | // re-assemble |
| 121 | if (!resolve_dir.empty()) |
| 122 | lib->name = resolve_dir / t_out; |
| 123 | else |
| 124 | lib->name = t_out; |
| 125 | |
| 126 | fp = fopen(lib->name.u8string().c_str(), "rb"); |
| 127 | if (fp == nullptr) { |
| 128 | return 0; // CF_NO_FILE; |
| 129 | } |
| 130 | // check if this if first library opened |
| 131 | if (first_time) { |
| 132 | atexit(cf_Close); |
| 133 | first_time = 0; |
| 134 | } |
| 135 | // read HOG header |
| 136 | if (!ReadHogHeader(fp, &header)) { |
| 137 | fclose(fp); |
| 138 | return 0; // CF_BAD_LIB; |
| 139 | } |
| 140 | lib->nfiles = header.nfiles; |
| 141 | // allocate CFILE hog info. |
| 142 | lib->entries.reserve(lib->nfiles); |
| 143 | lib->next = Libraries; |
| 144 | Libraries = lib; |
| 145 | // set data offset of first file |
| 146 | offset = header.file_data_offset; |
| 147 | // Go to index start |
| 148 | fseek(fp, HOG_HDR_SIZE, SEEK_SET); |
| 149 | |
| 150 | // read in index table |
| 151 | for (i = 0; i < lib->nfiles; i++) { |
| 152 | if (!ReadHogEntry(fp, &entry)) { |
| 153 | fclose(fp); |
| 154 | return 0; |