diff options
author | John Firebaugh <john.firebaugh@gmail.com> | 2016-01-11 12:52:41 -0800 |
---|---|---|
committer | John Firebaugh <john.firebaugh@gmail.com> | 2016-01-13 13:40:31 -0800 |
commit | 86c8446d3a4390ff6577d070ac8b5fa3ad3c5cd1 (patch) | |
tree | ef10190d3fca34ff72b2473816901088b0b85ac2 /platform/default/asset_file_source.cpp | |
parent | 2126e34e52dc5dd94c5a3907b240e62ee17d1e70 (diff) | |
download | qtlocation-mapboxgl-86c8446d3a4390ff6577d070ac8b5fa3ad3c5cd1.tar.gz |
[core] Simplify asset:// implementation
* Move asset:// URL handling to DefaultFileSource.
* AssetFileSource implements FileSource interface and follows familiar implementation patterns.
* Move default implementation to platform/default, zip implementation to platform/android.
* Don't bother with modified / expires / etag -- assets are not cached so it doesn't matter.
* Don't bother with interleaving individual IO calls on the implementation thread. That adds a lot of complexity for very little benefit.
Diffstat (limited to 'platform/default/asset_file_source.cpp')
-rw-r--r-- | platform/default/asset_file_source.cpp | 79 |
1 files changed, 79 insertions, 0 deletions
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 |