| 1152 | } |
| 1153 | |
| 1154 | ConstConfigRcPtr Config::CreateFromFile(const char * filename) |
| 1155 | { |
| 1156 | if (!filename || !*filename) |
| 1157 | { |
| 1158 | throw ExceptionMissingFile ("The config filepath is missing."); |
| 1159 | } |
| 1160 | |
| 1161 | // Check for URI Pattern: ocio://<config name> |
| 1162 | static const std::regex uriPattern(R"(ocio:\/\/([^\s]+))"); |
| 1163 | std::smatch match; |
| 1164 | const std::string uri = filename; |
| 1165 | if (std::regex_search(uri, match, uriPattern)) |
| 1166 | { |
| 1167 | return CreateFromBuiltinConfig(uri.c_str()); |
| 1168 | } |
| 1169 | |
| 1170 | std::ifstream ifstream = Platform::CreateInputFileStream( |
| 1171 | filename, |
| 1172 | std::ios_base::in | std::ios_base::binary |
| 1173 | ); |
| 1174 | |
| 1175 | if (ifstream.fail()) |
| 1176 | { |
| 1177 | std::ostringstream os; |
| 1178 | os << "Error could not read '" << filename; |
| 1179 | os << "' OCIO profile."; |
| 1180 | throw Exception (os.str().c_str()); |
| 1181 | } |
| 1182 | |
| 1183 | char magicNumber[2] = { 0 }; |
| 1184 | if (ifstream.read(magicNumber, 2)) |
| 1185 | { |
| 1186 | // Check if it is an OCIOZ archive. |
| 1187 | if (magicNumber[0] == 'P' && magicNumber[1] == 'K') |
| 1188 | { |
| 1189 | // Closing ifstream even though it should be closed by ifstream destructor (RAII). |
| 1190 | ifstream.close(); |
| 1191 | |
| 1192 | // The file should be an OCIOZ archive file. |
| 1193 | |
| 1194 | auto ciop = std::make_shared<CIOPOciozArchive>(); |
| 1195 | // Store archive absolute path. |
| 1196 | ciop->setArchiveAbsPath(filename); |
| 1197 | // Build the entries map. |
| 1198 | ciop->buildEntries(); |
| 1199 | return CreateFromConfigIOProxy(ciop); |
| 1200 | } |
| 1201 | } |
| 1202 | |
| 1203 | // Not an OCIOZ archive. Continue as usual. |
| 1204 | ifstream.clear(); |
| 1205 | ifstream.seekg(0); |
| 1206 | return Config::Impl::Read(ifstream, filename); |
| 1207 | } |
| 1208 | |
| 1209 | ConstConfigRcPtr Config::CreateFromStream(std::istream & istream) |
| 1210 | { |