JavaScript "oslib"

Admin User, created Jan 06. 2024
         
/**
* Modern Albufeira Prolog Interpreter
*
* Warranty & Liability
* To the extent permitted by applicable law and unless explicitly
* otherwise agreed upon, XLOG Technologies AG makes no warranties
* regarding the provided information. XLOG Technologies AG assumes
* no liability that any problems might be solved with the information
* provided by XLOG Technologies AG.
*
* Rights & License
* All industrial property rights regarding the information - copyright
* and patent rights in particular - are the sole property of XLOG
* Technologies AG. If the company was not the originator of some
* excerpts, XLOG Technologies AG has at least obtained the right to
* reproduce, change and translate the information.
*
* Reproduction is restricted to the whole unaltered document. Reproduction
* of the information is only allowed for non-commercial uses. Selling,
* giving away or letting of the execution of the library is prohibited.
* The library can be distributed as part of your applications and libraries
* for execution provided this comment remains unchanged.
*
* Restrictions
* Only to be distributed with programs that add significant and primary
* functionality to the library. Not to be distributed with additional
* software intended to replace any components of the library.
*
* Trademarks
* Jekejeke is a registered trademark of XLOG Technologies AG.
*/
import {add, make_check, norm_float, exec_unify, deref,
exec_build, check_atom, make_error, Compound, fs
} from "../../dogelog.mjs";
/*********************************************************************/
/* File Access */
/*********************************************************************/
/**
* directory_files(F, L):
* The predicate succeeds in L with the entries of the directory F.
* Barks if path F doesn't exist or if path F doesn't point to directory.
*/
function test_directory_files(args) {
let url = deref(exec_build(args[0]));
check_atom(url);
if (fs === undefined)
throw make_error(new Compound("permission_error", ["access", "source_sink", url]));
let entries;
try {
entries = fs.readdirSync(url !== "" ? url : process.cwd());
} catch (err) {
if (err.code === "ENOENT") {
throw make_error(new Compound("existence_error", ["source_sink", url]));
} else {
throw make_error(new Compound("resource_error", ["io_exception"]));
}
}
let res = "[]";
for (let i = entries.length - 1; i >= 0; i--) {
let val = entries[i];
res = new Compound(".", [val, res]);
}
return exec_unify(args[1], res);
}
/**
* file_exists(F):
* The predicate succeeds if the file F exists, otherwise fails.
*/
function test_file_exists(args) {
let url = deref(exec_build(args[0]));
check_atom(url);
if (fs === undefined)
throw make_error(new Compound("permission_error", ["access", "source_sink", url]));
return fs.existsSync(url);
}
/**
* make_directory(F):
* The predicate succeeds. As a side effect a directory F is created.
* Barks if the parent of F doesn't exist or if F already exists.
*/
function test_make_directory(args) {
let url = deref(exec_build(args[0]));
check_atom(url);
if (fs === undefined)
throw make_error(new Compound("permission_error", ["access", "source_sink", url]));
try {
fs.mkdirSync(url);
} catch (err) {
if (err.code === "ENOENT") {
throw make_error(new Compound("existence_error", ["source_sink", url]));
} else {
throw make_error(new Compound("resource_error", ["io_exception"]));
}
}
return true;
}
/**
* delete_file(F):
* The predicate succeeds. As a side effect the file F is deleted.
* Barks if the file F doesn't exist or if its a directory.
*/
function test_delete_file(args) {
let url = deref(exec_build(args[0]));
check_atom(url);
if (fs === undefined)
throw make_error(new Compound("permission_error", ["access", "source_sink", url]));
try {
fs.unlinkSync(url);
} catch (err) {
if (err.code === "ENOENT") {
throw make_error(new Compound("existence_error", ["source_sink", url]));
} else {
throw make_error(new Compound("resource_error", ["io_exception"]));
}
}
return true;
}
/**
* copy_binary(F, G):
* The predicate succeeds. As a side effect the file F is copied
* to the file G, without rollback upon error. An already existing
* file G is silently overwritten.
*/
function test_copy_binary(args) {
let src = deref(exec_build(args[0]));
check_atom(src);
let dst = deref(exec_build(args[1]));
check_atom(dst);
try {
copy_binary(src, dst);
} catch (err) {
if (err.code === "ENOENT") {
throw make_error(new Compound("existence_error",
["source_sink", src]));
} else {
throw make_error(new Compound("resource_error",
["io_exception"]));
}
}
return true;
}
function copy_binary(src, dst) {
let bin = fs.openSync(src);
try {
let bout = fs.openSync(dst, "w");
try {
let buf = Buffer.alloc(8192);
let len = fs.readSync(bin, buf);
while (len > 0) {
fs.writeSync(bout, buf, 0, len);
len = fs.readSync(bin, buf);
}
} finally {
fs.closeSync(bout);
}
} finally {
fs.closeSync(bin);
}
}
/*********************************************************************/
/* Os Lib Init */
/*********************************************************************/
export function main() {
add("directory_files", 2, make_check(test_directory_files));
add("file_exists", 1, make_check(test_file_exists));
add("make_directory", 1, make_check(test_make_directory));
add("delete_file", 1, make_check(test_delete_file));
add("copy_binary", 2, make_check(test_copy_binary));
}