Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/ctx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ projCppContext *pj_ctx::get_cpp_context() {
/************************************************************************/

void pj_ctx::set_search_paths(const std::vector<std::string> &search_paths_in) {
lookupedFiles.clear();
search_paths = search_paths_in;
delete[] c_compat_paths;
c_compat_paths = nullptr;
Expand Down
15 changes: 15 additions & 0 deletions src/filemanager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1779,6 +1779,16 @@ NS_PROJ::FileManager::open_resource_file(PJ_CONTEXT *ctx, const char *name,
*/
int pj_find_file(PJ_CONTEXT *ctx, const char *short_filename,
char *out_full_filename, size_t out_full_filename_size) {
const auto iter = ctx->lookupedFiles.find(short_filename);
if (iter != ctx->lookupedFiles.end()) {
if (iter->second.empty()) {
out_full_filename[0] = 0;
return 0;
}
snprintf(out_full_filename, out_full_filename_size, "%s",
iter->second.c_str());
return 1;
}
const bool old_network_enabled =
proj_context_is_network_enabled(ctx) != FALSE;
if (old_network_enabled)
Expand All @@ -1787,6 +1797,11 @@ int pj_find_file(PJ_CONTEXT *ctx, const char *short_filename,
ctx, short_filename, out_full_filename, out_full_filename_size);
if (old_network_enabled)
proj_context_set_enable_network(ctx, true);
if (file) {
ctx->lookupedFiles[short_filename] = out_full_filename;
} else {
ctx->lookupedFiles[short_filename] = std::string();
}
return file != nullptr;
}

Expand Down
42 changes: 23 additions & 19 deletions src/iso19111/io.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12244,25 +12244,35 @@ PROJStringParser::createFromPROJString(const std::string &projString) {
if (d->steps_.size() == 1 && d->steps_[0].isInit &&
!d->steps_[0].inverted) {

auto ctx = d->ctx_ ? d->ctx_ : proj_context_create();
if (!ctx) {
throw ParsingException("out of memory");
}
PJContextHolder contextHolder(ctx, ctx != d->ctx_);

// Those used to come from a text init file
// We only support them in compatibility mode
const std::string &stepName = d->steps_[0].name;
if (ci_starts_with(stepName, "epsg:") ||
ci_starts_with(stepName, "IGNF:")) {

/* We create a new context so as to avoid messing up with the */
/* errorno of the main context, when trying to find the likely */
/* missing epsg file */
auto ctx = proj_context_create();
if (!ctx) {
throw ParsingException("out of memory");
}
PJContextHolder contextHolder(ctx, true);
if (d->ctx_) {
ctx->set_search_paths(d->ctx_->search_paths);
ctx->file_finder = d->ctx_->file_finder;
ctx->file_finder_user_data = d->ctx_->file_finder_user_data;
}
struct BackupContextErrno {
PJ_CONTEXT *m_ctxt = nullptr;
int m_last_errno = 0;

explicit BackupContextErrno(PJ_CONTEXT *ctxtIn)
: m_ctxt(ctxtIn), m_last_errno(m_ctxt->last_errno) {
m_ctxt->debug_level = PJ_LOG_ERROR;
}

~BackupContextErrno() { m_ctxt->last_errno = m_last_errno; }

BackupContextErrno(const BackupContextErrno &) = delete;
BackupContextErrno &
operator=(const BackupContextErrno &) = delete;
};

BackupContextErrno backupContextErrno(ctx);

bool usePROJ4InitRules = d->usePROJ4InitRules_;
if (!usePROJ4InitRules) {
Expand Down Expand Up @@ -12369,12 +12379,6 @@ PROJStringParser::createFromPROJString(const std::string &projString) {
}
}

auto ctx = d->ctx_ ? d->ctx_ : proj_context_create();
if (!ctx) {
throw ParsingException("out of memory");
}
PJContextHolder contextHolder(ctx, ctx != d->ctx_);

paralist *init = pj_mkparam(("init=" + d->steps_[0].name).c_str());
if (!init) {
throw ParsingException("out of memory");
Expand Down
3 changes: 3 additions & 0 deletions src/proj_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -806,6 +806,9 @@ struct pj_ctx {
void *user_data) = nullptr;
void *file_finder_user_data = nullptr;

// Cache result of pj_find_file()
std::map<std::string, std::string> lookupedFiles{};

bool defer_grid_opening = false; // set transiently by pj_obj_create()

projFileApiCallbackAndData fileApi{};
Expand Down