summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gyp/asset-fs.gypi2
-rw-r--r--gyp/asset-zip.gypi2
-rw-r--r--include/mbgl/storage/online_file_source.hpp2
-rw-r--r--platform/android/src/asset_file_source.cpp111
-rw-r--r--platform/default/asset_file_source.cpp79
-rw-r--r--platform/default/asset_request_fs.cpp234
-rw-r--r--platform/default/asset_request_zip.cpp319
-rw-r--r--platform/default/default_file_source.cpp28
-rw-r--r--platform/default/online_file_source.cpp26
-rw-r--r--src/mbgl/storage/asset_context_base.hpp20
-rw-r--r--src/mbgl/storage/asset_file_source.hpp26
-rw-r--r--src/mbgl/util/url.cpp8
-rw-r--r--src/mbgl/util/url.hpp2
-rw-r--r--test/api/annotations.cpp22
-rw-r--r--test/api/custom_layer.cpp2
-rw-r--r--test/api/repeated_render.cpp6
-rw-r--r--test/fixtures/api/annotation.json5
-rw-r--r--test/fixtures/util.cpp8
-rw-r--r--test/fixtures/util.hpp2
-rw-r--r--test/storage/asset_file_source.cpp (renamed from test/storage/file_reading.cpp)71
-rw-r--r--test/storage/directory_reading.cpp40
-rw-r--r--test/test.gypi3
22 files changed, 287 insertions, 731 deletions
diff --git a/gyp/asset-fs.gypi b/gyp/asset-fs.gypi
index a4f3f7f4f0..30dc9e07aa 100644
--- a/gyp/asset-fs.gypi
+++ b/gyp/asset-fs.gypi
@@ -7,7 +7,7 @@
'hard_dependency': 1,
'sources': [
- '../platform/default/asset_request_fs.cpp',
+ '../platform/default/asset_file_source.cpp',
],
'include_dirs': [
diff --git a/gyp/asset-zip.gypi b/gyp/asset-zip.gypi
index 8a19da4fcd..9011981f6c 100644
--- a/gyp/asset-zip.gypi
+++ b/gyp/asset-zip.gypi
@@ -7,7 +7,7 @@
'hard_dependency': 1,
'sources': [
- '../platform/default/asset_request_zip.cpp',
+ '../platform/android/src/asset_file_source.cpp',
],
'include_dirs': [
diff --git a/include/mbgl/storage/online_file_source.hpp b/include/mbgl/storage/online_file_source.hpp
index 2164d40032..1725af844d 100644
--- a/include/mbgl/storage/online_file_source.hpp
+++ b/include/mbgl/storage/online_file_source.hpp
@@ -12,7 +12,7 @@ template <typename T> class Thread;
class OnlineFileSource : public FileSource {
public:
- OnlineFileSource(FileCache *cache, const std::string &root = "");
+ OnlineFileSource(FileCache*);
~OnlineFileSource() override;
void setAccessToken(const std::string& t) { accessToken = t; }
diff --git a/platform/android/src/asset_file_source.cpp b/platform/android/src/asset_file_source.cpp
new file mode 100644
index 0000000000..1f02f9cf4a
--- /dev/null
+++ b/platform/android/src/asset_file_source.cpp
@@ -0,0 +1,111 @@
+#include <mbgl/storage/asset_file_source.hpp>
+#include <mbgl/storage/response.hpp>
+#include <mbgl/util/util.hpp>
+#include <mbgl/util/thread.hpp>
+
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wshadow"
+#include <zip.h>
+#pragma GCC diagnostic pop
+
+namespace {
+
+struct ZipHolder {
+ ZipHolder(struct zip* archive_) : archive(archive_) {}
+
+ ~ZipHolder() {
+ if (archive) ::zip_close(archive);
+ }
+
+ struct zip* archive;
+};
+
+struct ZipFileHolder {
+ ZipFileHolder(struct zip_file* file_) : file(file_) {}
+
+ ~ZipFileHolder() {
+ if (file) ::zip_fclose(file);
+ }
+
+ struct zip_file* file;
+};
+
+}
+
+namespace mbgl {
+
+class AssetFileRequest : public FileRequest {
+public:
+ AssetFileRequest(std::unique_ptr<WorkRequest> workRequest_)
+ : workRequest(std::move(workRequest_)) {
+ }
+
+ std::unique_ptr<WorkRequest> workRequest;
+};
+
+class AssetFileSource::Impl {
+public:
+ Impl(const std::string& root_)
+ : root(root_) {
+ }
+
+ void request(const std::string& url, FileSource::Callback callback) {
+ ZipHolder archive = ::zip_open(root.c_str(), 0, nullptr);
+ if (!archive.archive) {
+ reportError(Response::Error::Reason::Other, "Could not open zip archive", callback);
+ return;
+ }
+
+ struct zip_stat stat;
+ ::zip_stat_init(&stat);
+
+ std::string path = std::string("assets/") + url.substr(8);
+ int ret = ::zip_stat(archive.archive, path.c_str(), 0, &stat);
+ if (ret < 0 || !(stat.valid & ZIP_STAT_SIZE)) {
+ reportError(Response::Error::Reason::NotFound, "Could not stat file in zip archive", callback);
+ return;
+ }
+
+ ZipFileHolder file = ::zip_fopen(archive.archive, path.c_str(), 0);
+ if (!file.file) {
+ reportError(Response::Error::Reason::NotFound, "Could not open file in zip archive", callback);
+ return;
+ }
+
+ std::shared_ptr<std::string> buf = std::make_shared<std::string>();
+ buf->resize(stat.size);
+
+ ret = ::zip_fread(file.file, &buf->front(), stat.size);
+ if (ret < 0) {
+ reportError(Response::Error::Reason::Other, "Could not read file in zip archive", callback);
+ return;
+ }
+
+ Response response;
+ response.data = buf;
+ callback(response);
+ }
+
+ void reportError(Response::Error::Reason reason, const char * message, FileSource::Callback callback) {
+ Response response;
+ response.error = std::make_unique<Response::Error>(reason, message);
+ callback(response);
+ }
+
+private:
+ std::string root;
+};
+
+AssetFileSource::AssetFileSource(const std::string& root)
+ : thread(std::make_unique<util::Thread<Impl>>(
+ util::ThreadContext{"AssetFileSource", util::ThreadType::Worker, util::ThreadPriority::Regular},
+ root.empty() ? platform::assetRoot() : root)) {
+}
+
+AssetFileSource::~AssetFileSource() = default;
+
+std::unique_ptr<FileRequest> AssetFileSource::request(const Resource& resource, Callback callback) {
+ return std::make_unique<AssetFileRequest>(thread->invokeWithCallback(&Impl::request, callback, resource.url));
+}
+
+}
diff --git a/platform/default/asset_file_source.cpp b/platform/default/asset_file_source.cpp
new file mode 100644
index 0000000000..5aa5730c94
--- /dev/null
+++ b/platform/default/asset_file_source.cpp
@@ -0,0 +1,79 @@
+#include <mbgl/storage/asset_file_source.hpp>
+#include <mbgl/storage/response.hpp>
+#include <mbgl/util/string.hpp>
+#include <mbgl/util/thread.hpp>
+#include <mbgl/util/url.hpp>
+#include <mbgl/util/util.hpp>
+#include <mbgl/util/io.hpp>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+namespace mbgl {
+
+class AssetFileRequest : public FileRequest {
+public:
+ AssetFileRequest(std::unique_ptr<WorkRequest> workRequest_)
+ : workRequest(std::move(workRequest_)) {
+ }
+
+ std::unique_ptr<WorkRequest> workRequest;
+};
+
+class AssetFileSource::Impl {
+public:
+ Impl(const std::string& root_)
+ : root(root_) {
+ }
+
+ void request(const std::string& url, FileSource::Callback callback) {
+ std::string path;
+
+ if (url.size() <= 8 || url[8] == '/') {
+ // This is an empty or absolute path.
+ path = mbgl::util::percentDecode(url.substr(8));
+ } else {
+ // This is a relative path. Prefix with the application root.
+ path = root + "/" + mbgl::util::percentDecode(url.substr(8));
+ }
+
+ Response response;
+
+ struct stat buf;
+ int result = stat(path.c_str(), &buf);
+
+ if (result == 0 && S_ISDIR(buf.st_mode)) {
+ response.error = std::make_unique<Response::Error>(Response::Error::Reason::NotFound);
+ } else if (result == -1 && errno == ENOENT) {
+ response.error = std::make_unique<Response::Error>(Response::Error::Reason::NotFound);
+ } else {
+ try {
+ response.data = std::make_shared<std::string>(util::read_file(path));
+ } catch (...) {
+ response.error = std::make_unique<Response::Error>(
+ Response::Error::Reason::Other,
+ util::toString(std::current_exception()));
+ }
+ }
+
+ callback(response);
+ }
+
+private:
+ std::string root;
+};
+
+AssetFileSource::AssetFileSource(const std::string& root)
+ : thread(std::make_unique<util::Thread<Impl>>(
+ util::ThreadContext{"AssetFileSource", util::ThreadType::Worker, util::ThreadPriority::Regular},
+ root.empty() ? platform::assetRoot() : root)) {
+}
+
+AssetFileSource::~AssetFileSource() = default;
+
+std::unique_ptr<FileRequest> AssetFileSource::request(const Resource& resource, Callback callback) {
+ return std::make_unique<AssetFileRequest>(thread->invokeWithCallback(&Impl::request, callback, resource.url));
+}
+
+} // namespace mbgl
diff --git a/platform/default/asset_request_fs.cpp b/platform/default/asset_request_fs.cpp
deleted file mode 100644
index 2ef22f9586..0000000000
--- a/platform/default/asset_request_fs.cpp
+++ /dev/null
@@ -1,234 +0,0 @@
-#include <mbgl/storage/asset_context_base.hpp>
-#include <mbgl/storage/response.hpp>
-#include <mbgl/util/string.hpp>
-#include <mbgl/util/thread.hpp>
-#include <mbgl/util/url.hpp>
-#include <mbgl/util/util.hpp>
-
-#include <errno.h>
-#include <fcntl.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <unistd.h>
-
-namespace {
-
-struct FDHolder {
- FDHolder(int fd_) : fd(fd_) {}
-
- ~FDHolder() {
- if (fd >= 0) ::close(fd);
- }
-
- int fd;
-};
-
-class FileIOWorker {
-public:
- FileIOWorker() = default;
-
- void open(const std::string& path, int flags, mode_t mode,
- std::function<void(std::unique_ptr<FDHolder>)> cb) {
- // FDHolder is needed because if the request gets canceled
- // we would otherwise end up with a fd leaking.
- int ret = ::open(path.c_str(), flags, mode);
- cb(std::make_unique<FDHolder>(ret < 0 ? -errno : ret));
- }
-
- void fstat(int fd, std::function<void (int, std::unique_ptr<struct stat>)> cb) {
- std::unique_ptr<struct stat> buf = std::make_unique<struct stat>();
- int ret = ::fstat(fd, buf.get());
- cb(ret < 0 ? -errno : ret, std::move(buf));
- }
-
- void read(int fd, size_t size,
- std::function<void (ssize_t, std::shared_ptr<std::string>)> cb) {
- std::shared_ptr<std::string> buf = std::make_shared<std::string>();
- buf->resize(size);
-
- ssize_t ret = ::read(fd, &buf->front(), size);
- cb(ret < 0 ? -errno : ret, std::move(buf));
- }
-
- void close(int fd, std::function<void (void)> cb) {
- ::close(fd);
- cb();
- }
-};
-
-} // namespace
-
-namespace mbgl {
-
-using namespace std::placeholders;
-
-class AssetRequest : public RequestBase {
- MBGL_STORE_THREAD(tid)
-
-public:
- AssetRequest(const std::string& url, Callback, const std::string& assetRoot,
- util::Thread<FileIOWorker> *worker);
- ~AssetRequest();
-
- // RequestBase implementation.
- void cancel() final;
-
-private:
- void fileOpened(std::unique_ptr<FDHolder>);
- void fileStated(int result, std::unique_ptr<struct stat>);
- void fileRead(int result, std::shared_ptr<std::string>);
- void fileClosed();
-
- void notifyError(int result);
-
- void close();
- void cleanup();
-
- std::string assetRoot;
- std::unique_ptr<Response> response;
-
- int fd = -1;
-
- util::Thread<FileIOWorker> *worker;
- std::unique_ptr<WorkRequest> request;
-};
-
-class AssetFSContext : public AssetContextBase {
-public:
- AssetFSContext()
- : worker({"FileIOWorker", util::ThreadType::Worker, util::ThreadPriority::Regular}) {}
-
-private:
- RequestBase* createRequest(const std::string& url,
- RequestBase::Callback callback,
- const std::string& assetRoot) final {
- return new AssetRequest(url, callback, assetRoot, &worker);
- }
-
- util::Thread<FileIOWorker> worker;
-};
-
-AssetRequest::~AssetRequest() {
- MBGL_VERIFY_THREAD(tid);
-}
-
-AssetRequest::AssetRequest(const std::string& url_, Callback callback_,
- const std::string& assetRoot_, util::Thread<FileIOWorker> *worker_)
- : RequestBase(url_, callback_),
- assetRoot(assetRoot_),
- worker(worker_) {
- std::string path;
- if (url.size() <= 8 || url[8] == '/') {
- // This is an empty or absolute path.
- path = mbgl::util::percentDecode(url.substr(8));
- } else {
- // This is a relative path. Prefix with the application root.
- path = assetRoot + "/" + mbgl::util::percentDecode(url.substr(8));
- }
-
- request = worker->invokeWithCallback(&FileIOWorker::open,
- std::bind(&AssetRequest::fileOpened, this, _1), path, O_RDONLY, S_IRUSR);
-}
-
-void AssetRequest::cancel() {
- MBGL_VERIFY_THREAD(tid);
-
- request.reset();
- close();
-}
-
-void AssetRequest::fileOpened(std::unique_ptr<FDHolder> holder) {
- MBGL_VERIFY_THREAD(tid);
-
- std::swap(fd, holder->fd);
-
- if (fd < 0) {
- // Opening failed. There isn't much left we can do.
- notifyError(fd);
- cleanup();
-
- return;
- }
-
- request = worker->invokeWithCallback(&FileIOWorker::fstat,
- std::bind(&AssetRequest::fileStated, this, _1, _2), fd);
-}
-
-void AssetRequest::fileStated(int result, std::unique_ptr<struct stat> stat) {
- MBGL_VERIFY_THREAD(tid);
-
- if (result != 0) {
- // Stating failed. We already have an open file handle
- // though, which we'll have to close.
- notifyError(result);
- close();
- } else {
- response = std::make_unique<Response>();
- response->modified = Seconds(stat->st_mtime);
- response->etag = util::toString(stat->st_ino);
-
- request = worker->invokeWithCallback(&FileIOWorker::read,
- std::bind(&AssetRequest::fileRead, this, _1, _2), fd, stat->st_size);
- }
-}
-
-void AssetRequest::fileRead(int result, std::shared_ptr<std::string> data) {
- MBGL_VERIFY_THREAD(tid);
-
- if (result < 0) {
- // Reading failed. We already have an open file handle
- // though, which we'll have to close.
- notifyError(result);
- } else {
- response->data = data;
- notify(std::move(response));
- }
-
- close();
-}
-
-void AssetRequest::fileClosed() {
- MBGL_VERIFY_THREAD(tid);
-
- cleanup();
-}
-
-void AssetRequest::close() {
- MBGL_VERIFY_THREAD(tid);
-
- if (fd >= 0) {
- request = worker->invokeWithCallback(&FileIOWorker::close,
- std::bind(&AssetRequest::fileClosed, this), fd);
- fd = -1;
- } else {
- cleanup();
- }
-}
-
-void AssetRequest::cleanup() {
- MBGL_VERIFY_THREAD(tid);
-
- delete this;
-}
-
-void AssetRequest::notifyError(int result) {
- MBGL_VERIFY_THREAD(tid);
-
- result = std::abs(result);
- Response::Error::Reason reason = Response::Error::Reason::Other;
-
- if (result == ENOENT || result == EISDIR) {
- reason = Response::Error::Reason::NotFound;
- }
-
- response = std::make_unique<Response>();
- response->error = std::make_unique<Response::Error>(reason, ::strerror(result));
-
- notify(std::move(response));
-}
-
-std::unique_ptr<AssetContextBase> AssetContextBase::createContext() {
- return std::make_unique<AssetFSContext>();
-}
-
-} // namespace mbgl
diff --git a/platform/default/asset_request_zip.cpp b/platform/default/asset_request_zip.cpp
deleted file mode 100644
index 76bf8bba14..0000000000
--- a/platform/default/asset_request_zip.cpp
+++ /dev/null
@@ -1,319 +0,0 @@
-#include <mbgl/storage/asset_context_base.hpp>
-#include <mbgl/storage/response.hpp>
-#include <mbgl/util/chrono.hpp>
-#include <mbgl/util/util.hpp>
-#include <mbgl/util/thread.hpp>
-
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wshadow"
-#include <zip.h>
-#pragma GCC diagnostic pop
-
-#include <cassert>
-#include <forward_list>
-#include <map>
-
-#include <fcntl.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-
-namespace {
-
-struct ZipHolder {
- ZipHolder(struct zip* archive_) : archive(archive_) {}
-
- ~ZipHolder() {
- if (archive) ::zip_discard(archive);
- }
-
- struct zip* archive;
-};
-
-struct ZipFileHolder {
- ZipFileHolder(struct zip_file* file_) : file(file_) {}
-
- ~ZipFileHolder() {
- if (file) ::zip_fclose(file);
- }
-
- struct zip_file* file;
-};
-
-class ZipIOWorker {
-public:
- ZipIOWorker() = default;
-
- void zip_fdopen(const std::string& path,
- std::function<void(std::unique_ptr<ZipHolder>)> cb) {
- int fd = ::open(path.c_str(), O_RDONLY, S_IRUSR);
- if (fd < 0) {
- cb(std::make_unique<ZipHolder>(nullptr));
- } else {
- int errorp;
- struct zip* archive = ::zip_fdopen(fd, 0, &errorp);
- cb(std::make_unique<ZipHolder>(archive));
- }
- }
-
- void zip_stat(struct zip* archive, const std::string& path,
- std::function<void (int, std::unique_ptr<struct zip_stat>)> cb) {
- std::unique_ptr<struct zip_stat> buf = std::make_unique<struct zip_stat>();
- ::zip_stat_init(buf.get());
-
- int ret = ::zip_stat(archive, path.c_str(), 0, buf.get());
- cb(ret, std::move(buf));
- }
-
- void zip_fopen(struct zip* archive, const std::string& path,
- std::function<void (std::unique_ptr<ZipFileHolder>)> cb) {
- struct zip_file* file = ::zip_fopen(archive, path.c_str(), 0);
- cb(std::make_unique<ZipFileHolder>(file));
- }
-
- void zip_fread(struct zip_file* file, size_t size,
- std::function<void (int, std::shared_ptr<std::string>)> cb) {
- std::shared_ptr<std::string> buf = std::make_shared<std::string>();
- buf->resize(size);
-
- int ret = ::zip_fread(file, &buf->front(), size);
- cb(ret, std::move(buf));
- }
-
- void zip_fclose(struct zip_file* file, std::function<void (int)> cb) {
- cb(::zip_fclose(file));
- }
-};
-
-}
-
-namespace mbgl {
-
-using namespace std::placeholders;
-
-class AssetZipContext;
-
-class AssetRequest : public RequestBase {
- MBGL_STORE_THREAD(tid)
-
-public:
- AssetRequest(const std::string& url, Callback, const std::string& assetRoot,
- AssetZipContext* context, util::Thread<ZipIOWorker>* worker);
- ~AssetRequest();
-
- // RequestBase implementation.
- void cancel() final;
-
-private:
- void openArchive();
- void archiveOpened(std::unique_ptr<ZipHolder>);
- void fileStated(int result, std::unique_ptr<struct zip_stat>);
- void fileOpened(std::unique_ptr<ZipFileHolder>);
- void fileRead(int result, std::shared_ptr<std::string>);
- void fileClosed();
-
- void close();
- void cleanup();
-
- void notifyError(Response::Error::Reason, const char *message);
-
- const std::string root;
- const std::string path;
- std::unique_ptr<Response> response;
-
- struct zip* archive = nullptr;
- struct zip_file* file = nullptr;
- size_t size = 0;
-
- AssetZipContext *context;
-
- util::Thread<ZipIOWorker> *worker;
- std::unique_ptr<WorkRequest> request;
-};
-
-class AssetZipContext : public AssetContextBase {
-public:
- AssetZipContext();
- ~AssetZipContext();
-
- RequestBase* createRequest(const std::string& url,
- RequestBase::Callback callback,
- const std::string& assetRoot) final {
- return new AssetRequest(url, callback, assetRoot, this, &worker);
- }
-
- struct zip *getHandle(const std::string &path);
- void returnHandle(const std::string &path, struct zip *zip);
-
- // A list of resuable zip handles to avoid creating
- // and destroying them all the time.
- std::map<std::string, std::forward_list<struct zip*>> handles;
-
- util::Thread<ZipIOWorker> worker;
- std::unique_ptr<WorkRequest> request;
-};
-
-AssetZipContext::AssetZipContext()
- : worker({"ZipIOWorker", util::ThreadType::Worker, util::ThreadPriority::Regular}) {}
-
-AssetZipContext::~AssetZipContext() {
- // Close all zip handles
- for (auto &list : handles) {
- for (auto archive : list.second) {
- zip_discard(archive);
- }
- }
-
- handles.clear();
-}
-
-struct zip* AssetZipContext::getHandle(const std::string &path) {
- auto &list = handles[path];
- if (!list.empty()) {
- auto archive = list.front();
- list.pop_front();
- return archive;
- } else {
- return nullptr;
- }
-}
-
-void AssetZipContext::returnHandle(const std::string &path, struct zip* archive) {
- handles[path].push_front(archive);
-}
-
-AssetRequest::AssetRequest(const std::string& url_, Callback callback_,
- const std::string& assetRoot, AssetZipContext* context_, util::Thread<ZipIOWorker>* worker_)
- : RequestBase(url_, callback_),
- root(assetRoot),
- path(std::string("assets/") + url.substr(8)),
- context(context_),
- worker(worker_) {
- archive = context->getHandle(root);
- if (archive) {
- request = worker->invokeWithCallback(&ZipIOWorker::zip_stat,
- std::bind(&AssetRequest::fileStated, this, _1, _2), archive, path);
- } else {
- request = worker->invokeWithCallback(&ZipIOWorker::zip_fdopen,
- std::bind(&AssetRequest::archiveOpened, this, _1), root);
- }
-}
-
-AssetRequest::~AssetRequest() {
- MBGL_VERIFY_THREAD(tid);
-}
-
-void AssetRequest::cancel() {
- MBGL_VERIFY_THREAD(tid);
-
- request.reset();
- close();
-}
-
-void AssetRequest::archiveOpened(std::unique_ptr<ZipHolder> holder) {
- MBGL_VERIFY_THREAD(tid);
-
- std::swap(archive, holder->archive);
-
- if (!archive) {
- notifyError(Response::Error::Reason::Other, "Could not open zip archive");
- cleanup();
- } else {
- request = worker->invokeWithCallback(&ZipIOWorker::zip_stat,
- std::bind(&AssetRequest::fileStated, this, _1, _2), archive, path);
- }
-}
-
-void AssetRequest::fileStated(int result, std::unique_ptr<struct zip_stat> stat) {
- MBGL_VERIFY_THREAD(tid);
-
- if (result < 0 || !(stat->valid & ZIP_STAT_SIZE)) {
- notifyError(Response::Error::Reason::NotFound, "Could not stat file in zip archive");
- cleanup();
- } else {
- response = std::make_unique<Response>();
-
- if (stat->valid & ZIP_STAT_MTIME) {
- response->modified = Seconds(stat->mtime);
- }
-
- if (stat->valid & ZIP_STAT_INDEX) {
- response->etag = std::to_string(stat->index);
- }
-
- size = stat->size;
-
- request = worker->invokeWithCallback(&ZipIOWorker::zip_fopen,
- std::bind(&AssetRequest::fileOpened, this, _1), archive, path);
- }
-}
-
-void AssetRequest::fileOpened(std::unique_ptr<ZipFileHolder> holder) {
- MBGL_VERIFY_THREAD(tid);
-
- std::swap(file, holder->file);
-
- if (!file) {
- notifyError(Response::Error::Reason::NotFound, "Could not open file in zip archive"),
- cleanup();
- } else {
- request = worker->invokeWithCallback(&ZipIOWorker::zip_fread,
- std::bind(&AssetRequest::fileRead, this, _1, _2), file, size);
- }
-}
-
-void AssetRequest::fileRead(int result, std::shared_ptr<std::string> data) {
- MBGL_VERIFY_THREAD(tid);
-
- if (result < 0) {
- notifyError(Response::Error::Reason::Other, "Could not read file in zip archive");
- } else {
- response->data = data;
- notify(std::move(response));
- }
-
- close();
-}
-
-void AssetRequest::fileClosed() {
- MBGL_VERIFY_THREAD(tid);
-
- cleanup();
-}
-
-
-void AssetRequest::close() {
- MBGL_VERIFY_THREAD(tid);
-
- if (file) {
- request = worker->invokeWithCallback(&ZipIOWorker::zip_fclose,
- std::bind(&AssetRequest::fileClosed, this), file);
- file = nullptr;
- } else {
- cleanup();
- }
-}
-
-void AssetRequest::cleanup() {
- MBGL_VERIFY_THREAD(tid);
-
- if (archive) {
- context->returnHandle(root, archive);
- }
-
- delete this;
-}
-
-void AssetRequest::notifyError(Response::Error::Reason reason, const char *message) {
- MBGL_VERIFY_THREAD(tid);
-
- response = std::make_unique<Response>();
- response->error = std::make_unique<Response::Error>(reason, message);
-
- notify(std::move(response));
-}
-
-std::unique_ptr<AssetContextBase> AssetContextBase::createContext() {
- return std::make_unique<AssetZipContext>();
-}
-
-}
diff --git a/platform/default/default_file_source.cpp b/platform/default/default_file_source.cpp
index d2bbce6002..8f2f024a11 100644
--- a/platform/default/default_file_source.cpp
+++ b/platform/default/default_file_source.cpp
@@ -1,16 +1,32 @@
#include <mbgl/storage/default_file_source.hpp>
+#include <mbgl/storage/asset_file_source.hpp>
#include <mbgl/storage/online_file_source.hpp>
#include <mbgl/storage/sqlite_cache.hpp>
+#include <mbgl/platform/platform.hpp>
+#include <mbgl/util/url.hpp>
+
+namespace {
+
+const std::string assetProtocol = "asset://";
+
+bool isAssetURL(const std::string& url) {
+ return std::equal(assetProtocol.begin(), assetProtocol.end(), url.begin());
+}
+
+} // namespace
+
namespace mbgl {
class DefaultFileSource::Impl {
public:
- Impl(const std::string& cachePath, const std::string& root)
- : cache(SharedSQLiteCache::get(cachePath)),
- onlineFileSource(cache.get(), root) {
+ Impl(const std::string& cachePath, const std::string& assetRoot)
+ : assetFileSource(assetRoot),
+ cache(SharedSQLiteCache::get(cachePath)),
+ onlineFileSource(cache.get()) {
}
+ AssetFileSource assetFileSource;
std::shared_ptr<SQLiteCache> cache;
OnlineFileSource onlineFileSource;
};
@@ -38,7 +54,11 @@ void DefaultFileSource::setMaximumCacheEntrySize(uint64_t size) {
}
std::unique_ptr<FileRequest> DefaultFileSource::request(const Resource& resource, Callback callback) {
- return impl->onlineFileSource.request(resource, callback);
+ if (isAssetURL(resource.url)) {
+ return impl->assetFileSource.request(resource, callback);
+ } else {
+ return impl->onlineFileSource.request(resource, callback);
+ }
}
} // namespace mbgl
diff --git a/platform/default/online_file_source.cpp b/platform/default/online_file_source.cpp
index 480d2a8276..84be64a22f 100644
--- a/platform/default/online_file_source.cpp
+++ b/platform/default/online_file_source.cpp
@@ -1,10 +1,8 @@
#include <mbgl/storage/online_file_source.hpp>
-#include <mbgl/storage/asset_context_base.hpp>
#include <mbgl/storage/http_context_base.hpp>
#include <mbgl/storage/network_status.hpp>
#include <mbgl/storage/response.hpp>
-#include <mbgl/platform/platform.hpp>
#include <mbgl/platform/log.hpp>
#include <mbgl/util/thread.hpp>
@@ -14,7 +12,6 @@
#include <mbgl/util/async_task.hpp>
#include <mbgl/util/noncopyable.hpp>
#include <mbgl/util/timer.hpp>
-#include <mbgl/util/url.hpp>
#include <algorithm>
#include <cassert>
@@ -83,7 +80,7 @@ class OnlineFileSource::Impl {
public:
using Callback = std::function<void (Response)>;
- Impl(FileCache*, const std::string& = "");
+ Impl(FileCache*);
~Impl();
void networkIsReachableAgain();
@@ -96,17 +93,14 @@ private:
std::unordered_map<Resource, std::unique_ptr<OnlineFileRequestImpl>, Resource::Hash> pending;
FileCache* const cache;
- const std::string assetRoot;
- const std::unique_ptr<AssetContextBase> assetContext;
const std::unique_ptr<HTTPContextBase> httpContext;
util::AsyncTask reachability;
};
-OnlineFileSource::OnlineFileSource(FileCache* cache, const std::string& root)
+OnlineFileSource::OnlineFileSource(FileCache* cache)
: thread(std::make_unique<util::Thread<Impl>>(
util::ThreadContext{ "OnlineFileSource", util::ThreadType::Unknown, util::ThreadPriority::Low },
- cache,
- root)) {
+ cache)) {
}
OnlineFileSource::~OnlineFileSource() = default;
@@ -152,10 +146,8 @@ void OnlineFileSource::cancel(const Resource& res, FileRequest* req) {
// ----- Impl -----
-OnlineFileSource::Impl::Impl(FileCache* cache_, const std::string& root)
+OnlineFileSource::Impl::Impl(FileCache* cache_)
: cache(cache_),
- assetRoot(root.empty() ? platform::assetRoot() : root),
- assetContext(AssetContextBase::createContext()),
httpContext(HTTPContextBase::createContext()),
reachability(std::bind(&Impl::networkIsReachableAgain, this)) {
// Subscribe to network status changes, but make sure that this async handle doesn't keep the
@@ -242,7 +234,7 @@ void OnlineFileRequestImpl::addObserver(FileRequest* req, Callback callback, Onl
} else if (!cacheRequest && !realRequest) {
// There is no request in progress, and we don't have a response yet. This means we'll have
// to start the request ourselves.
- if (impl.cache && !util::isAssetURL(resource.url)) {
+ if (impl.cache) {
scheduleCacheRequest(impl);
} else {
scheduleRealRequest(impl);
@@ -330,7 +322,7 @@ void OnlineFileRequestImpl::scheduleRealRequest(OnlineFileSource::Impl& impl, bo
// In particular, we don't want to write a Canceled request, or one that failed due to
// connection errors to the cache. Server errors are hopefully also temporary, so we're not
// caching them either.
- if (impl.cache && !util::isAssetURL(resource.url) &&
+ if (impl.cache &&
(!response_->error || (response_->error->reason == Response::Error::Reason::NotFound))) {
// Store response in database. Make sure we only refresh the expires column if the data
// didn't change.
@@ -357,11 +349,7 @@ void OnlineFileRequestImpl::scheduleRealRequest(OnlineFileSource::Impl& impl, bo
scheduleRealRequest(impl);
};
- if (util::isAssetURL(resource.url)) {
- realRequest = impl.assetContext->createRequest(resource.url, callback, impl.assetRoot);
- } else {
- realRequest = impl.httpContext->createRequest(resource.url, callback, response);
- }
+ realRequest = impl.httpContext->createRequest(resource.url, callback, response);
});
}
diff --git a/src/mbgl/storage/asset_context_base.hpp b/src/mbgl/storage/asset_context_base.hpp
deleted file mode 100644
index 92138615b5..0000000000
--- a/src/mbgl/storage/asset_context_base.hpp
+++ /dev/null
@@ -1,20 +0,0 @@
-#ifndef MBGL_STORAGE_ASSET_CONTEXT_BASE
-#define MBGL_STORAGE_ASSET_CONTEXT_BASE
-
-#include <mbgl/storage/request_base.hpp>
-
-namespace mbgl {
-
-class AssetContextBase {
-public:
- static std::unique_ptr<AssetContextBase> createContext();
-
- virtual ~AssetContextBase() = default;
- virtual RequestBase* createRequest(const std::string& url,
- RequestBase::Callback,
- const std::string& assetRoot) = 0;
-};
-
-} // namespace mbgl
-
-#endif // MBGL_STORAGE_ASSET_CONTEXT_BASE
diff --git a/src/mbgl/storage/asset_file_source.hpp b/src/mbgl/storage/asset_file_source.hpp
new file mode 100644
index 0000000000..11a430e124
--- /dev/null
+++ b/src/mbgl/storage/asset_file_source.hpp
@@ -0,0 +1,26 @@
+#ifndef MBGL_STORAGE_ASSET_FILE_SOURCE
+#define MBGL_STORAGE_ASSET_FILE_SOURCE
+
+#include <mbgl/storage/file_source.hpp>
+
+namespace mbgl {
+
+namespace util {
+template <typename T> class Thread;
+} // namespace util
+
+class AssetFileSource : public FileSource {
+public:
+ AssetFileSource(const std::string& assetRoot);
+ ~AssetFileSource() override;
+
+ std::unique_ptr<FileRequest> request(const Resource&, Callback) override;
+
+private:
+ class Impl;
+ std::unique_ptr<util::Thread<Impl>> thread;
+};
+
+} // namespace mbgl
+
+#endif // MBGL_STORAGE_ASSET_FILE_SOURCE
diff --git a/src/mbgl/util/url.cpp b/src/mbgl/util/url.cpp
index 1bd9f410fe..85d8bc5bd0 100644
--- a/src/mbgl/util/url.cpp
+++ b/src/mbgl/util/url.cpp
@@ -71,13 +71,5 @@ std::string templateTileURL(const std::string& url, const TileID& id, float pixe
});
}
-namespace {
-const std::string assetProtocol = "asset://";
-}
-
-bool isAssetURL(const std::string& url) {
- return std::equal(assetProtocol.begin(), assetProtocol.end(), url.begin());
-}
-
} // namespace util
} // namespace mbgl
diff --git a/src/mbgl/util/url.hpp b/src/mbgl/util/url.hpp
index da4cfb2672..550fff8aa1 100644
--- a/src/mbgl/util/url.hpp
+++ b/src/mbgl/util/url.hpp
@@ -14,8 +14,6 @@ std::string percentDecode(const std::string&);
std::string templateTileURL(const std::string& url, const TileID& id, float pixelRatio = 1);
-bool isAssetURL(const std::string&);
-
} // namespace util
} // namespace mbgl
diff --git a/test/api/annotations.cpp b/test/api/annotations.cpp
index 1b088b52c5..d80cff9e8e 100644
--- a/test/api/annotations.cpp
+++ b/test/api/annotations.cpp
@@ -31,7 +31,7 @@ void checkRendering(Map& map, const char * name) {
TEST(Annotations, PointAnnotation) {
auto display = std::make_shared<mbgl::HeadlessDisplay>();
HeadlessView view(display, 1);
- OnlineFileSource fileSource(nullptr, test::getFileSourceRoot());
+ OnlineFileSource fileSource(nullptr);
Map map(view, fileSource, MapMode::Still);
map.setStyleJSON(util::read_file("test/fixtures/api/empty.json"), "");
@@ -44,7 +44,7 @@ TEST(Annotations, PointAnnotation) {
TEST(Annotations, LineAnnotation) {
auto display = std::make_shared<mbgl::HeadlessDisplay>();
HeadlessView view(display, 1);
- OnlineFileSource fileSource(nullptr, test::getFileSourceRoot());
+ OnlineFileSource fileSource(nullptr);
Map map(view, fileSource, MapMode::Still);
map.setStyleJSON(util::read_file("test/fixtures/api/empty.json"), "");
@@ -63,7 +63,7 @@ TEST(Annotations, LineAnnotation) {
TEST(Annotations, FillAnnotation) {
auto display = std::make_shared<mbgl::HeadlessDisplay>();
HeadlessView view(display, 1);
- OnlineFileSource fileSource(nullptr, test::getFileSourceRoot());
+ OnlineFileSource fileSource(nullptr);
Map map(view, fileSource, MapMode::Still);
map.setStyleJSON(util::read_file("test/fixtures/api/empty.json"), "");
@@ -81,7 +81,7 @@ TEST(Annotations, FillAnnotation) {
TEST(Annotations, StyleSourcedShapeAnnotation) {
auto display = std::make_shared<mbgl::HeadlessDisplay>();
HeadlessView view(display, 1);
- OnlineFileSource fileSource(nullptr, test::getFileSourceRoot());
+ OnlineFileSource fileSource(nullptr);
Map map(view, fileSource, MapMode::Still);
map.setStyleJSON(util::read_file("test/fixtures/api/annotation.json"), "");
@@ -96,7 +96,7 @@ TEST(Annotations, StyleSourcedShapeAnnotation) {
TEST(Annotations, AddMultiple) {
auto display = std::make_shared<mbgl::HeadlessDisplay>();
HeadlessView view(display, 1);
- OnlineFileSource fileSource(nullptr, test::getFileSourceRoot());
+ OnlineFileSource fileSource(nullptr);
Map map(view, fileSource, MapMode::Still);
map.setStyleJSON(util::read_file("test/fixtures/api/empty.json"), "");
@@ -113,7 +113,7 @@ TEST(Annotations, AddMultiple) {
TEST(Annotations, NonImmediateAdd) {
auto display = std::make_shared<mbgl::HeadlessDisplay>();
HeadlessView view(display, 1);
- OnlineFileSource fileSource(nullptr, test::getFileSourceRoot());
+ OnlineFileSource fileSource(nullptr);
Map map(view, fileSource, MapMode::Still);
map.setStyleJSON(util::read_file("test/fixtures/api/empty.json"), "");
@@ -133,7 +133,7 @@ TEST(Annotations, NonImmediateAdd) {
TEST(Annotations, UpdatePoint) {
auto display = std::make_shared<mbgl::HeadlessDisplay>();
HeadlessView view(display, 1);
- OnlineFileSource fileSource(nullptr, test::getFileSourceRoot());
+ OnlineFileSource fileSource(nullptr);
Map map(view, fileSource, MapMode::Still);
map.setStyleJSON(util::read_file("test/fixtures/api/empty.json"), "");
@@ -152,7 +152,7 @@ TEST(Annotations, UpdatePoint) {
TEST(Annotations, RemovePoint) {
auto display = std::make_shared<mbgl::HeadlessDisplay>();
HeadlessView view(display, 1);
- OnlineFileSource fileSource(nullptr, test::getFileSourceRoot());
+ OnlineFileSource fileSource(nullptr);
Map map(view, fileSource, MapMode::Still);
map.setStyleJSON(util::read_file("test/fixtures/api/empty.json"), "");
@@ -169,7 +169,7 @@ TEST(Annotations, RemovePoint) {
TEST(Annotations, RemoveShape) {
auto display = std::make_shared<mbgl::HeadlessDisplay>();
HeadlessView view(display, 1);
- OnlineFileSource fileSource(nullptr, test::getFileSourceRoot());
+ OnlineFileSource fileSource(nullptr);
AnnotationSegments segments = {{ {{ { 0, 0 }, { 45, 45 } }} }};
@@ -191,7 +191,7 @@ TEST(Annotations, RemoveShape) {
TEST(Annotations, ImmediateRemoveShape) {
auto display = std::make_shared<mbgl::HeadlessDisplay>();
HeadlessView view(display, 1);
- OnlineFileSource fileSource(nullptr, test::getFileSourceRoot());
+ OnlineFileSource fileSource(nullptr);
Map map(view, fileSource, MapMode::Still);
map.removeAnnotation(map.addShapeAnnotation(ShapeAnnotation({}, {})));
@@ -203,7 +203,7 @@ TEST(Annotations, ImmediateRemoveShape) {
TEST(Annotations, SwitchStyle) {
auto display = std::make_shared<mbgl::HeadlessDisplay>();
HeadlessView view(display, 1);
- OnlineFileSource fileSource(nullptr, test::getFileSourceRoot());
+ OnlineFileSource fileSource(nullptr);
Map map(view, fileSource, MapMode::Still);
map.setStyleJSON(util::read_file("test/fixtures/api/empty.json"), "");
diff --git a/test/api/custom_layer.cpp b/test/api/custom_layer.cpp
index efe63d74c9..923bf4566e 100644
--- a/test/api/custom_layer.cpp
+++ b/test/api/custom_layer.cpp
@@ -66,7 +66,7 @@ public:
TEST(CustomLayer, Basic) {
auto display = std::make_shared<mbgl::HeadlessDisplay>();
HeadlessView view(display, 1);
- OnlineFileSource fileSource(nullptr, test::getFileSourceRoot());
+ OnlineFileSource fileSource(nullptr);
Map map(view, fileSource, MapMode::Still);
map.setStyleJSON(util::read_file("test/fixtures/api/empty.json"), "");
diff --git a/test/api/repeated_render.cpp b/test/api/repeated_render.cpp
index 0b2a87cc33..3eab03de5b 100644
--- a/test/api/repeated_render.cpp
+++ b/test/api/repeated_render.cpp
@@ -4,7 +4,7 @@
#include <mbgl/map/map.hpp>
#include <mbgl/platform/default/headless_view.hpp>
#include <mbgl/platform/default/headless_display.hpp>
-#include <mbgl/storage/online_file_source.hpp>
+#include <mbgl/storage/default_file_source.hpp>
#include <mbgl/util/image.hpp>
#include <mbgl/util/io.hpp>
@@ -18,9 +18,9 @@ TEST(API, RepeatedRender) {
auto display = std::make_shared<mbgl::HeadlessDisplay>();
HeadlessView view(display, 1, 256, 512);
#ifdef MBGL_ASSET_ZIP
- OnlineFileSource fileSource(nullptr, "test/fixtures/api/assets.zip");
+ DefaultFileSource fileSource(":memory", "test/fixtures/api/assets.zip");
#else
- OnlineFileSource fileSource(nullptr);
+ DefaultFileSource fileSource;
#endif
Log::setObserver(std::make_unique<FixtureLogObserver>());
diff --git a/test/fixtures/api/annotation.json b/test/fixtures/api/annotation.json
index e0792a40bf..ab83d43476 100644
--- a/test/fixtures/api/annotation.json
+++ b/test/fixtures/api/annotation.json
@@ -3,7 +3,7 @@
"sources": {
"fake": {
"type": "vector",
- "url": "asset://TEST_DATA/fixtures/tiles/streets.json"
+ "url": "fake"
}
},
"layers": [{
@@ -17,6 +17,5 @@
"paint": {
"fill-color": "rgba(255,0,0,1)"
}
- }],
- "sprite": "asset://TEST_DATA/fixtures/resources/sprite"
+ }]
}
diff --git a/test/fixtures/util.cpp b/test/fixtures/util.cpp
index 9e929a90b4..926e267631 100644
--- a/test/fixtures/util.cpp
+++ b/test/fixtures/util.cpp
@@ -20,14 +20,6 @@
namespace mbgl {
namespace test {
-std::string getFileSourceRoot() {
-#ifdef MBGL_ASSET_ZIP
- return "test/fixtures/annotations/assets.zip";
-#else
- return "";
-#endif
-}
-
Server::Server(const char* executable) {
int input[2];
int output[2];
diff --git a/test/fixtures/util.hpp b/test/fixtures/util.hpp
index e2cadc50dd..d7c9c63a89 100644
--- a/test/fixtures/util.hpp
+++ b/test/fixtures/util.hpp
@@ -22,8 +22,6 @@ class Map;
namespace test {
-std::string getFileSourceRoot();
-
class Server {
public:
Server(const char* executable);
diff --git a/test/storage/file_reading.cpp b/test/storage/asset_file_source.cpp
index a8ddd5a661..8c597027dc 100644
--- a/test/storage/file_reading.cpp
+++ b/test/storage/asset_file_source.cpp
@@ -1,6 +1,6 @@
#include "storage.hpp"
-#include <mbgl/storage/online_file_source.hpp>
+#include <mbgl/storage/asset_file_source.hpp>
#include <mbgl/storage/sqlite_cache.hpp>
#include <mbgl/platform/platform.hpp>
#include <mbgl/util/chrono.hpp>
@@ -19,7 +19,7 @@ std::string getFileSourceRoot() {
class TestWorker {
public:
- TestWorker(mbgl::OnlineFileSource* fs_) : fs(fs_) {}
+ TestWorker(mbgl::AssetFileSource* fs_) : fs(fs_) {}
void run(std::function<void()> endCallback) {
const std::string asset("asset://TEST_DATA/fixtures/storage/nonempty");
@@ -47,7 +47,7 @@ public:
private:
unsigned numRequests = 1000;
- mbgl::OnlineFileSource* fs;
+ mbgl::AssetFileSource* fs;
std::unique_ptr<mbgl::FileRequest> request;
std::function<void(mbgl::Response)> requestCallback;
@@ -62,7 +62,7 @@ TEST_F(Storage, AssetStress) {
util::RunLoop loop;
- mbgl::OnlineFileSource fs(nullptr, getFileSourceRoot());
+ AssetFileSource fs(getFileSourceRoot());
unsigned numThreads = 50;
@@ -98,7 +98,7 @@ TEST_F(Storage, AssetEmptyFile) {
util::RunLoop loop;
- OnlineFileSource fs(nullptr, getFileSourceRoot());
+ AssetFileSource fs(getFileSourceRoot());
std::unique_ptr<FileRequest> req = fs.request({ Resource::Unknown, "asset://TEST_DATA/fixtures/storage/empty" }, [&](Response res) {
req.reset();
@@ -106,9 +106,6 @@ TEST_F(Storage, AssetEmptyFile) {
EXPECT_EQ(false, res.stale);
ASSERT_TRUE(res.data.get());
EXPECT_EQ("", *res.data);
- EXPECT_EQ(Seconds::zero(), res.expires);
- EXPECT_LT(1420000000, res.modified.count());
- EXPECT_NE("", res.etag);
loop.stop();
EmptyFile.finish();
});
@@ -123,7 +120,7 @@ TEST_F(Storage, AssetNonEmptyFile) {
util::RunLoop loop;
- OnlineFileSource fs(nullptr, getFileSourceRoot());
+ AssetFileSource fs(getFileSourceRoot());
std::unique_ptr<FileRequest> req = fs.request({ Resource::Unknown, "asset://TEST_DATA/fixtures/storage/nonempty" }, [&](Response res) {
req.reset();
@@ -131,11 +128,6 @@ TEST_F(Storage, AssetNonEmptyFile) {
EXPECT_EQ(false, res.stale);
ASSERT_TRUE(res.data.get());
EXPECT_EQ("content is here\n", *res.data);
- EXPECT_EQ(Seconds::zero(), res.expires);
- EXPECT_LT(1420000000, res.modified.count());
- EXPECT_NE("", res.etag);
- ASSERT_TRUE(res.data.get());
- EXPECT_EQ("content is here\n", *res.data);
loop.stop();
NonEmptyFile.finish();
});
@@ -150,7 +142,7 @@ TEST_F(Storage, AssetNonExistentFile) {
util::RunLoop loop;
- OnlineFileSource fs(nullptr, getFileSourceRoot());
+ AssetFileSource fs(getFileSourceRoot());
std::unique_ptr<FileRequest> req = fs.request({ Resource::Unknown, "asset://TEST_DATA/fixtures/storage/does_not_exist" }, [&](Response res) {
req.reset();
@@ -158,14 +150,7 @@ TEST_F(Storage, AssetNonExistentFile) {
EXPECT_EQ(Response::Error::Reason::NotFound, res.error->reason);
EXPECT_EQ(false, res.stale);
ASSERT_FALSE(res.data.get());
- EXPECT_EQ(Seconds::zero(), res.expires);
- EXPECT_EQ(Seconds::zero(), res.modified);
- EXPECT_EQ("", res.etag);
-#ifdef MBGL_ASSET_ZIP
- EXPECT_EQ("Could not stat file in zip archive", res.error->message);
-#elif MBGL_ASSET_FS
- EXPECT_EQ("No such file or directory", res.error->message);
-#endif
+ // Do not assert on platform-specific error message.
loop.stop();
NonExistentFile.finish();
});
@@ -173,42 +158,24 @@ TEST_F(Storage, AssetNonExistentFile) {
loop.run();
}
-TEST_F(Storage, AssetNotCached) {
- SCOPED_TEST(NotCached)
+TEST_F(Storage, AssetReadDirectory) {
+ SCOPED_TEST(ReadDirectory)
using namespace mbgl;
- const Resource resource { Resource::Unknown, "asset://TEST_DATA/fixtures/storage/nonempty" };
-
util::RunLoop loop;
- SQLiteCache cache(":memory:");
+ AssetFileSource fs(getFileSourceRoot());
- // Add a fake response to the cache to verify that we don't retrieve it.
- {
- auto response = std::make_shared<Response>();
- response->data = std::make_shared<const std::string>("cached data");
- cache.put(resource, response, FileCache::Hint::Full);
- }
-
- OnlineFileSource fs(&cache, getFileSourceRoot());
-
- std::unique_ptr<WorkRequest> workReq;
- std::unique_ptr<FileRequest> req = fs.request(resource, [&](Response res) {
+ std::unique_ptr<FileRequest> req = fs.request({ Resource::Unknown, "asset://TEST_DATA/fixtures/storage" }, [&](Response res) {
req.reset();
-
- EXPECT_EQ(nullptr, res.error);
- ASSERT_TRUE(res.data.get());
- EXPECT_EQ("content is here\n", *res.data);
-
- workReq = cache.get(resource, [&](std::shared_ptr<Response> response) {
- // Check that we didn't put the file into the cache
- ASSERT_TRUE(response->data.get());
- EXPECT_EQ(*response->data, "cached data");
-
- loop.stop();
- NotCached.finish();
- });
+ ASSERT_NE(nullptr, res.error);
+ EXPECT_EQ(Response::Error::Reason::NotFound, res.error->reason);
+ EXPECT_EQ(false, res.stale);
+ ASSERT_FALSE(res.data.get());
+ // Do not assert on platform-specific error message.
+ loop.stop();
+ ReadDirectory.finish();
});
loop.run();
diff --git a/test/storage/directory_reading.cpp b/test/storage/directory_reading.cpp
deleted file mode 100644
index 2e6b90f0d3..0000000000
--- a/test/storage/directory_reading.cpp
+++ /dev/null
@@ -1,40 +0,0 @@
-#include "storage.hpp"
-
-#include <mbgl/storage/online_file_source.hpp>
-#include <mbgl/util/chrono.hpp>
-#include <mbgl/util/run_loop.hpp>
-
-TEST_F(Storage, AssetReadDirectory) {
- SCOPED_TEST(ReadDirectory)
-
- using namespace mbgl;
-
- util::RunLoop loop;
-
-#ifdef MBGL_ASSET_ZIP
- OnlineFileSource fs(nullptr, "test/fixtures/storage/assets.zip");
-#else
- OnlineFileSource fs(nullptr);
-#endif
-
- std::unique_ptr<FileRequest> req = fs.request({ Resource::Unknown, "asset://TEST_DATA/fixtures/storage" }, [&](Response res) {
- req.reset();
- ASSERT_NE(nullptr, res.error);
- EXPECT_EQ(Response::Error::Reason::NotFound, res.error->reason);
- EXPECT_EQ(false, res.stale);
- ASSERT_FALSE(res.data.get());
- EXPECT_EQ(Seconds::zero(), res.expires);
- EXPECT_EQ(Seconds::zero(), res.modified);
- EXPECT_EQ("", res.etag);
-#ifdef MBGL_ASSET_ZIP
- EXPECT_EQ("Could not stat file in zip archive", res.error->message);
-#elif MBGL_ASSET_FS
- EXPECT_EQ("Is a directory", res.error->message);
-#endif
-
- loop.stop();
- ReadDirectory.finish();
- });
-
- loop.run();
-}
diff --git a/test/test.gypi b/test/test.gypi
index 6a6ba507c6..e92a706894 100644
--- a/test/test.gypi
+++ b/test/test.gypi
@@ -73,8 +73,7 @@
'storage/cache_revalidate.cpp',
'storage/cache_size.cpp',
'storage/database.cpp',
- 'storage/directory_reading.cpp',
- 'storage/file_reading.cpp',
+ 'storage/asset_file_source.cpp',
'storage/headers.cpp',
'storage/http_cancel.cpp',
'storage/http_coalescing.cpp',