1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
|
#include "storage.h"
#include "emscripten.h"
#include <filesystem>
#include <fstream>
EM_JS(int, inbrowser, (), { return typeof window !== 'undefined'; });
EM_JS(int, inworker, (), { return typeof WorkerGlobalScope !== 'undefined' &&
self instanceof WorkerGlobalScope; });
std::string getprefix() {
return inbrowser() || inworker() ? "/tables/" : "./tables/";
}
EM_ASYNC_JS(int, loadfs, (), {
const inBrowser = typeof window !== 'undefined';
const inWorker = typeof WorkerGlobalScope !== 'undefined' &&
self instanceof WorkerGlobalScope;
console.assert(inBrowser || inWorker, "Non-browsers not supported");
const dir = '/tables';
if (!FS.analyzePath(dir).exists)
FS.mkdir(dir);
if (FS.analyzePath(dir).object.mount.mountpoint != dir) {
FS.mount(IDBFS, { autoPersist: true }, dir);
await new Promise((resolve, reject) => {
FS.syncfs(true, function (err) {
if (err)
reject(err);
else
resolve(true);
});
});
}
});
EM_ASYNC_JS(int, download_and_store, (const char *key, const char *url), {
const inBrowser = typeof window !== 'undefined';
const inWorker = typeof WorkerGlobalScope !== 'undefined' &&
self instanceof WorkerGlobalScope;
console.assert(inBrowser || inWorker, "Non-browsers not supported");
// See comment in callback.js about this workaround
const non64_url = Number(url);
const non64_key = Number(key);
url = UTF8ToString(non64_url);
key = UTF8ToString(non64_key);
let response = await fetch(url);
if (!response.ok) {
console.log("Error downloading data for " + key);
console.log("" + response.status + ": " + response.statusText);
return 0;
}
console.log("Data for " + key + " downloaded, writing to storage...");
let data = await response.bytes();
var stream = FS.open("/tables/" + key, "w+");
FS.write(stream, data, 0, data.length, 0);
FS.close(stream);
console.log("Data for " + key + " stored (" + data.length + " bytes)");
return 1;
});
bool storage::read(std::string key, size_t data_size, char *data)
{
loadfs();
std::filesystem::path path(getprefix() + key);
if (!std::filesystem::exists(path))
return false;
std::ifstream ifs(path, std::ios::binary);
ifs.read(data, data_size);
ifs.close();
return !ifs.fail();
}
bool storage::write(std::string key, size_t data_size, const char *data)
{
loadfs();
std::filesystem::path path(getprefix() + key);
std::ofstream ofs(path, std::ios::binary);
ofs.write(data, data_size);
ofs.close();
return !ofs.fail();
}
int storage::download(std::string key, std::string url)
{
loadfs();
return download_and_store(key.c_str(), url.c_str());
}
|