aboutsummaryrefslogtreecommitdiff
path: root/src/open_lib.cpp
diff options
context:
space:
mode:
authorEven Rouault <even.rouault@spatialys.com>2019-12-25 18:44:45 +0100
committerEven Rouault <even.rouault@spatialys.com>2019-12-27 11:14:16 +0100
commitc4589fbe42e5fea07a03919d3484164f5fb70dd3 (patch)
tree37d526da7460deead544ebcfd0ed37db1945a0fc /src/open_lib.cpp
parent0a1f1fe469029ae31591dc8b51d20f5617496128 (diff)
downloadPROJ-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.cpp59
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;
}
/************************************************************************/