Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
emscripten-core
GitHub Repository: emscripten-core/emscripten
Path: blob/main/system/lib/wasmfs/backends/fetch_backend.cpp
6175 views
1
// Copyright 2021 The Emscripten Authors. All rights reserved.
2
// Emscripten is available under two separate licenses, the MIT license and the
3
// University of Illinois/NCSA Open Source License. Both these licenses can be
4
// found in the LICENSE file.
5
6
// This file defines the fetch backend.
7
8
#include "fetch_backend.h"
9
#include "backend.h"
10
#include "proxied_async_js_impl_backend.h"
11
#include "wasmfs.h"
12
13
namespace wasmfs {
14
15
const uint32_t DEFAULT_CHUNK_SIZE = 16*1024*1024;
16
17
class FetchBackend : public wasmfs::ProxiedAsyncJSBackend {
18
std::string baseUrl;
19
uint32_t chunkSize;
20
public:
21
FetchBackend(const std::string& baseUrl,
22
uint32_t chunkSize,
23
std::function<void(backend_t)> setupOnThread)
24
: ProxiedAsyncJSBackend(setupOnThread), baseUrl(baseUrl), chunkSize(chunkSize) {}
25
std::shared_ptr<DataFile> createFile(mode_t mode) override;
26
std::shared_ptr<Directory> createDirectory(mode_t mode) override;
27
const std::string getFileURL(const std::string& filePath);
28
uint32_t getChunkSize();
29
};
30
31
32
class FetchFile : public ProxiedAsyncJSImplFile {
33
std::string filePath;
34
std::string fileUrl;
35
36
public:
37
FetchFile(const std::string& path,
38
mode_t mode,
39
backend_t backend,
40
emscripten::ProxyWorker& proxy)
41
: ProxiedAsyncJSImplFile(mode, backend, proxy), filePath(path) {
42
this->fileUrl = dynamic_cast<FetchBackend*>(getBackend())->getFileURL(filePath);
43
}
44
45
const std::string& getPath() const { return filePath; }
46
const std::string& getURL() const { return fileUrl; }
47
const uint32_t getChunkSize() const { return dynamic_cast<FetchBackend*>(getBackend())->getChunkSize(); }
48
};
49
50
class FetchDirectory : public MemoryDirectory {
51
std::string dirPath;
52
emscripten::ProxyWorker& proxy;
53
54
public:
55
FetchDirectory(const std::string& path,
56
mode_t mode,
57
backend_t backend,
58
emscripten::ProxyWorker& proxy)
59
: MemoryDirectory(mode, backend), dirPath(path), proxy(proxy) {}
60
61
std::shared_ptr<DataFile> insertDataFile(const std::string& name,
62
mode_t mode) override {
63
auto childPath = getChildPath(name);
64
auto child =
65
std::make_shared<FetchFile>(childPath, mode, getBackend(), proxy);
66
insertChild(name, child);
67
return child;
68
}
69
70
std::shared_ptr<Directory> insertDirectory(const std::string& name,
71
mode_t mode) override {
72
auto childPath = getChildPath(name);
73
auto childDir =
74
std::make_shared<FetchDirectory>(childPath, mode, getBackend(), proxy);
75
insertChild(name, childDir);
76
return childDir;
77
}
78
79
std::string getChildPath(const std::string& name) const {
80
return dirPath + '/' + name;
81
}
82
83
std::shared_ptr<File> getChild(const std::string& name) override {
84
return MemoryDirectory::getChild(name);
85
}
86
};
87
88
std::shared_ptr<DataFile> FetchBackend::createFile(mode_t mode) {
89
return std::make_shared<FetchFile>("", mode, this, proxy);
90
}
91
92
std::shared_ptr<Directory> FetchBackend::createDirectory(mode_t mode) {
93
return std::make_shared<FetchDirectory>("", mode, this, proxy);
94
}
95
96
const std::string FetchBackend::getFileURL(const std::string& filePath) {
97
if (filePath == "") {
98
return baseUrl;
99
}
100
return baseUrl + "/" + filePath;
101
}
102
103
uint32_t FetchBackend::getChunkSize() {
104
return chunkSize;
105
}
106
107
extern "C" {
108
backend_t wasmfs_create_fetch_backend(const char* base_url, uint32_t chunkSize) {
109
// ProxyWorker cannot safely be synchronously spawned from the main browser
110
// thread. See comment in thread_utils.h for more details.
111
assert(!emscripten_is_main_browser_thread() &&
112
"Cannot safely create fetch backend on main browser thread");
113
return wasmFS.addBackend(std::make_unique<FetchBackend>(
114
base_url ? base_url : "",
115
chunkSize ? chunkSize : DEFAULT_CHUNK_SIZE,
116
[](backend_t backend) { _wasmfs_create_fetch_backend_js(backend); }));
117
}
118
119
const char* _wasmfs_fetch_get_file_url(void* ptr) {
120
auto* file = reinterpret_cast<wasmfs::FetchFile*>(ptr);
121
return file ? file->getURL().data() : nullptr;
122
}
123
124
uint32_t _wasmfs_fetch_get_chunk_size(void* ptr) {
125
auto* file = reinterpret_cast<wasmfs::FetchFile*>(ptr);
126
return file ? file->getChunkSize() : DEFAULT_CHUNK_SIZE;
127
}
128
129
}
130
131
} // namespace wasmfs
132
133