aboutsummaryrefslogtreecommitdiff
path: root/test/unit/test_network.cpp
diff options
context:
space:
mode:
authorEven Rouault <even.rouault@spatialys.com>2020-01-13 22:30:59 +0100
committerEven Rouault <even.rouault@spatialys.com>2020-01-14 23:33:16 +0100
commit9cb40a8322f4ccbf8305daf368308783969d1c94 (patch)
tree1702a990752eae1c3f41ab67e9eba2843adb3f2a /test/unit/test_network.cpp
parent034238e5014ae965a7dbd1e2bf26f7227196e987 (diff)
downloadPROJ-9cb40a8322f4ccbf8305daf368308783969d1c94.tar.gz
PROJ-9cb40a8322f4ccbf8305daf368308783969d1c94.zip
Add proj_context_set_fileapi() and proj_context_set_sqlite3_vfs_name() (fixes #866)
Diffstat (limited to 'test/unit/test_network.cpp')
-rw-r--r--test/unit/test_network.cpp144
1 files changed, 144 insertions, 0 deletions
diff --git a/test/unit/test_network.cpp b/test/unit/test_network.cpp
index e959fd54..688e61e5 100644
--- a/test/unit/test_network.cpp
+++ b/test/unit/test_network.cpp
@@ -1707,6 +1707,150 @@ TEST(networking, download_whole_files) {
rmdir("proj_test_tmp");
}
+// ---------------------------------------------------------------------------
+
+TEST(networking, file_api) {
+ if (!networkAccessOK) {
+ return;
+ }
+
+ proj_cleanup();
+ unlink("proj_test_tmp/cache.db");
+ unlink("proj_test_tmp/dvr90.tif");
+ rmdir("proj_test_tmp");
+
+ putenv(const_cast<char *>("PROJ_IGNORE_USER_WRITABLE_DIRECTORY="));
+ putenv(const_cast<char *>("PROJ_USER_WRITABLE_DIRECTORY=./proj_test_tmp"));
+ putenv(const_cast<char *>("PROJ_FULL_FILE_CHUNK_SIZE=30000"));
+ auto ctx = proj_context_create();
+ proj_context_set_enable_network(ctx, true);
+
+ struct UserData {
+ bool in_open = false;
+ bool in_read = false;
+ bool in_write = false;
+ bool in_seek = false;
+ bool in_tell = false;
+ bool in_close = false;
+ bool in_exists = false;
+ bool in_mkdir = false;
+ bool in_unlink = false;
+ bool in_rename = false;
+ };
+
+ struct PROJ_FILE_API api;
+ api.version = 1;
+ api.open_cbk = [](PJ_CONTEXT *, const char *filename,
+ PROJ_OPEN_ACCESS access,
+ void *user_data) -> PROJ_FILE_HANDLE * {
+ static_cast<UserData *>(user_data)->in_open = true;
+ return reinterpret_cast<PROJ_FILE_HANDLE *>(fopen(
+ filename,
+ access == PROJ_OPEN_ACCESS_READ_ONLY
+ ? "rb"
+ : access == PROJ_OPEN_ACCESS_READ_UPDATE ? "r+b" : "w+b"));
+ };
+ api.read_cbk = [](PJ_CONTEXT *, PROJ_FILE_HANDLE *handle, void *buffer,
+ size_t sizeBytes, void *user_data) -> size_t {
+ static_cast<UserData *>(user_data)->in_read = true;
+ return fread(buffer, 1, sizeBytes, reinterpret_cast<FILE *>(handle));
+ };
+ api.write_cbk = [](PJ_CONTEXT *, PROJ_FILE_HANDLE *handle,
+ const void *buffer, size_t sizeBytes,
+ void *user_data) -> size_t {
+ static_cast<UserData *>(user_data)->in_write = true;
+ return fwrite(buffer, 1, sizeBytes, reinterpret_cast<FILE *>(handle));
+ };
+ api.seek_cbk = [](PJ_CONTEXT *, PROJ_FILE_HANDLE *handle, long long offset,
+ int whence, void *user_data) -> int {
+ static_cast<UserData *>(user_data)->in_seek = true;
+ return fseek(reinterpret_cast<FILE *>(handle),
+ static_cast<long>(offset), whence) == 0;
+ };
+ api.tell_cbk = [](PJ_CONTEXT *, PROJ_FILE_HANDLE *handle,
+ void *user_data) -> unsigned long long {
+ static_cast<UserData *>(user_data)->in_tell = true;
+ return ftell(reinterpret_cast<FILE *>(handle));
+ };
+ api.close_cbk = [](PJ_CONTEXT *, PROJ_FILE_HANDLE *handle,
+ void *user_data) -> void {
+ static_cast<UserData *>(user_data)->in_close = true;
+ fclose(reinterpret_cast<FILE *>(handle));
+ };
+ api.exists_cbk = [](PJ_CONTEXT *, const char *filename,
+ void *user_data) -> int {
+ static_cast<UserData *>(user_data)->in_exists = true;
+ struct stat buf;
+ return stat(filename, &buf) == 0;
+ };
+ api.mkdir_cbk = [](PJ_CONTEXT *, const char *filename,
+ void *user_data) -> int {
+ static_cast<UserData *>(user_data)->in_mkdir = true;
+#ifdef _WIN32
+ return mkdir(filename) == 0;
+#else
+ return mkdir(filename, 0755) == 0;
+#endif
+ };
+ api.unlink_cbk = [](PJ_CONTEXT *, const char *filename,
+ void *user_data) -> int {
+ static_cast<UserData *>(user_data)->in_unlink = true;
+ return unlink(filename) == 0;
+ };
+ api.rename_cbk = [](PJ_CONTEXT *, const char *oldPath, const char *newPath,
+ void *user_data) -> int {
+ static_cast<UserData *>(user_data)->in_rename = true;
+ return rename(oldPath, newPath) == 0;
+ };
+
+ UserData userData;
+ ASSERT_TRUE(proj_context_set_fileapi(ctx, &api, &userData));
+
+ ASSERT_TRUE(proj_is_download_needed(ctx, "dvr90.gtx", false));
+
+ ASSERT_TRUE(proj_download_file(ctx, "dvr90.gtx", false, nullptr, nullptr));
+
+ ASSERT_TRUE(userData.in_open);
+ ASSERT_FALSE(userData.in_read);
+ ASSERT_TRUE(userData.in_write);
+ ASSERT_TRUE(userData.in_close);
+ ASSERT_TRUE(userData.in_exists);
+ ASSERT_TRUE(userData.in_mkdir);
+ ASSERT_TRUE(userData.in_unlink);
+ ASSERT_TRUE(userData.in_rename);
+
+ proj_context_set_enable_network(ctx, false);
+
+ const char *pipeline =
+ "+proj=pipeline "
+ "+step +proj=unitconvert +xy_in=deg +xy_out=rad "
+ "+step +proj=vgridshift +grids=dvr90.gtx +multiplier=1 "
+ "+step +proj=unitconvert +xy_in=rad +xy_out=deg";
+
+ auto P = proj_create(ctx, pipeline);
+ ASSERT_NE(P, nullptr);
+
+ double lon = 12;
+ double lat = 56;
+ double z = 0;
+ proj_trans_generic(P, PJ_FWD, &lon, sizeof(double), 1, &lat, sizeof(double),
+ 1, &z, sizeof(double), 1, nullptr, 0, 0);
+ EXPECT_NEAR(z, 36.5909996032715, 1e-10);
+
+ proj_destroy(P);
+
+ ASSERT_TRUE(userData.in_read);
+ ASSERT_TRUE(userData.in_seek);
+
+ proj_context_destroy(ctx);
+ putenv(const_cast<char *>("PROJ_IGNORE_USER_WRITABLE_DIRECTORY=YES"));
+ putenv(const_cast<char *>("PROJ_USER_WRITABLE_DIRECTORY="));
+ putenv(const_cast<char *>("PROJ_FULL_FILE_CHUNK_SIZE="));
+ unlink("proj_test_tmp/cache.db");
+ unlink("proj_test_tmp/dvr90.tif");
+ rmdir("proj_test_tmp");
+}
+
#endif
} // namespace