nissy-core

The "engine" of nissy, including the H48 optimal solver.
git clone https://git.tronto.net/nissy-core
Download | Log | Files | Refs | README | LICENSE

storage.cpp (2853B)


      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 	// This is a workaround related to usign WASM64
     47 	// JavaScript's UTF8ToString expects a pointer argument, which for JS is
     48 	// of type "number", but WASM64 is passing a BigInt. See also:
     49 	// https://github.com/emscripten-core/emscripten/issues/21541
     50 	// (but I could not make the suggested solution work in this case).
     51 	// TODO: check if there is a better workaround.
     52 	const non64_url = Number(url);
     53 	const non64_key = Number(key);
     54 	url = UTF8ToString(non64_url);
     55 	key = UTF8ToString(non64_key);
     56 	let response = await fetch(url);
     57 	if (!response.ok) {
     58 		console.log("Error downloading data for " + key);
     59 		console.log("" + response.status + ": " + response.statusText);
     60 		return 0;
     61 	}
     62 
     63 	let data = await response.bytes();
     64 	var stream = FS.open("/tables/" + key, "w+");
     65 	FS.write(stream, data, 0, data.length, 0);
     66 	FS.close(stream);
     67 	console.log("Data for " + key + " stored (" + data.length + " bytes)");
     68 	return 1;
     69 });
     70 
     71 bool storage::read(std::string key, size_t data_size, char *data)
     72 {
     73 	loadfs();
     74 
     75 	std::filesystem::path path(getprefix() + key);
     76 	if (!std::filesystem::exists(path))
     77 		return false;
     78 
     79 	std::ifstream ifs(path, std::ios::binary);
     80 	ifs.read(data, data_size);
     81 	ifs.close();
     82 
     83 	return !ifs.fail();
     84 }
     85 
     86 bool storage::write(std::string key, size_t data_size, const char *data)
     87 {
     88 	loadfs();
     89 
     90 	std::filesystem::path path(getprefix() + key);
     91 
     92 	std::ofstream ofs(path, std::ios::binary);
     93 	ofs.write(data, data_size);
     94 	ofs.close();
     95 
     96 	return !ofs.fail();
     97 }
     98 
     99 int storage::download(std::string key, std::string url)
    100 {
    101 	loadfs();
    102 	return download_and_store(key.c_str(), url.c_str());
    103 }