| 331 | } |
| 332 | |
| 333 | static std::optional<BaseObjectNNPtr> buildObject( |
| 334 | DatabaseContextPtr dbContext, const std::string &user_string, |
| 335 | const std::string &epoch, const std::string &kind, |
| 336 | const std::string &context, bool buildBoundCRSToWGS84, |
| 337 | CoordinateOperationContext::IntermediateCRSUse allowUseIntermediateCRS, |
| 338 | bool promoteTo3D, bool normalizeAxisOrder, bool quiet, Streamer &strm) { |
| 339 | BaseObjectPtr obj; |
| 340 | |
| 341 | std::string l_user_string(user_string); |
| 342 | if (!user_string.empty() && user_string[0] == '@') { |
| 343 | std::ifstream fs; |
| 344 | auto filename = user_string.substr(1); |
| 345 | fs.open(filename, std::fstream::in | std::fstream::binary); |
| 346 | if (!fs.is_open()) { |
| 347 | strm.cerr << context << ": cannot open " << filename << std::endl; |
| 348 | return std::nullopt; |
| 349 | } |
| 350 | l_user_string.clear(); |
| 351 | while (!fs.eof()) { |
| 352 | char buffer[256]; |
| 353 | fs.read(buffer, sizeof(buffer)); |
| 354 | l_user_string.append(buffer, static_cast<size_t>(fs.gcount())); |
| 355 | if (l_user_string.size() > 1000 * 1000) { |
| 356 | fs.close(); |
| 357 | strm.cerr << context << ": too big file" << std::endl; |
| 358 | return std::nullopt; |
| 359 | } |
| 360 | } |
| 361 | fs.close(); |
| 362 | } |
| 363 | if (!l_user_string.empty() && l_user_string.back() == '\n') { |
| 364 | l_user_string.resize(l_user_string.size() - 1); |
| 365 | } |
| 366 | if (!l_user_string.empty() && l_user_string.back() == '\r') { |
| 367 | l_user_string.resize(l_user_string.size() - 1); |
| 368 | } |
| 369 | |
| 370 | try { |
| 371 | auto tokens = split(l_user_string, ':'); |
| 372 | if (kind == "operation" && tokens.size() == 2) { |
| 373 | auto urn = "urn:ogc:def:coordinateOperation:" + tokens[0] + |
| 374 | "::" + tokens[1]; |
| 375 | obj = createFromUserInput(urn, dbContext).as_nullable(); |
| 376 | } else if ((kind == "ellipsoid" || kind == "datum" || |
| 377 | kind == "ensemble") && |
| 378 | tokens.size() == 2) { |
| 379 | auto urn = |
| 380 | "urn:ogc:def:" + kind + ":" + tokens[0] + "::" + tokens[1]; |
| 381 | obj = createFromUserInput(urn, dbContext).as_nullable(); |
| 382 | } else { |
| 383 | // Convenience to be able to use C escaped strings... |
| 384 | if (l_user_string.size() > 2 && l_user_string[0] == '"' && |
| 385 | l_user_string.back() == '"' && |
| 386 | l_user_string.find("\\\"") != std::string::npos) { |
| 387 | l_user_string = un_c_ify_string(l_user_string); |
| 388 | } |
| 389 | WKTParser wktParser; |
| 390 | if (wktParser.guessDialect(l_user_string) != |
no test coverage detected