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