------------------------------------------------------------------------------------------------ Imports the given file into the given scene structure.
| 145 | // ------------------------------------------------------------------------------------------------ |
| 146 | // Imports the given file into the given scene structure. |
| 147 | void IFCImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSystem *pIOHandler) { |
| 148 | std::shared_ptr<IOStream> stream(pIOHandler->Open(pFile)); |
| 149 | if (!stream) { |
| 150 | ThrowException("Could not open file for reading"); |
| 151 | } |
| 152 | |
| 153 | // if this is a ifczip file, decompress its contents first |
| 154 | if (GetExtension(pFile) == "ifczip") { |
| 155 | #ifndef ASSIMP_BUILD_NO_COMPRESSED_IFC |
| 156 | unzFile zip = unzOpen(pFile.c_str()); |
| 157 | if (zip == nullptr) { |
| 158 | ThrowException("Could not open ifczip file for reading, unzip failed"); |
| 159 | } |
| 160 | |
| 161 | // chop 'zip' postfix |
| 162 | std::string fileName = pFile.substr(0, pFile.length() - 3); |
| 163 | |
| 164 | std::string::size_type s = pFile.find_last_of('\\'); |
| 165 | if (s == std::string::npos) { |
| 166 | s = pFile.find_last_of('/'); |
| 167 | } |
| 168 | if (s != std::string::npos) { |
| 169 | fileName = fileName.substr(s + 1); |
| 170 | } |
| 171 | |
| 172 | // search file (same name as the IFCZIP except for the file extension) and place file pointer there |
| 173 | if (UNZ_OK == unzGoToFirstFile(zip)) { |
| 174 | do { |
| 175 | // get file size, etc. |
| 176 | unz_file_info fileInfo; |
| 177 | char filename[256]; |
| 178 | unzGetCurrentFileInfo(zip, &fileInfo, filename, sizeof(filename), nullptr, 0, nullptr, 0); |
| 179 | if (GetExtension(filename) != "ifc") { |
| 180 | continue; |
| 181 | } |
| 182 | uint8_t *buff = new uint8_t[fileInfo.uncompressed_size]; |
| 183 | LogInfo("Decompressing IFCZIP file"); |
| 184 | unzOpenCurrentFile(zip); |
| 185 | size_t total = 0; |
| 186 | int read = 0; |
| 187 | do { |
| 188 | unsigned bufferSize = fileInfo.uncompressed_size < INT16_MAX ? static_cast<unsigned>(fileInfo.uncompressed_size) : INT16_MAX; |
| 189 | void *buffer = malloc(bufferSize); |
| 190 | read = unzReadCurrentFile(zip, buffer, bufferSize); |
| 191 | if (read > 0) { |
| 192 | memcpy((char *)buff + total, buffer, read); |
| 193 | total += read; |
| 194 | } |
| 195 | free(buffer); |
| 196 | } while (read > 0); |
| 197 | size_t filesize = fileInfo.uncompressed_size; |
| 198 | if (total == 0 || size_t(total) != filesize) { |
| 199 | delete[] buff; |
| 200 | ThrowException("Failed to decompress IFC ZIP file"); |
| 201 | } |
| 202 | unzCloseCurrentFile(zip); |
| 203 | stream = std::make_shared<MemoryIOStream>(buff, fileInfo.uncompressed_size, true); |
| 204 | if (unzGoToNextFile(zip) == UNZ_END_OF_LIST_OF_FILE) { |
nothing calls this directly
no test coverage detected