diff options
| author | Even Rouault <even.rouault@spatialys.com> | 2019-12-25 18:44:45 +0100 |
|---|---|---|
| committer | Even Rouault <even.rouault@spatialys.com> | 2019-12-27 11:14:16 +0100 |
| commit | c4589fbe42e5fea07a03919d3484164f5fb70dd3 (patch) | |
| tree | 37d526da7460deead544ebcfd0ed37db1945a0fc /src/open_lib.cpp | |
| parent | 0a1f1fe469029ae31591dc8b51d20f5617496128 (diff) | |
| download | PROJ-c4589fbe42e5fea07a03919d3484164f5fb70dd3.tar.gz PROJ-c4589fbe42e5fea07a03919d3484164f5fb70dd3.zip | |
Network: automatically use CDN resources when local resources not available, and networking enabled
Diffstat (limited to 'src/open_lib.cpp')
| -rw-r--r-- | src/open_lib.cpp | 59 |
1 files changed, 45 insertions, 14 deletions
diff --git a/src/open_lib.cpp b/src/open_lib.cpp index 6bdd5510..926505ba 100644 --- a/src/open_lib.cpp +++ b/src/open_lib.cpp @@ -203,6 +203,27 @@ static const char *get_path_from_win32_projlib(const char *name, std::string& ou /* pj_open_lib_internal() */ /************************************************************************/ +#ifdef WIN32 +static const char dir_chars[] = "/\\"; +static const char dirSeparator = ';'; +#else +static const char dir_chars[] = "/"; +static const char dirSeparator = ':'; +#endif + +static bool is_tilde_slash(const char* name) +{ + return *name == '~' && strchr(dir_chars,name[1]); +} + +static bool is_rel_or_absolute_filename(const char *name) +{ + return strchr(dir_chars,*name) + || (*name == '.' && strchr(dir_chars,name[1])) + || (!strncmp(name, "..", 2) && strchr(dir_chars,name[2])) + || (name[0] != '\0' && name[1] == ':' && strchr(dir_chars,name[2])); +} + static void* pj_open_lib_internal(projCtx ctx, const char *name, const char *mode, void* (*open_file)(projCtx, const char*, const char*), @@ -211,13 +232,6 @@ pj_open_lib_internal(projCtx ctx, const char *name, const char *mode, std::string fname; const char *sysname = nullptr; void* fid = nullptr; -#ifdef WIN32 - static const char dir_chars[] = "/\\"; - const char dirSeparator = ';'; -#else - static const char dir_chars[] = "/"; - const char dirSeparator = ':'; -#endif if( ctx == nullptr ) { ctx = pj_get_default_ctx(); @@ -227,7 +241,7 @@ pj_open_lib_internal(projCtx ctx, const char *name, const char *mode, out_full_filename[0] = '\0'; /* check if ~/name */ - if (*name == '~' && strchr(dir_chars,name[1]) ) + if (is_tilde_slash(name)) if ((sysname = getenv("HOME")) != nullptr) { fname = sysname; fname += DIR_CHAR; @@ -236,11 +250,8 @@ pj_open_lib_internal(projCtx ctx, const char *name, const char *mode, } else return nullptr; - /* or fixed path: /name, ./name or ../name */ - else if (strchr(dir_chars,*name) - || (*name == '.' && strchr(dir_chars,name[1])) - || (!strncmp(name, "..", 2) && strchr(dir_chars,name[2])) - || (name[0] != '\0' && name[1] == ':' && strchr(dir_chars,name[2])) + /* or fixed path: /name, ./name or ../name or http[s]:// */ + else if (is_rel_or_absolute_filename(name) || starts_with(name, "http://") || starts_with(name, "https://")) sysname = name; @@ -344,11 +355,31 @@ static void* pj_open_file_with_manager(projCtx ctx, const char *name, std::unique_ptr<NS_PROJ::File> NS_PROJ::FileManager::open_resource_file( projCtx ctx, const char *name) { - return std::unique_ptr<NS_PROJ::File>( + auto file = std::unique_ptr<NS_PROJ::File>( reinterpret_cast<NS_PROJ::File*>( pj_open_lib_internal(ctx, name, "rb", pj_open_file_with_manager, nullptr, 0))); + if( file == nullptr && + !is_tilde_slash(name) && + !is_rel_or_absolute_filename(name) && + !starts_with(name, "http://") && + !starts_with(name, "https://") && + pj_context_is_network_enabled(ctx) ) { + std::string remote_file("https://cdn.proj.org/"); + remote_file += name; + auto pos = remote_file.rfind('.'); + if( pos + 4 == remote_file.size() ) { + remote_file = remote_file.substr(0, pos) + ".tif"; + file = open(ctx, remote_file.c_str()); + if( file ) { + pj_log( ctx, PJ_LOG_DEBUG_MAJOR, + "Using %s", remote_file.c_str() ); + pj_ctx_set_errno( ctx, 0 ); + } + } + } + return file; } /************************************************************************/ |
