diff options
-rw-r--r-- | gyp/asset-fs.gypi | 2 | ||||
-rw-r--r-- | gyp/asset-zip.gypi | 2 | ||||
-rw-r--r-- | include/mbgl/storage/online_file_source.hpp | 2 | ||||
-rw-r--r-- | platform/android/src/asset_file_source.cpp | 111 | ||||
-rw-r--r-- | platform/default/asset_file_source.cpp | 79 | ||||
-rw-r--r-- | platform/default/asset_request_fs.cpp | 234 | ||||
-rw-r--r-- | platform/default/asset_request_zip.cpp | 319 | ||||
-rw-r--r-- | platform/default/default_file_source.cpp | 28 | ||||
-rw-r--r-- | platform/default/online_file_source.cpp | 26 | ||||
-rw-r--r-- | src/mbgl/storage/asset_context_base.hpp | 20 | ||||
-rw-r--r-- | src/mbgl/storage/asset_file_source.hpp | 26 | ||||
-rw-r--r-- | src/mbgl/util/url.cpp | 8 | ||||
-rw-r--r-- | src/mbgl/util/url.hpp | 2 | ||||
-rw-r--r-- | test/api/annotations.cpp | 22 | ||||
-rw-r--r-- | test/api/custom_layer.cpp | 2 | ||||
-rw-r--r-- | test/api/repeated_render.cpp | 6 | ||||
-rw-r--r-- | test/fixtures/api/annotation.json | 5 | ||||
-rw-r--r-- | test/fixtures/util.cpp | 8 | ||||
-rw-r--r-- | test/fixtures/util.hpp | 2 | ||||
-rw-r--r-- | test/storage/asset_file_source.cpp (renamed from test/storage/file_reading.cpp) | 71 | ||||
-rw-r--r-- | test/storage/directory_reading.cpp | 40 | ||||
-rw-r--r-- | test/test.gypi | 3 |
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', |