1#include <mbgl/storage/asset_file_source.hpp>
2#include <mbgl/storage/file_source_request.hpp>
3#include <mbgl/storage/response.hpp>
4#include <mbgl/util/string.hpp>
5#include <mbgl/util/thread.hpp>
6#include <mbgl/util/url.hpp>
7#include <mbgl/util/util.hpp>
8#include <mbgl/util/io.hpp>
9
10#include <sys/types.h>
11#include <sys/stat.h>
12
13namespace {
14
15const std::string assetProtocol = "asset://";
16
17} // namespace
18
19namespace mbgl {
20
21class AssetFileSource::Impl {
22public:
23 Impl(ActorRef<Impl>, std::string root_)
24 : root(std::move(root_)) {
25 }
26
27 void request(const std::string& url, ActorRef<FileSourceRequest> req) {
28 Response response;
29
30 if (!acceptsURL(url)) {
31 response.error = std::make_unique<Response::Error>(args: Response::Error::Reason::Other,
32 args: "Invalid asset URL");
33 req.invoke(fn: &FileSourceRequest::setResponse, args&: response);
34 return;
35 }
36
37 // Cut off the protocol and prefix with path.
38 const auto path = root + "/" + mbgl::util::percentDecode(url.substr(pos: assetProtocol.size()));
39 struct stat buf;
40 int result = stat(file: path.c_str(), buf: &buf);
41
42 if (result == 0 && (S_IFDIR & buf.st_mode)) {
43 response.error = std::make_unique<Response::Error>(args: Response::Error::Reason::NotFound);
44 } else if (result == -1 && errno == ENOENT) {
45 response.error = std::make_unique<Response::Error>(args: Response::Error::Reason::NotFound);
46 } else {
47 try {
48 response.data = std::make_shared<std::string>(args: util::read_file(filename: path));
49 } catch (...) {
50 response.error = std::make_unique<Response::Error>(
51 args: Response::Error::Reason::Other,
52 args: util::toString(error: std::current_exception()));
53 }
54 }
55
56 req.invoke(fn: &FileSourceRequest::setResponse, args&: response);
57 }
58
59private:
60 std::string root;
61};
62
63AssetFileSource::AssetFileSource(const std::string& root)
64 : impl(std::make_unique<util::Thread<Impl>>(args: "AssetFileSource", args: root)) {
65}
66
67AssetFileSource::~AssetFileSource() = default;
68
69std::unique_ptr<AsyncRequest> AssetFileSource::request(const Resource& resource, Callback callback) {
70 auto req = std::make_unique<FileSourceRequest>(args: std::move(callback));
71
72 impl->actor().invoke(fn: &Impl::request, args: resource.url, args: req->actor());
73
74 return std::move(req);
75}
76
77bool AssetFileSource::acceptsURL(const std::string& url) {
78 return std::equal(first1: assetProtocol.begin(), last1: assetProtocol.end(), first2: url.begin());
79}
80
81} // namespace mbgl
82

source code of qtlocation/src/3rdparty/mapbox-gl-native/platform/default/asset_file_source.cpp