summaryrefslogtreecommitdiff
path: root/platform/default/asset_file_source.cpp
diff options
context:
space:
mode:
authorJohn Firebaugh <john.firebaugh@gmail.com>2016-01-11 12:52:41 -0800
committerJohn Firebaugh <john.firebaugh@gmail.com>2016-01-13 13:40:31 -0800
commit86c8446d3a4390ff6577d070ac8b5fa3ad3c5cd1 (patch)
treeef10190d3fca34ff72b2473816901088b0b85ac2 /platform/default/asset_file_source.cpp
parent2126e34e52dc5dd94c5a3907b240e62ee17d1e70 (diff)
downloadqtlocation-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.cpp79
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