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 (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 }