rampart.utils¶
Utility functions are provided in the global rampart.utils Object. These functions bring file io and other functionality to Duktape JavaScript.
License¶
The modified printf
code used in the rampart utilities and in the Rampart Server
Module is provided by Marco Paland under the MIT License.
The %!H HTML escape
decoding is provided by Christoph Gärtner under the
Boost License.
The utilities are included in Rampart JavaScript and as such are licensed under the same MIT license.
General Utilities¶
printf¶
Print a formatted string to stdout. Provides C-like printf(3) functionality in JavaScript.
Usage:
rampart.utils.printf(fmt, ...)
- Return Value:
- Number. The length in bytes of the printed string.
Standard formats: Most of the normal flags and formats are respected. See standard formats and flags from printf(3).
Extended (non-standard) formats:
%s- corresponding argument is treated as a String (converted/coerced if necessary; Objects are converted the same as for%Jand Buffers are printed as is).
%S- same as%sexcept an error is thrown if the corresponding argument is not a String.
%J- print Object as JSON. An optional width (i.e.printf("%4J", obj);) may be given which will print with new lines and indentation of the specified amount. Thusprintf("%4J", obj);is equivalent toprintf("%s", JSON.stringify(obj, null, 4) );.
- if
!flag is present, a safe version of JSON will be printed where any references to inner Objects are marked. See second example below. Note: if!is omitted but printing would fail because of cyclic references, then!is implied. Also this flag will print any methods of an object which would otherwise be hidden with values such asmyfunc: {"_ecmascript_func": true}.
%B- print contents of a Buffer or String as base64.
- If
!flag present, it decodes a Buffer or String containing base64 (throws an error if not valid base64).- If a width is given (e.g.
%80B), a newline will be printed after everywidthcharacters.- If the
-flag is present and!is not present, the output will be a modified url safe base64 (using-and_in place of+and/).- If the
0flag is given (e.g.%0Bor%-080B), and!is not present, the output will not be padded with=characters.
%U- url encode (or if!flag present, decode) a String or Buffer. Without the!flag, Objects are converted to JSON first.
%H- html encode (or if!flag present, decode) a String or Buffer. Without the!flag, Objects are converted to JSON first.
%P- pretty print a String or Buffer. Expects text with white space. Format is%[!][-][i][.w]Pwhere:
iis the optional level of indentation. Each output line will be indented by this amount. Default is0. If0, the indent level for each paragraph will match the indentation of the first line of the corresponding paragraph in the input text (number of spaces at beginning of the paragraph).-when used with the!flag optionally sets indentation to 0 on all lines regardless ofior leading white space on first line..wwherewis the optional length of each line (default80if not specified).!specifies, if present, that newlines are not converted to spaces (but text after newlines is still indented). In all cases, a double newline (“\n\n”) is considered a separator of paragraphs and is respected.
%w- a shortcut format for%!-.wP- wherewis effectively unlimited. Remove all leading white space from each line and don’t wrap lines.
%C- like%cbut prints multi-byte character. Example:
rampart.utils.printf("%C", 0xf09f9983);prints🙃.Requires a number, 1-4 bytes (
0-4294967295, or0x0-0xffffffff).
%M- print multiline string. Corresponding argument must be an Array. This prints each member of the array without scrolling the terminal when called multiple times.Example:
for (var i=0,j=0; i<20; i++,j+=10) { rampart.utils.printf("%M", [`line 1: ${i}`, `line 2: ${j}`]); rampart.utils.sleep(0.2) } rampart.utils.printf("done\n");
Extended (non-standard) flags:
a- For all formats, accent output with color, if on a terminal that supports colors and usingprintf(...)orfprintf(stderr,...). Colors must be provided in a String before the parameter that will be colorized. Format for the color parameter isforegroundColor[, backgroundColor[, [option]]]where:
ForegroundColoris the color of the text.backgroundColoris the background color.optionisblinkorflashingfor blinking text.Color is specified in a css compatible
rgb(x, x, x)format, by providing a named css color or by providing a named terminal color.
^- same asaexcept 16 color mode is forced.
A- same asaexcept 256 color mode is forced.
@- same asaexcept truecolor mode is forced.
,- For base-10 numeric formats (%d,%i,%u,%lld,%f, etc.), group the integer portion of the number with commas as thousands separators. For floating point formats, only the digits before the decimal point are grouped. Always a comma, independent of locale.
'- The standard C grouping flag: same as,but uses the current locale’s separator (nothing under theClocale).Both flags also work with BigInt values.
Example:
rampart.utils.printf("%,d\n", 123456789098765); rampart.utils.printf("%,lld\n", 123456789098765); rampart.utils.printf("%,f\n", 123456789098765.0987);Output:
123,456,789,098,765 123,456,789,098,765 123,456,789,098,765.093750Although
%ddenotes a 32-bit integer, a Number whose value exceeds the 32-bit range is automatically promoted to a 64-bit integer (as if%lldhad been given) so the correct value is printed rather than a truncated one. The same promotion applies to%u,%x,%oand%b.
BigInt arguments:
All numeric formats accept a BigInt:
- For the integer formats (
%d,%i,%u,%x,%X,%o,%b, with or without anl/lllength modifier) the full, arbitrary-precision value is printed. Width, zero/space padding, the sign flags (+/space), the#prefix and the,grouping flag (base 10) are all honored.- For the floating point and exponential formats (
%f,%e,%gand their uppercase variants) the value is formatted directly from the BigInt’s exact digits — there is no conversion to a Number and therefore no precision loss, even at high precision (e.g.%.40e) or for magnitudes above 253.%sprints the BigInt’s decimal string.%Jprints{}, matchingJSON.stringifywhich cannot serialize a BigInt.var big = BigInt("123456789012345678901234567890"); rampart.utils.printf("%,d\n", big); // 123,456,789,012,345,678,901,234,567,890
Color with %H
format:
- Using
%aHor any of the forced versions (^,Aor@) will perform the same operation as with other format codes. In addition, it will wrap the text in a span with the foreground and background colors set as specified. It will also add theoptionas a class name to the span.Example:
rampart.utils.printf("%aH", "green, white, myclassname", "Text in a span");Output would be as follows:
<span class=”rp-color myclassname” style=”color:Green; background-color:White;”>Text in a span</span>If using
sprintfor if not printing to the terminal, output would be as follows:<span class=”rp-color myclassname” style=”color:Green; background-color:White;”>Text in a span</span>If the plus flag is included (
%+aH), rgb colors will be converted to the closest named css color.rampart.utils.sprintf("%+aH", "rgb(222,128,44)", "Text in a span");The return value would be as follows:
<span class=”rp-color” style=”color:Peru;”>Text in a span</span>
Colors with %J
format:
- Using
%aJor any of the forced versions (^,Aor@), takes as the color argument a number (palette number) rather than a foreground and background color. There are currently four palettes, numbered0-3. Anything not a number or outside of that range will default to0.var myObj = {Number:1.23, Bool:true, String:"Hello World!", Null: null}; rampart.utils.printf("%a3J\n", 0, myObj); rampart.utils.printf("%a3J\n", 1, myObj);{ Number": 1.23, "Bool": true, "String": "Hello World!", "Null": null } { Number": 1.23, "Bool": true, "String": "Hello World!", "Null": null }If palette option is omitted, and
myObjis not a Number, palette0will be assumed:rampart.utils.printf("%a3J\n", myObj); //palette 0 assumed
Basic printf example:
var uenc = "a+url+encoded+string.+%27%23%24%3f%27";
rampart.utils.printf("Encoded: %s\nDecoded: %!U\n", uenc, uenc);
/* expected output:
Encoded: a+url+encoded+string.+%27%23%24%3f%27
Decoded: a url encoded string. '#$?'
*/
var getty = "Four score and seven years ago our fathers\n" +
"brought forth on this continent, a new nation,\n" +
"conceived in Liberty, and dedicated to the proposition\n" +
"that all men are created equal."
rampart.utils.printf("%5.40P\n", getty);
/* or
rampart.utils.printf("%*.*P\n", 5, 40, getty);
*/
/* expected output:
Four score and seven years ago our
fathers brought forth on this
continent, a new nation, conceived
in Liberty, and dedicated to the
proposition that all men are
created equal.
*/
var html =
"<html>\n"+
" <body>\n"+
" <div>\n"+
" content\n"+
" </div>\n"+
" </body>\n"+
"</html>\n";
/* remove leading white space */
/* rampart.utils.printf("%!-.1000P", html); */
/* or more simply as */
rampart.utils.printf("%w", html);
/* expected output
<html>
<body>
<div>
content
</div>
</body>
</html>
*/
Example printing JSON with cyclic references:
var x = {a:{c:1},b:{} };
x.b.a = x.a;
// without "!", it is printed as normal
rampart.utils.printf("%3J\n", x);
/* expected results
{
"a": {
"c": 1
},
"b": {
"a": {
"c": 1
}
}
}
*/
// with "!" all self references are printed
rampart.utils.printf("%!3J\n", x);
/* expected results:
{
"a": {
"c": 1
},
"b": {
"a": {
"_cyclic_ref": "$.a"
}
}
}
*/
// add cyclic ref
x.x_ref = x;
// with a cyclic ref present, "!" is implied
rampart.utils.printf("%3J\n", x);
/* expected results:
{
"a": {
"c": 1
},
"b": {
"a": {
"_cyclic_ref": "$.a"
}
},
"x_ref": {
"_cyclic_ref": "$"
}
}
*/
bprintf¶
Same as sprintf()
except a Buffer is returned.
- Return Value:
- Buffer. The formatted string as a Buffer.
abprintf¶
Same as bprintf()
except a provided Buffer is resized and appended.
Usage:
var newBuf = abprintf(oldbuf[, start], fmt, ...);
Where:
oldbufis a Buffer - the Buffer to be appended.startis an optional Number, where inoldbufto start writing data. Default is the end ofoldbuf. May be a negative number, signifying how many bytes from the end of the string to start.fmt, ...- A format String and optional format parameters.
- Return Value:
-
Buffer. The formatted string appended to
oldbufas a dynamic Buffer. - Note:
-
The Buffer
oldbufwill be altered if it is a dynamic buffer. Otherwise, it will be copied andoldbufremains unaltered.
hexify¶
Convert data to a hex string.
Usage:
var hexstring = rampart.utils.hexify(data [, upper]);
Where data is the
string of bytes (String or Buffer) to be
converted and upper
is an optional Boolean, which if true prints using upper-case
A-F.
- Return Value:
- String. Each byte in data is converted to its two character hex representation.
Example: See dehexify below.
dehexify¶
Convert a hex string to a string of bytes.
Usage:
var data = rampart.utils.dehexify(hexstring);
- Return Value:
- Buffer. Each two character hex representation converted to a byte in the binary string.
Example:
rampart.globalize(rampart.utils);
var s=sprintf("%c%c%c%c",0xF0, 0x9F, 0x98, 0x8A);
printf("0x%s\n", hexify(s) );
printf("%s\n", dehexify(hexify(s)) );
/* expected output:
0xf09f988a
😊
*/
stringToNumber¶
Convert various plain English Strings to a Number or Number range.
Usage:
var buf = rampart.utils.stringToNumber(nstr [, retObj ]);
Where nstr is a
String and optional retObj is a Boolean.
Examples:
rampart.globalize(rampart.utils);
var res = strintToNumber("five");
// res = 5
res = stringToNumber("three and a half");
// res = 3.5
res = stringToNumber("four score and seven");
// res = 87
res = stringToNumber("five dozen");
// res = 60
res = stringToNumber("a gazillion");
// res = NaN
res = stringToNumber("five dozen", true);
/* res = {
"value": 60,
"op": "=",
"rem": ""
} */
res = stringToNumber("five dozen cookies",true);
/* res = {
"value": 60,
"op": "=",
"rem": "cookies"
} */
res = stringToNumber("less than twenty",true);
/* res = {
"value": 20,
"op": "<",
"rem": ""
} */
res = stringToNumber("less than twenty greater than one half is our range",true);
/* res = {
"value": 20,
"min": 0.5,
"max": 20,
"rem": "is our range"
} */
stringToBuffer¶
Performs a byte-for-byte copy of a String into a Buffer. Also convert one Buffer to a Buffer of another type. See duk_to_buffer() in the Duktape documentation
Usage:
var buf = rampart.utils.stringToBuffer(data [, buftype ]);
Where data is a
String or Buffer and buftype is one of the following
Strings:
"fixed"- returned Buffer is a “fixed” Buffer."dynamic"- returned Buffer is a “dynamic” Buffer.
If no buftype is
given and data is a
Buffer, the same type of Buffer is
returned. If no buftype is given and data is a String, a “fixed” Buffer is returned.
See Duktape documentation for more information on different types of Buffers.
- Return Value:
- Buffer. Contents of String/Buffer copied to a new Buffer Object.
bufferToString¶
Performs a 1:1 copy of the contents of a Buffer to a String.
See duk_buffer_to_string() in the Duktape documentation
Usage:
var str = rampart.utils.bufferToString(data);
Where data is a Buffer Object.
- Return Value:
- String. Contents of Buffer copied to a new String.
objectToQuery¶
Convert an Object of key/value pairs to a String suitable for use as a query string in an HTTP request.
Usage:
var qs = rampart.utils.objectToQuery(kvObj [, arrayOpt]);
Where kvObj is an
Object containing the key/value pairs and arrayOpt controls how
Array values are treated. A String, one
of the following:
"repeat"- default value if not specified. Repeat the key in the query string with each value from the array. Example:{key1: ["val1", "val2"]}becomeskey1=val1&key1=val2."bracket"- similar to repeat, except url encoded[]is appended to the keys. Example:{key1: ["val1", "val2"]}becomeskey1%5B%5D=val1&key1%5B%5D=val2."comma"- One key with corresponding values separated by a,(comma). Example:{key1: ["val1", "val2"]}becomeskey1=val1,val2."json"- encode array as JSON. Example:{key1: ["val1", "val2"]}becomeskey1=%5b%22val1%22%2c%22val2%22%5d.
Note that the values null and undefined will be translated as the Strings
"null" and
"undefined"
respectively. Also values which themselves are Objects will be
converted to JSON.
queryToObject¶
Convert a query string to an Object. Reverses the process, with caveats, of objectToQuery().
Usage:
var kvObj = rampart.utils.queryToObject(qs);
Caveats:
- All primitive values will be converted to Strings unless
jsonwas used. - If
repeatorbracketwas used to create the query string, all values will be returned as strings (even if an Array of Numbers was given to objectToQuery(). - If
commawas used to create the query string, no separation of comma separated values will occur and the entire value will be returned as a String. - If
jsonwas used, numeric values will be preserved as Numbers. - If the query string contains object like notation (e.g.
"myvar[mykey]=myval&myvar[mykey2]=myval2"), it will be converted into an Object ({myvar: {mykey:"myval", mykey2:"myval2"} }).
Example:
var obj= {
key1: null,
key2: [1,2,3],
key3: ["val1","val2"]
}
var type = [ "repeat", "bracket", "comma", "json" ];
for (var i=0; i<4; i++) {
var qs = rampart.utils.objectToQuery(obj, type[i] );
var qsobj = rampart.utils.queryToObject(qs);
rampart.utils.printf("queryToObject(\n '%s'\n ) = \n%3J\n", qs, qsobj);
}
/* expected output:
queryToObject(
'key1=null&key2=1&key2=2&key2=3&key3=val1&key3=val2'
) =
{
"key1": "null",
"key2": [
"1",
"2",
"3"
],
"key3": [
"val1",
"val2"
]
}
queryToObject(
'key1=null&key2%5B%5D=1&key2%5B%5D=2&key2%5B%5D=3&key3%5B%5D=val1&key3%5B%5D=val2'
) =
{
"key1": "null",
"key2": [
"1",
"2",
"3"
],
"key3": [
"val1",
"val2"
]
}
queryToObject(
'key1=null&key2=1,2,3&key3=val1,val2'
) =
{
"key1": "null",
"key2": "1,2,3",
"key3": "val1,val2"
}
queryToObject(
'key1=null&key2=%5b1%2c2%2c3%5d&key3=%5b%22val1%22%2c%22val2%22%5d'
) =
{
"key1": "null",
"key2": [
1,
2,
3
],
"key3": [
"val1",
"val2"
]
}
*/
getchar¶
Get one or more characters from stdin.
Usage:
var instr = rampart.utils.getchar([nchar]);
Where nchar is an
optional number, the number of characters to read from stdin. The default is
1.
- Return Value:
-
A String of length
nchars. - Note:
-
If
stdinis from an interactive terminal, execution will be paused untilncharchars are input. Unlikefread(stdin);below, the terminal will be set to return characters without waiting for a newline.
readFile¶
Read the contents of a file.
Usage:
var contents = rampart.utils.readFile({
file: filename
[, offset: offsetPos]
[, length: rLength]
[, returnString: return_str]
});
/* or */
var contents = rampart.utils.readFile(filename [, offsetPos [, rLength]] [, return_str]);
Where values filename and optional values offsetPos, rLength and/or return_str are:
| Argument | Type | Description |
|---|---|---|
| filename | String | Path to the file to be read |
| offsetPos | Number | If positive, start position to read from beginning of file. |
| If negative, start position to read from end of file. | ||
| rLength | Number | If greater than zero, amount in bytes to be read. |
| If 0 or negative, position from end of file to stop reading. | ||
| return_str | Boolean |
If not set, or false, return a Buffer.
|
If true,
return contents as a String. May be truncated if the file
contains null characters.
|
- Return Value:
- Buffer or String. The contents of the file.
Example:
rampart.utils.fprintf("/tmp/file.txt","This is a text file\n");
var txt = rampart.utils.readFile({
filename: "/tmp/file.txt",
offset: 10,
length: -6,
retString: true
});
/* or var txt = rampart.utils.readFile("/tmp/file.txt", 10, -6, true); */
rampart.utils.printf("'%s'\n", txt);
/* expected output:
'text'
*/
- Note:
-
If
return_stristrueandoffsetPosand/orrLengthare set, the returned String may be shortened to ensure that the return value is a valid UTF-8 string. If that behavior is not desired, returning a Buffer and converting to a string with, e.g. sprintf() or bufferToString() will bypass the UTF-8 character/byte boundary check.
writeFile¶
Write the contents of a String or Buffer to a file in one call. Convenience wrapper around fopen() + fwrite() + fclose(). Truncates an existing file by default.
Usage:
rampart.utils.writeFile(path, data [, options]);
Where:
-
pathis a String, the path to the file to be written. -
datais a String or Buffer (any buffer type, including Uint8Array). -
optionsis an optional Object with the following properties:-
mode– Number or String (octal). File permissions applied viafchmodafter the bytes are written. If unset, the systemumaskdetermines mode. See chmod() for octal notation. -
flag– String, thefopenmode to use. Defaults to"w"(truncate). Pass"a"to append, or use appendFile() below for the common append case.
-
- Return Value:
-
undefined. Throws on I/O error.
Example:
rampart.utils.writeFile("/tmp/note.txt", "hello\n");
rampart.utils.writeFile("/tmp/key.bin", new Uint8Array([1,2,3]), {mode: 0o600});
appendFile¶
Append the contents of a String or Buffer
to a file. Creates the file if it does not exist. Equivalent to writeFile(path, data, {flag: "a"}).
Usage:
rampart.utils.appendFile(path, data [, options]);
Arguments are the same as writeFile()
above; the flag
option, if provided, overrides the default of "a".
- Return Value:
-
undefined. Throws on I/O error.
trim¶
Remove whitespace characters from the beginning and end of a String.
Usage:
var trimmed = rampart.utils.trim(str);
Where str is a
String.
- Return Value:
-
String.
strwith whitespace removed from beginning and end.
Example:
var str = "\n a line of text \n";
rampart.utils.printf("'%s'", rampart.utils.trim(str));
/* expected output:
'a line of text'
*/
minify¶
Minify JavaScript source code by removing unnecessary whitespace, stripping comments, and mangling (shortening) local variable names. Global variables and object property names are preserved.
Usage:
var minified = rampart.utils.minify(src);
Where src is a
String containing JavaScript source code.
- Return Value:
- String. The minified JavaScript code.
Example:
var src = "function add(first, second) {\n return first + second;\n}";
var min = rampart.utils.minify(src);
/* expected output:
"function add(a,b){return a+b;}"
*/
stat¶
Return information on a file.
Usage:
var st = rampart.utils.stat(file);
Where file is a
String (name of file).
- Return Value:
-
Boolean/Object.
falseif file does not exist. Otherwise an Object with the following properties:
{
"dev": Number,
"ino": Number,
"mode": Number,
"nlink": Number,
"uid": Number,
"gid": Number,
"rdev": Number,
"size": Number,
"blksize": Number,
"blocks": Number,
"atime": Date,
"mtime": Date,
"ctime": Date,
"readable": Boolean,
"writable": Boolean,
"executable": Boolean,
"owner": String,
"group": String,
"isBlockDevice": Boolean,
"isCharacterDevice": Boolean,
"isDirectory": Boolean,
"isFIFO": Boolean,
"isFile": Boolean,
"isSocket": Boolean,
"permissions": String /* i.e. "-rw-r--r--" */
}
See stat
(2) for the meaning of each property. The is* Booleans are set to true if the corresponding file property is true.
Example:
var st = rampart.utils.stat("/tmp/file.txt");
if(st) {
/* print file mode as octal number */
rampart.utils.printf("%o\n", st.mode & 0777)
} else {
console.log("file /tmp.file.txt does not exist");
}
/* expected output: 644 */
lstat¶
Same as stat() except if file is a link, return
information about the link itself.
- Return Value:
-
Same as stat() with the addition of the
property
isSymbolicLinkwhich is settrueif the file is a symbolic link.readableandwritablerefer to the link, not the target.
exists¶
Test whether a path resolves to anything accessible. Convenience wrapper that returns
false for missing
paths and inaccessible parents (the errors stat() would swallow into a false return) without forcing callers to examine the stat result.
Usage:
var ok = rampart.utils.exists(path);
Where path is a
String.
- Return Value:
-
Boolean.
trueif the path exists and is reachable,falseotherwise.
statVfs¶
Return filesystem statistics for the volume containing path – block sizes, free space,
inode counts and similar values reported by statvfs (3).
Usage:
var info = rampart.utils.statVfs(path);
Where path is a
String, any path on the volume of interest.
- Return Value:
- Object with the following properties:
{
"bsize": Number, /* filesystem block size */
"frsize": Number, /* fragment size */
"blocks": Number, /* total fragments */
"bfree": Number, /* free fragments */
"bavail": Number, /* free fragments available to non-root */
"files": Number, /* total inodes */
"ffree": Number, /* free inodes */
"favail": Number, /* free inodes available to non-root */
"fsid": Number, /* filesystem ID */
"flag": Number, /* mount flags */
"namemax": Number, /* maximum filename length */
"totalBytes": Number, /* convenience: frsize * blocks */
"freeBytes": Number, /* convenience: frsize * bfree */
"availBytes": Number /* convenience: frsize * bavail */
}
Throws if the path cannot be resolved.
exec¶
Run an executable file.
Usage:
var ret = rampart.utils.exec(command [, options] [,arg1, arg2, ..., argn] );
Where:
-
command- String. An absolute path to an executable or the name of an executable that may be found in the currentPATHenvironment variable. -
options- Object. Containing the following properties:-
timeout- Number. Maximum amount of time in milliseconds before the process is automatically killed. Valid ifbackgroundis unset orfalse. -
killSignal- Number. If timeout is reached, use this signal. Valid ifbackgroundis unset orfalseand atimeoutvalue is set. -
background- Boolean. Whether to execute detached and return immediately. Iftrue,stdoutandstderrbelow will be set tonull. Anytimeoutvalue is ignored. -
env- Object. Key/value pairs to be used as environment variables for the executed process. Default, if not provided is process.env. An empty Object ({}) removes all environment variables. -
appendEnv- Boolean. Iffalse(the default), only the environment variables given inenvwill be available. Iftrue, variables provided inenvwill be appended to process.env. Duplicate keys in process.env are replaced with the value fromenv. -
stdin- String or Buffer. If specified, the content of the String or Buffer is piped to the command as stdin. -
returnBuffer- Boolean. Whether content is returned in a Buffer rather than a String. Useful for capturing binary data output. -
args- Array. An array of arguments to be passed to the executable. If arguments are also given as parameters toexec(), the Array of arguments are appended. -
changeDirectory- String. Change the working directory to value before executing. -
cd- Alias forchangeDirectory.
-
-
argn- String/Number/Object/Boolean/Null - Arguments to be passed tocommand. Non-Strings are converted to a String (e.g. “true”, “null”, “42” or for Object, the equivalent ofJSON.stringify(obj)).
- Return Value:
-
Object. Properties as follows:
-
stdout- String. Output of command ifbackgroundis not settrue. Otherwisenull. -
stderr- String. stderr output of command ifbackgroundis not settrue. Otherwisenull. -
exitStatus- Number. The returned exit status of the command. -
timedOut- Boolean. Set true if the program was killed aftertimeoutmilliseconds has elapsed. -
pid- Number. Process id of the executed command.
-
getenv¶
Return the value of an environment variable as currently set in the process’s environment.
Usage:
var value = rampart.utils.getenv(name);
Where name is a
String containing the environment variable name.
- Return Value:
-
String containing the current value of the variable, or
undefinedif the variable is not set.
How this differs from process.env:
process.env is a Object populated with a snapshot of the environment at the time rampart started. Reads from
process.envreturn values from that snapshot; writes modify only the snapshot and are not visible to native code that callsgetenv(3)(such as a library loaded viarequire()), nor are they inherited by child processes spawned with exec().
rampart.utils.getenvconsults the live OS-level process environment. It sees values set later via setenv() (whether by this function family or by C code in a loaded module), and it does not see writes made only to theprocess.envObject.
Example:
process.env.HELLO = "from-js-dict";
rampart.utils.setenv("HELLO", "from-os-env");
rampart.utils.printf("process.env.HELLO = %s\n",
process.env.HELLO); /* from-js-dict */
rampart.utils.printf("rampart.utils.getenv() = %s\n",
rampart.utils.getenv("HELLO")); /* from-os-env */
rampart.utils.printf("child shell sees = %s\n",
rampart.utils.exec("/bin/sh","-c","echo $HELLO").stdout);
/* from-os-env\n */
setenv¶
Set an environment variable in the process’s live OS-level environment. Wraps POSIX setenv(3).
Usage:
rampart.utils.setenv(name, value [, overwrite]);
Where:
-
name- String. The variable name. Must be non-empty and may not contain=. -
value- String. The value to assign. -
overwrite- Boolean. Optional. Iftrue(the default) and the variable is already set, the existing value is replaced. Iffalse, an existing value is left untouched.
- Return Value:
- Undefined. Throws on error (e.g. invalid name, allocation failure).
- Notes:
-
The value is visible to subsequent
rampart.utils.getenv()calls, to native code that callsgetenv(3), and to child processes spawned with exec(). Writes to process.env do not have these properties; usesetenvwhen something outside the JS runtime needs to read the value.A common use case is preparing an environment variable that a native module reads from its library constructor. For example,
MAGICK_CONFIGURE_PATHmust be set beforerequire("rampart-graphicsmagick")triggers the load oflibGraphicsMagick;rampart-gm.jsdoes exactly that viarampart.utils.setenvbefore therequire().
Example:
rampart.utils.setenv("MY_VAR", "hello");
rampart.utils.printf("%s\n", rampart.utils.getenv("MY_VAR"));
/* expected output:
hello
*/
/* overwrite=false: leave a caller-supplied value in place */
rampart.utils.setenv("MY_VAR", "ignored", false);
rampart.utils.printf("%s\n", rampart.utils.getenv("MY_VAR"));
/* expected output:
hello
*/
unsetenv¶
Remove an environment variable from the process’s live OS-level environment. Wraps POSIX unsetenv(3).
Usage:
rampart.utils.unsetenv(name);
Where name is a
String. Must be non-empty and may not contain =.
- Return Value:
- Undefined. Throws on error.
- Notes:
-
Removing a variable affects
rampart.utils.getenv(), native code that callsgetenv(3), and child processes spawned by exec(). It does not modify process.env; if you want both views cleared, delete the property fromprocess.envas well.
Example:
rampart.utils.setenv("TEMP_VAR", "x");
rampart.utils.unsetenv("TEMP_VAR");
rampart.utils.printf("%s\n", rampart.utils.getenv("TEMP_VAR") || "(unset)");
/* expected output:
(unset)
*/
shell¶
Execute String in a bash shell. Equivalent to rampart.utils.exec("bash", "-c", shellcmd);.
Usage:
var ret = rampart.utils.shell(shellcmd[, options]);
Where shellcmd is a
String containing the command and arguments to be passed to bash and
options are the same
as specified for exec.
- Return Value:
- Same as exec().
Example:
var ret = rampart.utils.shell('echo -n "hello"; echo "hi" 1>&2;');
console.log(JSON.stringify(ret, null, 3));
/* expected output:
{
"stdout": "hello",
"stderr": "hi\n",
"timedOut": false,
"exitStatus": 0,
"pid": 24658
}
*/
fork¶
Fork the current process.
Usage:
var pid = rampart.utils.fork([pipe, pipe2, ..., pipeX]);
if(pid=-1)
rampart.utils.fprintf(rampart.utils.stderr, "error forking\n");
if(pid) {
//parent
} else {
//child
}
Where pipeX is one
or several pipes created with newPipe below.
- Return Value:
-
A Number - The pid of the child in the parent process,
0in the child process and-1if there is an error and fork failed. - Note:
-
forkwill throw an error if there are any threads running at the time of the fork, either fromrampart.threadorrampart-server. Threads, however, can be created after the fork in either the child or parent process.
newPipe¶
Create a bi-directional pipe for passing variables between processes created with fork above.
Usage:
var pipe = rampart.utils.newPipe();
var pid = fork(pipe);
- Return Value:
-
An Object of Functions:
-
write(data)- write to the pipe, where data is any variable which can be serialized usingCBOR. Return value is the number of bytes written. Note: writes may block if the pipe is full until the reading process reads with one of the two read functions below. Throws an error if pipe has been closed. -
read([function])- perform a blocking read of data sent from another process usingwrite()above. If a function is provided (i.e.function(value, error){}) the value or error will be passed to that callback (with the other being undefined). Return value will be undefined. If no function is provided, the return value will be an Object with eithervalueorerrorset. -
onRead(function)- same asread, except that a Function is required, the call is non-blocking and the callback Function will be called in the event loop each time data is available. On error, the pipe will close and the event will be removed. -
close()- close the pipe. Any further reads or writes from either process will produce or throw an error.
-
Example:
var pipe = rampart.utils.newPipe();
// fork and set the pipe for parent and child processes
var pid = fork(pipe);
if(pid ==-1) {
rampart.utils.fprintf(rampart.utils.stderr, "error piping\n");
process.exit(1);
}
if(pid) {
//parent
pipe.write("My first message");
pipe.write("My second message");
} else {
//child
var msg = pipe.read();
if(msg.err)
rampart.utils.fprintf(rampart.utils.stderr, "error reading- %s\n", msg.error);
else
rampart.utils.printf("msg = '%s'\n", msg.value);
//run non-blocking in event loop
pipe.onRead(function(val,err) {
if(err)
rampart.utils.fprintf(rampart.utils.stderr, "read event: error reading- %s\n", err);
else
rampart.utils.printf("read event: msg = '%s'\n", val);
});
}
daemon¶
Same as fork above, except it double forks, detaches and creates its own session. Thus the child process will continue to run after the parent and the controlling terminal exit.
forkpty¶
Run an executable file in a pseudo-terminal with unbuffered IO. IO is performed asynchronously in the event loop of the current thread.
Usage:
var pty = rampart.utils.forkpty(command [, options] [,arg1, arg2, ..., argn] );
Where:
-
command- String. An absolute path to an executable or the name of an executable that may be found in the currentPATHenvironment variable. -
options- Object. Containing the following properties:-
env- Object. Key/value pairs to be used as environment variables for the executed process. Default, if not provided is process.env. An empty Object ({}) removes all environment variables. -
appendEnv- Boolean. Iffalse(the default), only the environment variables given inenvwill be available. Iftrue, variables provided inenvwill be appended to process.env. Duplicate keys in process.env are replaced with the value fromenv.
-
-
argn- String/Number/Object/Boolean/Null - Arguments to be passed tocommand. Non-Strings are converted to a String (e.g. “true”, “null”, “42” or for Object, the equivalent ofJSON.stringify(obj)).
- Return Value:
-
Object. Properties as follows:
-
read- Function. Read data from the stdout of the executed process.pty.read([buffersize [, maxread]] [, retstring]);
Where:
buffersizedefaults to4096,maxreaddefaults to unlimited andretstring(defaultfalsefor Buffer) is a Boolean - whether the return contents should be converted to String. -
write- Function. Write data to the stdin of the executed process.pty.write([buffer|string]);
-
resize- Function. Set a new size for the pseudo-terminal.pty.resize(width, height);
Where:
widthandheightare Numbers - number of character rows and columns. -
on- Function: Two events are currently allowed:"data"and"close". If,"data"is specified, when new data is available to be read, the provided callback function will be called. If"close"is specified, the provided callback function will be called when the process exits.pty.on(['data'|'close'], callback);
If there is an initial error executing
command,forkpty()will throw an error. When the command exits, the functions in the return object will be deleted. Therefore a check should be run before accessing any functions in case the pty has closed:var pty = rampart.utils.forkpty(command [, options] [,arg1, arg2, ..., argn] ); if(pty.write) pty.write(msg); else do_cleanup();
An example for using
forkpty()with websockets to run a terminal in a web browser can be found here. -
kill¶
Terminate a process or send a signal.
Usage:
var ret = rampart.utils.kill(pid [, signal[, throwOnError]]);
- Where:
-
-
pidis a Number, the process id of process which will receive the signal. -
signalis a Number, or String, the signal to send. Ifsignalis not specified,15(SIGTERM) is used. See manual page for kill(1) for a list of signals, which may vary by platform. Settingsignalto0sends no signal, but checks for the existence of the process identified bypid.signalmay also be a String, a well known signal such as"SIGTERM"or"SIGUSR1". -
throwOnError- Boolean - whether to throw an error with a specified reason upon failure. Default isfalse.
-
- Return Value:
-
Boolean.
trueif the signal was successfully sent. IfthrowOnErroris nottrue, will returnfalseif there was an error or process does not exist.
Example:
var ret = rampart.utils.exec("sleep", "100", {background:true});
var pid=ret.pid;
if (rampart.utils.kill(pid,0)) {
console.log("process is still running");
rampart.utils.kill(pid);
rampart.utils.sleep(0.2);
if( rampart.utils.kill(pid,0) == 0 )
console.log("and now is dead");
} else
console.log("not running");
/* expected output:
process is still running
and now is dead
*/
getcwd¶
Return the current working directory as a String.
Usage:
rampart.utils.getcwd();
- Return Value:
- A String, the current working directory of the script.
chdir¶
Change the current working directory.
Usage:
rampart.utils.chdir(path);
Where path is a
String, the location of the new working directory. This command
throws an error if it fails to change to the specified directory.
- Return Value:
-
undefined.
mkdir¶
Create a directory.
Usage:
rampart.utils.mkdir(path [, mode]);
Where path is a
String, the directory to be created and mode is a Number or String, the octal permissions mode. Any
parent directories which do not exist will also be created. Throws error if lacking permissions
or if another error was encountered.
Note that mode is
normally given as an octal. As such it can be, e.g., 0755 (octal number) or
"755" (String representation of an octal number), but 755, as a decimal number will
give the octal 01363, which is likely not what was intended.
- Return Value:
-
undefined.
mkdTemp¶
Create a uniquely-named directory using mkdtemp (3). Six random characters
are appended to the supplied prefix and a new directory is created with mode 0700 (owner only).
Usage:
var dir = rampart.utils.mkdTemp(prefix);
Where prefix is a
String – the full path leading up to the random suffix. For example,
"/tmp/build-"
produces a directory like /tmp/build-AbC123.
- Return Value:
- String. The full path of the newly created directory. Throws on failure (most commonly because the parent directory does not exist or is not writable).
rmdir¶
Remove an empty directory.
Usage:
rampart.utils.rmdir(path [, recurse]);
Where path is a
String, the directory to be removed and recurse is an optional
Boolean, which if true, parent directories
explicitly present in path will also be removed. Throws an error if the directory cannot be
removed (e.g., not empty or lacking permission).
- Return Value:
-
undefined.
Example:
/* make the following directories in the
current working directory */
rampart.utils.mkdir("p1/p2/p3",0755);
/* remove the directories recursively */
rampart.utils.rmdir("p1/p2/p3", true);
readDir¶
Get listing of directory files.
Usage:
var files = rampart.utils.readdir(path [, showhidden]);
Where path is a
String, the directory whose content will be listed and showhidden is a Boolean, which if true, files or directories beginning with . (hidden files) will be
included in the return value.
- Return Value:
- Array. An Array of Strings, each filename in the directory.
walkDir¶
Recursively walk a directory tree, calling a JavaScript Function for each entry encountered. Used internally by cp() and rm(); also useful directly for custom traversals.
Usage:
rampart.utils.walkDir(dir, callback [, options]);
Where:
-
diris a String, the path to descend. -
callbackis a Functioncallback(path, type, depth)invoked per entry:-
path– String, the entry’s full path (relative todirifdirwas relative). -
type– String, one of"file","dir","symlink", or"other". -
depth– Number, depth fromdir. The root passed in has depth0.
Returning
falsefrom the callback stops the walk (rampart’s standard callback-abort convention). -
-
optionsis an optional Object:-
followLinks– Boolean, defaultfalse. Iftrue, symlinks are followed during the descent. -
postOrder– Boolean, defaultfalse. Iftrue, directory entries are emitted after their contents (depth-first leaves-then-branches). Useful for safe recursive deletion.
-
- Return Value:
-
undefined.
Example:
/* Build an array of all .js files under the cwd */
var jsFiles = [];
rampart.utils.walkDir(".", function(p, t) {
if (t === "file" && /\.js$/.test(p)) jsFiles.push(p);
});
glob¶
Expand a wildcard pattern to a list of matching paths. Supports * (any chars within a
component), ?
(single char), [abc]
/ [a-z] /
[!abc] character
classes, and ** as a
component meaning “any depth of subdirectories”. No brace expansion.
Usage:
var matches = rampart.utils.glob(pattern [, options]);
Where:
-
patternis a String, either relative or absolute. Absolute patterns start the search at/; relative patterns start atoptions.cwdor the current working directory. -
optionsis an optional Object:-
cwd– String, the base directory for relative patterns. Default".". -
dot– Boolean, defaultfalse. Iftrue, dotfiles are included in matches.
-
- Return Value:
- Array of Strings, the matching paths (may be empty).
Example:
/* All .js files anywhere below ./src */
var src = rampart.utils.glob("**/*.js", {cwd: "./src"});
/* Absolute pattern */
var logs = rampart.utils.glob("/var/log/*.log");
zipList¶
Read a zip archive’s central directory and return a description of every entry. Does not extract, decompress or modify anything.
Usage:
var entries = rampart.utils.zipList(zipPath);
Where zipPath is a
String, the path to a zip file on disk.
- Return Value:
-
Object. Keys are entry names (as stored in the archive, so directory entries end with
"/"). Each value is an Object with these properties:Property Description size Number. Uncompressed size in bytes. compressedSize Number. Stored size in bytes. method Number. Compression method ( 0= stored,8= deflate).crc32 Number. CRC-32 of the uncompressed bytes. mode Number. Unix mode bits (file type + permissions). mtime Date. Modification time (omitted if the entry has none). isFile Boolean. truefor regular files.isDirectory Boolean. truefor directory entries.isSymbolicLink Boolean. truefor symlink entries.permissions String. ls -l-style mode string, e.g."-rw-r--r--".
Throws if the path is not a readable zip archive.
var e = rampart.utils.zipList("/tmp/release.zip");
// { "README.md": { size: 1024, isFile: true, ... },
// "lib/": { size: 0, isDirectory: true, ... },
// "lib/x.js": { size: 5120, isFile: true, ... },
// ... }
for (var name in e)
if (e[name].isFile)
console.log(name, e[name].size, "bytes");
zipGet¶
Read one entry from a zip archive into a Buffer. The entry is decompressed if it was stored with deflate.
Usage:
var buf = rampart.utils.zipGet(zipPath, entryName);
Where zipPath is a
String (path to the zip file on disk) and entryName is a String naming an entry as it appears in zipList()’s output.
Symbolic-link entries are followed; the returned buffer is the contents of the link’s final
target inside the archive.
- Return Value:
- Buffer. The uncompressed contents of the named entry.
Throws if the zip cannot be opened, the entry is missing, the entry uses an unsupported compression method, or a symlink chain cannot be resolved.
var b = rampart.utils.zipGet("/tmp/release.zip", "README.md");
console.log(rampart.utils.bufferToString(b));
zipExtract¶
Extract some or all of a zip archive’s entries to a destination directory on disk. File modes, modification times and symbolic links are preserved.
Usage:
var n = rampart.utils.zipExtract(zipPath, destPath [, entries]);
Where:
zipPath– String. The zip file on disk.destPath– String. The destination directory. It and any intermediate directories implied by entry names will be created as needed.entries– Array of Strings, optional. If omitted (orundefined/null), every entry is extracted. If supplied, only entries whose name matches one of the listed names is extracted. Names ending in"/"match every entry in that directory tree; bare names match exactly.
- Return Value:
- Number. The count of entries actually written to disk.
Notes:
- Path traversal is blocked: an entry name containing
..segments that would resolve outsidedestPathis rejected.- Symlinks are extracted as real symlinks (
symlink(target, path)); the link target is taken verbatim from the archive without further validation.chmodandutimensatfailures during metadata fixup are silently ignored so a bulk extract is not aborted by a single unprivileged operation.
// unpack the entire archive
rampart.utils.zipExtract("/tmp/release.zip", "/opt/myapp/");
// unpack just two specific files
rampart.utils.zipExtract("/tmp/release.zip", "/tmp/cfg/",
["README.md", "etc/default.conf"]);
// unpack everything under "templates/"
rampart.utils.zipExtract("/tmp/release.zip", "/var/www/", ["templates/"]);
Note
The bundle feature exposes three additional functions – rampart.utils.payloadList(),
rampart.utils.payloadGet(name) and rampart.utils.payloadExtract(destDir
[, name|nameArray]) – which operate
on the zip archive appended to rampart itself rather than on a zip file on disk. See Single-File Bundles.
copyFile¶
Make a copy of a file.
Usage:
rampart.utils.copyFile({src: source, dest: destination [, overwrite: overWrite]});
/* or */
rampart.utils.copyFile(source, destination [, overWrite]);
Where source is a
String, the file to be copied, destination is a String, the name of the target file and optional overWrite is a Boolean which if true will overwrite destination if it exists.
For directory trees, see cp() below.
- Return Value:
-
undefined.
cp¶
Copy a file or, with {recursive: true}, an entire directory tree.
Symbolic links are preserved unless dereference is set.
Usage:
rampart.utils.cp(src, dest [, options]);
Where:
-
srcis a String, the source file or directory. -
destis a String, the destination path. -
optionsis an optional Object:-
recursive– Boolean, defaultfalse. Required whensrcis a directory; throws otherwise. -
dereference– Boolean, defaultfalse. Iftrue, follow symlinks (copy the target’s contents). Iffalse, replicate the link as a link. -
preserveTimestamps– Boolean, defaultfalse. Iftrue, copyatimeandmtimefrom each source entry. -
force– Boolean, defaultfalse. Iftrue, ignore missing-destination errors silently when running witherrorOnExist: true. -
errorOnExist– Boolean, defaultfalse. Iftrue, fail withEEXISTrather than silently overwriting an existing destination file (usesO_EXCLinternally).
-
- Return Value:
-
undefined. Throws on the first error encountered (a partial copy may have already been written).
Example:
/* Single file */
rampart.utils.cp("conf.json", "conf.json.bak");
/* Recursive deep copy */
rampart.utils.cp("/src/proj", "/backup/proj", {
recursive: true,
preserveTimestamps: true
});
rmFile¶
Delete a single file.
Usage:
rampart.utils.rmFile(filename);
Where filename is a
String, the name of the file to be removed.
For removing directory trees, see rm() below.
- Return Value:
-
undefined.
rm¶
Remove a file or, with {recursive: true}, an entire directory tree
(rm -rf semantics). Walks children before parents so directories are empty by
the time they are removed.
Usage:
rampart.utils.rm(path [, options]);
Where:
-
pathis a String, the file or directory to remove. -
optionsis an optional Object:-
recursive– Boolean, defaultfalse. Required whenpathis a non-empty directory. -
force– Boolean, defaultfalse. Iftrue, missing paths are silently ignored (rather than throwingENOENT).
-
- Return Value:
-
undefined.
Example:
rampart.utils.rm("/tmp/build", {recursive: true, force: true});
link¶
Create a hard link.
Usage:
rampart.utils.link({src: sourceName, target: targetName});
/* or */
rampart.utils.link(sourceName, targetName);
Where sourceName is
the existing file and targetName is the name of the to-be-created link.
- Return Value:
-
undefined.
symlink¶
Create a soft (symbolic) link.
Usage:
rampart.utils.symlink({src: sourceName, target: targetName});
/* or */
rampart.utils.symlink(sourceName, targetName);
Where sourceName is
the existing file and targetName is the name of the to-be-created symlink.
- Return Value:
-
undefined.
readLink¶
Read the target path of a symbolic link. The link target string is returned verbatim (it is not resolved to an absolute path – use realPath() for that).
Usage:
var target = rampart.utils.readLink(path);
Where path is a
String, the symlink itself.
- Return Value:
-
String, the link’s target. Throws if
pathdoes not exist or is not a symbolic link (EINVAL).
chmod¶
Change the file mode bits of a file or directory.
Usage:
rampart.utils.chmod(path [, mode]);
Where path is a
String, the file or directory upon which to be operated and
mode is a
Number or String, the octal permissions
mode. Throws error if lacking permissions or if another error was encountered.
Note that mode is
normally given as an octal. As such it can be, e.g., 0755 (octal number) or
"755" (String representation of an octal number), but 755, as a decimal number will
likely not work as intended.
- Return Value:
-
undefined.
realPath¶
Find the canonical form of a file system path. The path or file must exist.
Usage:
rampart.utils.realPath(path);
Where path is a
String, not necessarily in canonical form.
- Return Value:
- A String, the canonical form of the path. Throws an error if path does not exist.
truncate¶
Truncate or extend a regular file to a given size in bytes. Extending a file beyond its current size creates a hole; reading the hole returns NUL bytes.
Usage:
rampart.utils.truncate(path, length);
Where path is a
String and length is a Number (non-negative).
- Return Value:
-
undefined. Throws if the file cannot be opened/modified.
See also truncate (2). For truncating via an open file handle, see fh.ftruncate() in the File Handle Utilities section, or ftruncateFd() in the POSIX File Descriptor I/O section.
touch¶
Create an empty file, or update the access timestamp of an existing file.
Usage:
rampart.utils.touch(file);
/* or */
rampart.utils.touch({
path: file
[, nocreate: noCreate]
[, setaccess: setAccess]
[, setmodify: setModify]
[, reference: referenceFile]
});
Where:
-
fileis a String, the name of the file upon which to operate, -
noCreateis a Boolean (defaultfalse) which, iftruewill only update the timestamp, and will not create a non-existingfile. -
setAccessis a Boolean (defaulttrue), a Date Object, or a Number (seconds since unix epoch). Update access time of the file to specified date or current date iftrue. Do not update iffalse. -
setModifyis a Boolean (defaulttrue), a Date Object, or a Number (seconds since unix epoch). Update modification time of the file to specified date or current date iftrue. Do not update iffalse. -
referenceFileis a String. If specified, the named file’s access and modification timestamps will be used rather than the current time/date.
- Return Value:
-
undefined.
rename¶
Rename or move a file.
Usage:
rampart.utils.rename(source, destination);
Where source is a
String, the file to be renamed or moved, destination is a String, the name of the target file.
- Return Value:
-
undefined.
chown¶
Change the owning user and/or group of a file or directory. Follows symbolic links (the target gets the new ownership); use lchown() to operate on the link itself.
Usage:
rampart.utils.chown(path [, user] [, group]);
/* or */
rampart.utils.chown({path: path [, user: user] [, group: group]});
Where:
-
pathis a String, the file or directory to modify. -
useris a String (account name, looked up viagetpwnam(3)) or a Number (uid). Omit – or pass a negative number in positional form – to leave the user unchanged. -
groupis a String (group name, looked up viagetgrnam(3)) or a Number (gid). Omit to leave the group unchanged.
- Return Value:
-
undefined. Throws if the path does not exist, the named user/ group is unknown, or the caller lacks permission (typically only root may changeuser).
Example:
/* By name */
rampart.utils.chown("/var/log/myapp", "www-data", "adm");
/* By id */
rampart.utils.chown("/srv/data", 1000, 1000);
/* Change group only, leave user alone */
rampart.utils.chown({path: "/srv/data", group: "deploy"});
lchown¶
Change ownership of a symbolic link itself, not the link’s target. Compare to
chmod/chown which follow symlinks.
Useful for backup/restore tools and any code that needs to faithfully reproduce filesystem
state.
Usage:
rampart.utils.lchown(path, user, group);
Where:
-
pathis a String, the symlink to modify. -
userandgroupare each a String (name – looked up viagetpwnam/getgrnam) or a Number (uid/gid). A negative number leaves that side unchanged.
- Return Value:
-
undefined. Throws if the symlink does not exist or the caller lacks permission.
lchmod¶
Change permission bits on a symbolic link itself, where the platform supports it.
Usage:
rampart.utils.lchmod(path, mode);
Where mode follows
the same conventions as chmod() (integer like
0o644 or octal
string like "644").
- Platform notes:
-
- macOS, FreeBSD: changes the symlink’s own mode (uses
lchmod(2)). - Linux: the kernel has no syscall to alter a symlink’s mode bits (and they aren’t
honored anyway). This function throws with an
ENOSYS-style message for actual symlinks, but falls through to a plain chmod() for non-symlink paths, so portable callers don’t have to special-case the not-a-symlink case.
- macOS, FreeBSD: changes the symlink’s own mode (uses
- Return Value:
-
undefined.
lUtimes¶
Set access and modification timestamps on a symbolic link itself. Like touch() but operates on the link rather than its target.
Usage:
rampart.utils.lUtimes(path, atime, mtime);
/* or */
rampart.utils.lUtimes(path, {setaccess: atime, setmodify: mtime});
Where:
-
pathis a String, the symlink to modify. -
atime/mtimeare each a Number (seconds since the unix epoch) or a Date. Omitted timestamps default to the current values on the link.
Internally uses utimensat(…, AT_SYMLINK_NOFOLLOW) on Linux and
lutimes(3)
elsewhere.
- Return Value:
-
undefined.
sleep¶
Pause execution for specified number of seconds.
Usage:
rampart.utils.sleep(seconds);
Where seconds is a
Number. Seconds may be a fraction of seconds. Internally nanosleep is used.
Example:
/* wait 1.5 seconds */
rampart.utils.sleep(1.5);
tmpDir¶
Return the system temporary directory. Honors the standard environment variables TMPDIR, TMP and TEMP in that order; falls back
to /tmp on POSIX
systems. The returned path is not validated to exist – callers should create whatever
subdirectory they need (often via mkdTemp()).
Usage:
var tmp = rampart.utils.tmpDir();
- Return Value:
- String. Trailing slashes are stripped.
homeDir¶
Return the current user’s home directory. Uses the HOME environment variable when
set; otherwise calls getpwuid(geteuid()) to look it up in /etc/passwd.
Usage:
var home = rampart.utils.homeDir();
- Return Value:
- String, the home directory. Throws only if neither lookup succeeds (extremely rare).
getType¶
Get the type of variable. A simplified but more specific version of typeof.
Usage:
var type = rampart.utils.getType(myvar);
- Return Value:
-
A String, one of
String,Array,Number,Function,Boolean,Buffer(any buffer type),Nan,Null,Undefined,Date,Vector,FilehandleorObject(excluding any of the other types of Objects such asNull,Array,Function,VectororFilehandle) .
timezone¶
Retrieve system timezone information.
Usage:
var tz = rampart.utils.timezone([directory]);
Where directory is
an optional directory with timezone information. Default is "/usr/share/zoneinfo".
- Return Value:
-
An Object with the following functions:
findZone(),findAbbr()anddump().
-
tz.findZone(tzname)- Return an Object with timezone information. If the timezone does not exist, returnsundefined. -
tz.findAbbr(abbrname)- Return an Object with a list of timezones that match the given abbreviation. If the abbreviation does not exist, returnsundefined. -
tz.dump()- Return an Object with the entire database organized by timezones and abbreviations.
Example:
var tz = rampart.utils.timezone();
var pstZones = tz.findAbbr("PST");
/* ambiguous => whether there are zones in "entries" with differing offsets
zoneAbbrIndex => where in the "abbreviations" section of the zone info
below "PST" is found
{
"ambiguous": true,
"entries": [
{
"offset": -28800,
"offsetString": "-8:00",
"zoneName": "America/Bahia_Banderas",
"zoneAbbrIndex": 5
},
{
"offset": -28800,
"offsetString": "-8:00",
"zoneName": "America/Boise",
"zoneAbbrIndex": 2
},
...
]
}
*/
var LAZone = tz.findZone("America/Los_Angeles");
/*
{
"name": "America/Los_Angeles",
"abbreviations": [
{
"Abbreviation": "LMT",
"UTCOffset": -28378,
"isDST": false
},
{
"Abbreviation": "PDT",
"UTCOffset": -25200,
"isDST": true
},
{
"Abbreviation": "PST",
"UTCOffset": -28800,
"isDST": false
},
{
"Abbreviation": "PWT",
"UTCOffset": -25200,
"isDST": true
},
{
"Abbreviation": "PPT",
"UTCOffset": -25200,
"isDST": true
},
{
"Abbreviation": "PST",
"UTCOffset": -28800,
"isDST": false
}
],
"transitions": [
{
"transitionDate": "1901-12-13T20:45:52.000Z",
"transition": {
"Abbreviation": "PST",
"UTCOffset": -28800,
"isDST": false
}
},
{
"transitionDate": "1918-03-31T10:00:00.000Z",
"transition": {
"Abbreviation": "PDT",
"UTCOffset": -25200,
"isDST": true
}
},
...
]
}
*/
dateFmt¶
Format a date String.
Usage:
var datestr = rampart.utils.dateFmt(format[, date][, input_format])
Where:
"%Y-%m-%d %H:%M:%S %z"
"%A %B %d %H:%M:%S %Y %z"
"%Y-%m-%d %H:%M:%S"
"%A %B %d %H:%M:%S %Y"
"%Y-%m-%dT%H:%M:%S"
"%c"
- Return Value:
- The formatted date as a String.
Note:
- Millisecond notation in the string in the form of
.123or.123Zis disregarded.- The return String is a date in local time.
- If year or year/month/day formats are missing, the current year or date respectively is assumed.
- If the
%zformat is specified in theinput_formatString, the date will be converted from that timezone offset to local time.- The
%Zformat has no effect on the time zone.
Example:
rampart.globalize(rampart.utils);
var d = new Date();
printf( "%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n",
dateFmt("%c", "Mon Jul 26 12:00:01 2021"),
dateFmt("%c", "Mon Jul 26 12:00:01 2021 -04:00"),
dateFmt("%c", "1999-12-31 23:59:59 -0000"),
dateFmt("%c", "2020", "%Y"),
dateFmt("%c", d),
dateFmt("%Y-%m-%d"),
dateFmt("%m/%d/%Y %H:%M:%S %Z", 946713599),
dateFmt("Today's lunch: %c", "12:15", '%H:%M')
);
/* Expected output:
Mon Jul 26 12:00:01 2021
Mon Jul 26 09:00:01 2021
Fri Dec 31 15:59:59 1999
Wed Jan 1 00:00:00 2020
Tue Jul 27 01:06:57 2021
2021-07-27
12/31/1999 23:59:59 PST
Today's lunch: Tue Jul 27 12:15:00 2021
*/
scanDate¶
Scan a date String and return a JavaScript date.
Usage:
var mydate = rampart.utils.scanDate(dateString[, default_offset][, input_format]);
Where:
- Return Value:
- A JavaScript Date.
autoScanDate¶
Attempt to match a date from a String using various formats.
Usage:
var dateRes = autoScanDate(dateString);
Return Value: An Object.
If no timezone offset or abbreviation is present, the return object has the following properties:
date- a JavaScript Date.offset- timezone offset (in this case0for GMT).endIndex- last character position indateStringof the match.matchedFormat- the format that was successfully matched.If a timezone offset is present, offset will be set to that timezone and and GMT will be returned with the offset set.
If a timezone abbreviation is present and valid, offset will be set to the best matching timezone (as sorted by distance from the system timezone). Also present is
datesfor all the possible timezones which match the abbreviation, filtered by the validity of the Abbreviation (i.e. PST vs PDT) on the given date.If
dateStringcould not be parsed,Nullis returned.
Example:
var dateRes = autoScanDate("Jan 5 03:20 pm 2002");
/*
{
"date": "2002-01-05T15:20:00.000Z",
"offset": 0,
"endIndex": 19,
"matchedFormat": "%b %e %I:%M %p %Y"
}
*/
dateRes=autoScanDate("Jan 5 03:20 pm 2002 -0800");
/*
{
"date": "2002-01-05T23:20:00.000Z",
"offset": -28800,
"endIndex": 25,
"matchedFormat": "%b %e %I:%M %p %Y %z"
}
*/
dateRes=autoScanDate("Jan 5 03:20 pm 2002 PST");
/* "dates" is sorted by distance from current timezone offset
"ambiguous" is true because Manila has a timezone abbv "PST"
"date" is set to the first record in "dates"
{
"ambiguous": true,
"dates": {
"America/Dawson": "2002-01-05T23:20:00.000Z",
"America/Fort_Nelson": "2002-01-05T23:20:00.000Z",
"America/Metlakatla": "2002-01-05T23:20:00.000Z",
"America/Ensenada": "2002-01-05T23:20:00.000Z",
"America/Santa_Isabel": "2002-01-05T23:20:00.000Z",
"America/Tijuana": "2002-01-05T23:20:00.000Z",
"America/Los_Angeles": "2002-01-05T23:20:00.000Z",
...
"Asia/Manila": "2002-01-05T07:20:00.000Z",
"posix/Asia/Manila": "2002-01-05T07:20:00.000Z",
"right/Asia/Manila": "2002-01-05T07:20:00.000Z"
},
"date": "2002-01-05T23:20:00.000Z",
"offset": -28800,
"endIndex": 23,
"matchedFormat": "%b %e %I:%M %p %Y %Z"
}
*/
dateRes=autoScanDate("Aug 5 03:20 pm 2002 PST");
/* note that most timezones that would match PST are observing
PDT in August, so they are excluded.
{
"ambiguous": true,
"dates": {
"America/Metlakatla": "2002-08-05T23:20:00.000Z",
"posix/America/Metlakatla": "2002-08-05T23:20:00.000Z",
"right/America/Metlakatla": "2002-08-05T23:20:00.000Z",
"Asia/Manila": "2002-08-05T07:20:00.000Z",
"posix/Asia/Manila": "2002-08-05T07:20:00.000Z",
"right/Asia/Manila": "2002-08-05T07:20:00.000Z"
},
"date": "2002-08-05T23:20:00.000Z",
"offset": -28800,
"endIndex": 23,
"matchedFormat": "%b %e %I:%M %p %Y %Z"
}
*/
use¶
Shortcut and alternative for importing modules with require.
Usage:
rampart.globalize(rampart.utils);//put utils in the global namespace
var Sql = use.sql; //same as var Sql = require("rampart-sql");
The use Object is a proxy object which uses the property name referenced (here
"sql) and searches
for a module named "rampart-sql". Failing that it will search for a module named ("sql"). It will then call the
require function to import and return that value. If no module can be
found, it will throw an error.
- Return Value:
- The exported module.
load¶
Same as use above except that the property name is also put in the global namespace.
Example:
rampart.globalize(rampart.utils);//put utils in the global namespace
load.curl; //same as global.curl = require("rampart-curl");
var res = curl.fetch("http...");
- Note:
-
The file name of the module must be lowercase, while the variable name may be mixed case.
Example:
load.Sql;is equivalent toglobal.Sql=require("rampart-sql");. - Caveat:
-
This cannot be used to load a module whose name contains illegal JavaScript variable name
characters. Thus,
load["my@mod"]will not work since'@'is not legal in javaScript even though it is legal in a file name. However'-'and'.'characters will be replaced with'_'. Thus,load["rampart-curl.so"]will load the Curl Module and put it in the global namespace similar tovar rampart_curl_so = require("rampart-curl.so").
errorConfig¶
Configure the format of reported errors.
Usage:
rampart.utils.errorConfig(options);
/* or */
rampart.utils.errorConfig(simple, lines);
Where:
-
optionsis an Object with the propertiessimpleandlines. -
simpleis a Boolean (defaultfalse) - whether to reduce the verbosity of the stack trace. -
linesis a Number (default0) - the number of lines of the source code surrounding the error to print. If greater than0and an even number, it will be incremented up to the next odd number.
Examples:
/* default settings */
rampart.utils.errorConfig(false,0);
function myfunc(myvar) {
console.log(myvar.x);
}
myfunc();
/* expected output
TypeError: cannot read property 'x' of undefined
at [anon] (/usr/local/src/rampart/src/duktape/core/duktape.c:60539) internal
at myfunc (myscript.js:4)
at global (myscript.js:7) preventsyield
*/
/* simple stack */
rampart.utils.errorConfig({simple:true,lines:0});
function myfunc(myvar) {
console.log(myvar.x);
}
myfunc();
/* expected output
TypeError: cannot read property 'x' of undefined
at myfunc (myscript.js:4)
at global (myscript.js:7)
*/
/* simple stack and 3 lines */
rampart.utils.errorConfig({simple:true,lines:3});
function myfunc(myvar) {
console.log(myvar.x);
}
myfunc();
/* expected output
TypeError: cannot read property 'x' of undefined
at myfunc (myscript.js:4)
at global (myscript.js:7)
File: myscript.js
line 3: |function myfunc(myvar) {
line 4: -> | console.log(myvar.x);
line 5: |}
*/
deepCopy¶
Make a deep copy of one or more Objects.
Usage:
var target = rampart.utils.deepCopy([appendArrays [, copyBuffers]], target, obj1[, obj2, obj3, ...]);
Where:
appendArrays- a Boolean, whether to append an Array with the same key instead of replace it with the source Array. Default isfalse.copyBuffers- a Boolean, whether to copy the full binary contents of a Buffer rather than its reference. Default istrue.target- an Object into which the subsequent Object parameters will be copied.objn- Source Objects to copy from, with later Objects overwriting duplicate keys in earlier ones.
Example:
var target,
source1 = {
account: {
firstName: "John"
},
links: [
'http://example.com/jsmith1.html'
]
},
source2 = {
account: {
lastName: "Smith"
},
links: [
'http://example.com/jsmith_about.html'
]
};
target = rampart.utils.deepCopy({}, source1, source2);
rampart.utils.printf("%3J\n", target);
/* expected output:
{
"account": {
"firstName": "John",
"lastName": "Smith"
},
"links": [
"http://example.com/jsmith_about.html"
]
}
*/
// true == append the "links" array
target = rampart.utils.deepCopy(true, {}, source1, source2);
rampart.utils.printf("%3J\n", target);
/* expected output:
{
"account": {
"firstName": "John",
"lastName": "Smith"
},
"links": [
"http://example.com/jsmith1.html",
"http://example.com/jsmith_about.html"
]
}
*/
eventCallback¶
Register a callback Function to catch warnings or errors produced by Rampart’s event loop (libevent2).
Usage:
rampart.utils.eventCallback(function(level,msg){ /* handle or report here */ });
Where:
level- a String, one of"msg","warn"or"error".msg- a String, the message from libevent2.
- Note:
- In normal usage, this function should not be necessary. If used, the callback function must not call any asynchronous functions. See the libevent2 reference for more information.
getScopeVars¶
Inspect variables visible at the current call scope. This function can return all variables grouped by scope type, or look up a single variable by name.
Usage:
var scopes = rampart.utils.getScopeVars();
/* or */
var result = rampart.utils.getScopeVars(varname);
Where varname is an
optional String — the name of a single variable to look up.
Mode 1: No arguments — returns an Object with all variables grouped by scope:
var scopes = rampart.utils.getScopeVars();
/* scopes = {
local: { x: 1, y: "hello" },
closure: { outerVar: 42 },
global: { ... }
}
*/
The returned Object has the following properties:
| Property | Type | Description |
|---|---|---|
| local | Object |
Variables declared in the calling function (var declarations and
formal parameters), with current values.
|
| closure | Object | Variables from enclosing function scopes (parent declarative environments). If multiple closure scopes exist, they are merged with inner scopes taking priority. |
| with | Object |
Present only if a with statement scope exists. Contains the with target object.
|
| global | Object | The global object. |
Mode 2: String argument — looks up a single variable by name across all scopes (innermost first), returning an Object describing where it was found:
var result = rampart.utils.getScopeVars("myVar");
/* result = { value: 42, scope: "closure" }
or undefined if not found */
| Property | Type | Description |
|---|---|---|
| value | any | The current value of the variable. |
| scope | String |
The scope in which the variable was found: "local", "closure", "with", or "global".
|
- Return Value:
-
Object or
undefined. In Mode 1, always returns an Object. In Mode 2, returns an Object if the variable was found, orundefinedif it was not found in any scope.
Example:
rampart.globalize(rampart.utils);
var globalVar = "gval";
function outer() {
var x = 10;
function inner() {
var y = 20;
/* inspect all scopes */
var scopes = getScopeVars();
printf("local y = %d\n", scopes.local.y); // 20
printf("closure x = %d\n", scopes.closure.x); // 10
/* look up a single variable */
var info = getScopeVars("x");
printf("x = %d (from %s scope)\n", info.value, info.scope);
// x = 10 (from closure scope)
var missing = getScopeVars("noSuchVar");
printf("missing = %s\n", typeof missing); // undefined
}
inner();
}
outer();
collapse() — The Object returned by getScopeVars() (Mode 1) has a
collapse() method
that merges all scopes into a single flat Object. Scopes are applied
outermost-first (global, then with, then closure, then local), so inner scopes shadow outer
ones — matching JavaScript’s actual variable resolution order.
Variables added via rampart.localize() are included in the local scope.
rampart.globalize(rampart.utils);
var globalVar = "gval";
function outer() {
var x = 10;
function inner() {
var y = 20;
var scopes = getScopeVars();
var all = scopes.collapse();
printf("y = %d\n", all.y); // 20 (local)
printf("x = %d\n", all.x); // 10 (closure)
printf("globalVar = %s\n", all.globalVar); // "gval" (global)
/* local shadows global */
var rampart = "shadowed";
all = getScopeVars().collapse();
printf("rampart = %s\n", all.rampart); // "shadowed"
}
inner();
}
outer();
- Return Value:
-
Object. A flat Object with
{name: value}entries for every variable visible at the point of thegetScopeVars()call.
repl¶
Create an interactive line editor backed by the same line-editing engine used by the built-in Rampart REPL. Provides prompt, history, and multi-line editing (Ctrl-X toggle).
Usage:
var r = rampart.utils.repl(options);
/* or */
var r = rampart.utils.repl(prompt);
Where options is an
Object with the following optional keys (or prompt is a String shortcut equivalent to passing {prompt: prompt}):
| Argument | Type | Description |
|---|---|---|
| prompt | String |
Text drawn before each input line. Default is "".
|
| history | Number |
Maximum number of history entries kept in memory. Default is 1024.
|
| historyFile | String |
Path to a history file. If the file exists, its contents are loaded into history
(appended to anything already in memory) when repl() is called. The file
is written after every successful line returned by .next(). If the file does
not yet exist it is created on first save.
|
| redrawOnResume | Boolean |
If true
(default), on Ctrl-Z resume the screen content visible just before suspend is restored by
replaying a captured copy of everything the REPL had written to stdout. If false, only the prompt and
current edit line are redrawn at the cursor’s current row (the behavior prior to the
capture-and-replay feature being added).
|
| objectMode | Boolean |
If true,
.next()
returns an Object with {text, status[, signal]} instead of the legacy
String / null / false return values. Required to distinguish a wake (see rampart.utils.repl.interrupt() below) from a Ctrl-C cancel. Default
false for
backwards compatibility.
|
- Return Value:
- Object. A handle with the following methods:
| Method | Description |
|---|---|
| next() |
Block, draw the prompt, and return the next line typed by the user.
Legacy mode (default —
objectMode (when
In both modes, Ctrl-C pressed while a line has content is handled internally:
linenoise prints |
| refresh() |
Redraw the current prompt and edit buffer at the cursor’s current position. Use this
after any output has been written to the terminal while
Safe to call from a different thread than the one in |
| close() | Restore terminal modes and drop the handle’s methods. Call when you no longer plan to use this repl. |
Module-level methods (called on the rampart.utils.repl Function itself, not on an
instance):
| Method | Description |
|---|---|
| getHistory() | Return the current in-memory history as an Array of Strings, oldest first. |
| replaceHistory(arr) |
Replace the in-memory history with arr (an Array of Strings). Existing entries are
discarded.
|
| appendHistory(arr) |
Append the contents of arr (an Array of Strings) to the end of the in-memory history without clearing existing
entries.
|
| refresh() |
Same as the instance refresh() method, but callable without holding a handle to the repl.
Useful from worker threads or library code that does not have access to the repl object
created by main.
|
| interrupt([payload]) |
Wake any in-flight
Safe to call from any thread. If no
In legacy (non-objectMode) |
- Note:
-
linenoise’s history is process-global.
getHistory,replaceHistoryandappendHistoryoperate on that single global buffer regardless of whichrepl()instance is active. They share the same buffer with the built-in Rampart REPL if rampart is started interactively.
Example (legacy mode):
/* Echo lines; reload history from disk, then prepend a seed at the
* start of each session so the user has a few commands to up-arrow
* to as separators. The file accumulates every line typed across
* sessions. */
var r = rampart.utils.repl({
prompt: "echo> ",
historyFile: "/tmp/echo.hist"
});
rampart.utils.repl.appendHistory([
"/* new session */",
"help",
"quit"
]);
while (true) {
var line = r.next();
if (line === null) break; /* Ctrl-D / EOF */
if (line === false) { /* Ctrl-C at empty prompt */
rampart.utils.printf("(ignored — use Ctrl-D to exit)\n");
continue;
}
rampart.utils.printf("you said: %s\n", line);
}
r.close();
rampart.utils.printf("history: %J\n", rampart.utils.repl.getHistory());
Example (objectMode with interrupt()):
/* Echo lines on the main thread while a worker thread fires an
* approval prompt every 5 seconds. The wake interrupts the
* .next() read; the caller routes on the `signal` field, asks
* the user a single-key question with getchar(1), and resumes
* the REPL — all without ever yielding the linenoise instance
* to another reader. */
rampart.globalize(rampart.utils);
function workerMain() {
rampart.globalize(rampart.utils);
while (true) {
sleep(5);
rampart.utils.repl.interrupt('approve');
}
}
var w = new rampart.thread();
w.exec(workerMain, null, function(){});
var r = repl({prompt: "echo> ", objectMode: true});
while (true) {
var res = r.next();
if (res.status === 'eof') break;
if (res.status === 'cancel') { printf("(Ctrl-D to exit)\n"); continue; }
if (res.status === 'wake') {
if (res.signal === 'approve') {
printf("[approval] allow? [y/n]: ");
fflush({stream: "stdout"});
var ch = (getchar(1) || '').toLowerCase();
printf("%s\n", ch);
printf(ch === 'y' ? "[approved]\n" : "[denied]\n");
}
continue;
}
/* status === 'ok' */
printf("you said: %s\n", res.text);
}
r.close();
- Keybindings:
-
The same keys as the built-in REPL are honored:
Key Action Up / Down arrow Scroll through history. Ctrl-A Move to beginning of line. Ctrl-C If line is empty: .next()returns false (legacy) or{status: 'cancel'}(objectMode). The caller decides whether to treat this as cancel, exit, or both (e.g. on second press).Ctrl-C If line is not empty: clear the line buffer and redraw a fresh prompt on the next row. .next()does not return and keeps reading.Ctrl-D Quit (if line is empty) — .next()returns null (legacy) or{status: 'eof'}(objectMode).Ctrl-D Delete to right (if line is not empty). Ctrl-D Submit line (if in multi-line mode). Ctrl-E Move to the end of line. Ctrl-K Delete from current to the end of line. Ctrl-L Clear and refresh screen. Ctrl-T Swap current character with previous. Ctrl-U Delete current line. Ctrl-W Delete previous word. Ctrl-X Toggle multi-line editing mode (prompt color changes while it is on). Ctrl-Z Suspend and drop to shell.
File Handle Utilities¶
The functions fprintf (), fseek(), rewind(), ftell(), fflush(), fread(), fgets(), fwrite(), and readLine() take a filehandle, which may be obtained using fopen() or fopenBuffer().
In addition, every handle returned by fopen()
carries the methods fh.fstat(), fh.fsync(), fh.fdatasync(), fh.ftruncate(), fh.fchmod(), fh.fchown(),
fh.fUtimes(), and fh.fileNo() – described in the Handle
stat/sync/truncate/chmod/chown/utimes subsection near the end of this section. For raw
integer-fd I/O (with O_EXCL, pread/pwrite, fsync-style durability and event-loop integration), see the separate
POSIX File Descriptor I/O
section that follows.
- Calling Methods:
-
The above listed functions (functions which take filehandles) may be called using one of two alternative syntaxes.
var handle = rampart.utils.fopen(filename, mode); rampart.utils.fprintf(handle, fmt, ...); /* or */ handle.fprintf(fmt, ...);
The return value for each of the file handle functions is the same for either syntax, with the exception that fseek(), rewind() and fflush() return undefined in the first syntax and
handlein the second.Below, only the first syntax is documented.
- Pre-opened file handles:
-
- rampart.utils.stdin:
- A handle that corresponds to the UNIX standard in stream.
- rampart.utils.stdout:
- A handle that corresponds to the UNIX standard out stream.
- rampart.utils.stderr:
- A handle that corresponds to the Unix standard error stream.
- rampart.utils.accessLog:
-
A handle that corresponds to the
accessLogfile option inserver.start()for therampart-servermodule. If not specified, or not loaded, same asrampart.utils.stdout. - rampart.utils.errorLog:
-
A handle that corresponds to the
errorLogfile option inserver.start()for therampart-servermodule. If not specified, or not loaded, same asrampart.utils.stderr.
The
rampart.utils.stdinhandle includes in its properties the fread(), fgets() and readLine() functions while the other four include the fprintf(), fflush() and fwrite() functions. Example:var line, inf = rampart.utils.stdin.readLine(); while ( line = inf.next() ) rampart.utils.stdout.fprintf("%s", line); //same as rampart.utils.printf
fopen¶
Open a filehandle for use with fprintf(), fclose(), fseek(), rewind(), ftell(), fflush() fread(), fgets(), fwrite() and readLine().
- Return Value:
- Object. An object which opaquely contains the opened file handle along with the above functions.
Usage:
var handle = rampart.utils.fopen(filename, mode[, stdRedir]);
Where filename is a
String containing the file to be opened.
Where mode is a
String (one of the following):
-
"r"- Open text file for reading. The stream is positioned at the beginning of the file. -
"r+"- Open for reading and writing. The stream is positioned at the beginning of the file. -
"w"- Truncate file to zero length or create text file for writing. The stream is positioned at the beginning of the file. -
"w+"- Open for reading and writing. The file is created if it does not exist, otherwise it is truncated. The stream is positioned at the beginning of the file. -
"a"- Open for appending (writing at end of file). The file is created if it does not exist. The stream is positioned at the end of the file. -
"a+"- Open for reading and appending (writing at end of file). The file is created if it does not exist. The initial file position for reading is at the beginning of the file, but output is always appended to the end of the file.
Where optional stdRedir is one of rampart.utils.stdin, rampart.utils.stdout or
rampart.utils.stderr
and the mode is set appropriately ("r" for stdin, "w" or a for stdout/stderr; no "+" allowed). Any data read or
written to one of the std filehandles will be redirected to the newly opened file. When the
filehandle is closed, the std filehandle will be restored to its previous value.
fopenBuffer¶
Open a filehandle that writes to a dynamically sized opaque buffer for use with fprintf(), fclose(), fseek(), rewind(), ftell(), fflush() fread(), fgets(), fwrite() and readLine().
- Return Value:
- Object. An object which opaquely contains the opened file handle along with the above functions.
Usage:
var handle = rampart.utils.fopenBuffer([chunkSize][, stdRedir]);
Where chunkSize is a
Number (default is 4096), amount of memory to
allocate each time the buffer is resized. When the filehandle is closed, the buffer will be
sized to fit the data written, if necessary.
Where optional stdRedir is one of rampart.utils.stdout or rampart.utils.stderr. Any data
written to one of the std filehandles will be redirected to the newly opened filehandle and
placed in the buffer. When the filehandle is closed, the std filehandle will be restored
to its previous value.
- Return Value:
-
Object. An object which opaquely contains the opened file handle
along with the same functions as in
fopen()above, as well asdestroy(),getBuffer()andgetString()functions, which will delete the backing data or copy the backing data and return the corresponding JavaScript type. - Note:
-
Calling
fclose()will close the file handle, but the backing buffer is still available for use withgetBuffer()andgetString(). Callingdestroy()will close the file handle if still open and delete the backing buffer. There is no finalizer on the returned object, so it is important to calldestroy()when it is no longer needed. Also note that thefopenBuffer()return object can be used in several threads at the same time, so long as it hasn’t been destroyed in any thread. Attempting to use a destroyedfopenBuffer()object will throw an error.
Example:
rampart.globalize(rampart.utils);
var fh = fopenBuffer(stdout);
// prints to buffer
printf("line 1\n");
// also prints to buffer
console.log("line 2");
//stdout restored after close
fclose(fh); // or fh.fclose()
printf("file handle closed\n");
// this goes to the terminal like expected
printf("%s", fh.getString() );
// manual cleanup is necessary
fh.destroy();
/* expected output"
file handle closed
line 1
line 2
*/
fclose¶
Close a previously opened handle Object opened with fopen() or fopenBuffer().
Example:
var handle = rampart.utils.fopen("/tmp/out.txt", "a");
...
rampart.utils.fclose(handle);
/* or */
handle.fclose();
- Return Value:
-
undefined.
fprintf¶
Same as printf() except output is sent to the file provided by a String or filehandle Object opened and returned from fopen().
Usage:
var filename = "/home/user/myfile.txt";
var output = rampart.utils.fopen(filename, mode);
rampart.utils.fprintf(output, fmt, ...);
rampart.utils.fclose(output);
/* or */
var output = filename;
var outputLen = rampart.utils.fprintf(output, [, append], fmt, ...);
/* file is automatically closed after function returns */
Where:
-
outputmay be a String (a file name), or an Object returned from fopen(). -
fmtis a String, a printf() format. -
appendis an optional Boolean only used when output is a filename- iftruethe file will be appended instead of overwritten.
- Return Value:
- A Number. The length in bytes of the printed string.
Example:
rampart.globalize(rampart.utils);
var handle = fopen("/tmp/out.txt", "w+");
fprintf(handle, "A number: %d\n", 123);
fclose(handle);
/* OR */
fprintf("/tmp/out.txt", "A number: %d\n", 123); /* implicit fclose */
fseek¶
Set file position for file operations.
Usage:
rampart.utils.fseek(handle, offset[, whence]);
| Argument | Type | Description |
|---|---|---|
| handle | Object | A handle opened with fopen() |
| offset | Number | offset in bytes from whence |
| whence | String | “seek_set” - measure offset from start of file (default) |
| “seek_cur” - measure offset from current position | ||
| “seek_end” - measure offset from end of file. |
- Return Value:
-
undefined
Example
rampart.globalize(rampart.utils,
["fopen","printf","fprintf","fseek","fread"]);
var handle = fopen("/tmp/out.txt", "w+");
fprintf(handle, "123def");
fseek(handle, 0, "seek_set");
fprintf(handle, "abc");
fseek(handle, 0, "seek_set");
var out=fread(handle);
printf("'%s'\n", out);
/*
expect output:
'abcdef'
*/
fclose(handle);
rewind¶
Set the file position to the beginning of the file. It is equivalent to:
rampart.utils.fseek(handle, 0, "seek_set")
Usage:
rampart.utils.rewind(handle);
- Return Value:
-
undefined
ftell¶
Obtain the current value of the file position for the handle opened with fopen().
Usage:
var pos = rampart.utils.ftell(handle);
- Return Value:
-
Number. Current position of
handle.
fflush¶
For output file handles opened with fopen(), or
for stdout/stderr/accessLog/errorLog, fflush() forces a write of buffered data.
Usage:
rampart.utils.fflush(handle);
- Return Value:
-
undefined
Example:
/* normally a flush happens automatically
when a '\n' is printed. Since we are using
'\r', flush manually */
for (var i=0; i< 10; i++) {
rampart.utils.printf("doing #%d\r", i);
rampart.utils.fflush(rampart.utils.stdout);
rampart.utils.sleep(1);
}
rampart.utils.printf("blast off!!!\n");
fread¶
Read data from a file, handle opened with fopen() or the pre-opened handle stdin.
Usage:
var data = rampart.utils.fread([handle|file] [, max_size [, chunk_size [,returnString]]]);
| Argument | Type | Description |
|---|---|---|
| handle | Object | A handle opened with fopen() |
| file | String | A filename – file will be auto opened and closed |
| max_size | Number | Maximum number of bytes to read. Unlimited if not specified. |
| chunk_size | Number | Initial size of return Buffer and number of bytes to read at a time. If the total number of bytes read is greater, the buffer grows as needed. If total bytes read is less, the returned buffer will be reduced in size to match. Default is 4096 if not specified. |
| returnString | Boolean |
Whether return value is returned as a String. Default is
false.
|
- Return Value:
-
A Buffer or a String if
returnStringistrue.
fgets¶
Usage:
var data = rampart.utils.fgets([handle|file] [, options[, max_size]]);
Read data from file, up to max_size bytes (default 1), stopping at and including
the first \n or the
end of the file.
If options is
included, it must be an Object, where if set to {"echo":false}, and reading from
stdin, echoing typed
characters on the terminal will be disabled (e.g., for entering passwords).
- Return Value:
- A String.
fwrite¶
Write data to a file, a handle opened with fopen() or a pre-opened output handle (stdout/stderr/accessLog/errorLog). If using a handle,
the start of the write will be the current position based on how the file was opened and
whether any seeks have been performed. If using a file name, the append parameter will determine
whether the file is appended or truncated.
Usage:
var nbytes = rampart.utils.fwrite([handle|file], data [, max_bytes][, append]);
| Argument | Type | Description |
|---|---|---|
| handle | Object | A handle opened with fopen() |
| file | String | A filename – file will be auto opened and closed |
| data | Buffer/ String | The data to be written. |
| max_bytes | Number | Maximum number of bytes to write. Buffer/ String length if not specified. |
| append | Boolean |
If opened with file instead of handle, whether to append
the file. Default is false, in which case the file will be truncated.
|
- Return Value:
- A Number. Number of bytes written.
readLine¶
Read a text file line-by-line.
Usage:
var rl = rampart.utils.readLine(file);
var line = rl.next();
Where file is a
String (name of file to be read) or a file handle opened with
fopen() or rampart.utils.stdin. It returns
a Object that contains the property next which is Function to retrieve and return the next line of text in the opened file.
- Return Value:
-
An Object. Property
nextof the return Object is a Function which retrieves and returns the next line of text in the file. After the last line offileis returned, subsequent calls tonextwill returnnull.
Example:
var rl = rampart.utils.readLine("./myfile.txt");
var i = 0;
var line, firstline, lastline;
while ( (line=rl.next()) ) {
if(i==0)
firstline = rampart.utils.trim(line);
i++;
lastline = line;
}
rampart.utils.printf("%s\n%s\n", firstline, lastline);
/* expected output: first and last line of file "./myfile.txt" */
Handle stat/sync/truncate/chmod/chown/utimes¶
The following methods are attached to every handle returned by fopen(). They operate on the open file via its underlying file descriptor and
are the buffered-stdio counterpart to the raw fd-keyed functions in the next section. Each method
is invoked as handle.METHOD(args).
fh.fstat¶
Return file status for the open handle. Equivalent to calling stat() on the path the handle was opened with, but works on the underlying file descriptor – useful when the file may have been renamed or unlinked after opening.
Usage:
var st = handle.fstat();
- Return Value:
- Object, same shape as stat().
fh.fsync¶
Flush stdio buffers and then call fsync(2) on the underlying file descriptor, blocking until all modified
data and metadata are written to durable storage. Required by the atomic write/rename/fsync
pattern.
Usage:
handle.fsync();
- Return Value:
-
undefined. Throws on I/O error.
fh.fdatasync¶
Like fh.fsync but only flushes file data
(not metadata that doesn’t affect future reads, such as access times). On macOS, falls back to
fsync because the
platform lacks fdatasync.
Usage:
handle.fdatasync();
- Return Value:
-
undefined.
fh.ftruncate¶
Truncate or extend the open file to length bytes. Stdio buffers are flushed first.
Usage:
handle.ftruncate(length);
Where length is a
non-negative Number.
- Return Value:
-
undefined.
See also truncate() for the path-based equivalent.
fh.fchmod¶
Change the file mode bits on the open handle. Same mode semantics as chmod() – accepts a Number or octal String.
Usage:
handle.fchmod(mode);
- Return Value:
-
undefined.
fh.fchown¶
Change the owning user and/or group on the open handle. Either argument may be a numeric id or a name string. Negative numbers leave that side unchanged.
Usage:
handle.fchown(user, group);
- Return Value:
-
undefined.
fh.fUtimes¶
Set access and modification timestamps on the open handle. Accepts either positional
(atime, mtime) arguments, where each is a Number
(seconds since epoch) or Date, or an options object matching
touch()’s style.
Usage:
handle.fUtimes(atime, mtime);
/* or */
handle.fUtimes({setaccess: atime, setmodify: mtime});
- Return Value:
-
undefined.
fh.fileNo¶
Return the integer file descriptor backing the handle, for use with the fd-keyed functions in
the next section, or with system calls that take a fd argument.
Usage:
var fd = handle.fileNo();
- Return Value:
-
Number.
-1if the handle is not backed by a real fd (rare; happens for fopenBuffer() handles).
POSIX File Descriptor I/O¶
The functions in this section operate on raw POSIX integer file descriptors rather than stdio handles. They expose primitives that the buffered fopen() interface cannot:
- Atomic create-or-fail via
O_EXCL(lock files, atomic temp files without TOCTOU races). - Positional I/O (pread/pwrite equivalents) for safe multi-threaded access to a single file.
- Direct durability primitives (fsyncFd(), fdatasyncFd()).
- Non-blocking I/O on FIFOs/sockets/pipes via
O_NONBLOCK. - Integration with the rampart event loop (libevent
event_newtakes an integer fd). - The classic “write to tmp, fsync, rename, fsync(dir)” atomic-write pattern for safe state-saving.
For text-oriented buffered reading/writing, fopen() remains the better choice. Use these when you need durability, atomicity, non-blocking semantics, or event-loop integration.
Open flag constants (rampart.utils.O)¶
The rampart.utils.O
object holds integer constants for the flags parameter of open().
Names mirror the POSIX <fcntl.h> macros with the O_ prefix dropped – O_RDONLY is rampart.utils.O.RDONLY, and so
on. The short namespace keeps call sites readable when several flags are OR’d together (typical
usage is u.O.WRONLY
| u.O.CREAT |
u.O.EXCL).
Combine with bitwise OR. Platform-specific constants are only present when supported by the host.
| Constant | Meaning |
|---|---|
RDONLY
|
Open for reading only. |
WRONLY
|
Open for writing only. |
RDWR
|
Open for reading and writing. |
CREAT
|
Create the file if it does not exist. |
EXCL
|
With CREAT,
fail if the file already exists (atomic create).
|
TRUNC
|
If the file exists, truncate to zero length on open. |
APPEND
|
All writes are appended to the end of the file. |
NONBLOCK
|
Open in non-blocking mode (matters for FIFOs/sockets). |
CLOEXEC
|
Close the descriptor on exec(3) – avoids leaking fds into children.
|
NOFOLLOW
|
Refuse to open if the final path component is a symbolic link. |
SYNC
|
Each write
blocks until data + metadata reach durable storage.
|
DSYNC
|
Each write
blocks until data (not metadata) reaches durable storage.
|
DIRECTORY
|
Fail unless the path resolves to a directory (when supported). |
NOCTTY
|
Do not let an opened terminal device become the controlling tty. |
DIRECT
|
(Linux only) Bypass the page cache. |
NOATIME
|
(Linux only) Do not update atime on read.
|
SEEK_SET
|
lseek whence:
from start of file (also 0).
|
SEEK_CUR
|
lseek whence:
from current position (also 1).
|
SEEK_END
|
lseek whence:
from end of file (also 2).
|
open¶
Open a file by path, returning an integer file descriptor. Equivalent to open (2).
Usage:
var fd = rampart.utils.open(path, flags [, mode]);
/* or */
var fd = rampart.utils.open({path: path, flags: flags [, mode: mode]});
Where:
-
pathis a String. -
flagsis an integer bitmask built from the Open flag constants (rampart.utils.O). -
modeis an optional Number or octal String – permissions applied whenO.CREATis set and the file is newly created. Defaults to0644. Modified by the process umask.
- Return Value:
- Number, the integer file descriptor. Throws on failure.
Example:
var O = rampart.utils.O;
/* Atomic create-or-fail (classic lock file pattern) */
var fd = rampart.utils.open("/var/run/myapp.lock",
O.WRONLY|O.CREAT|O.EXCL|O.CLOEXEC, 0o600);
read¶
Read bytes from an open file descriptor. Performs a single read(2) syscall (or pread when position is given) and returns
whatever bytes were obtained – which may be fewer than length.
Usage:
var buf = rampart.utils.read(fd, length [, position]);
Where:
-
fdis the integer file descriptor. -
lengthis a Number, the maximum number of bytes to read. -
positionis an optional Number. If supplied,preadis used and the descriptor’s offset is NOT advanced. Useful for multi-threaded random-access reads of one open file.
- Return Value:
-
Buffer. Will be zero-length if EOF has been reached at the read
position; will be shorter than
lengthif the kernel returned a short read.
write¶
Write bytes to an open file descriptor. Performs a single write(2) syscall (or
pwrite when
position is given)
and returns the number of bytes accepted – which may be fewer than the input length on a short
write.
Usage:
var n = rampart.utils.write(fd, data [, position]);
Where:
-
fdis the integer file descriptor. -
datais a String or Buffer. -
positionis an optional Number. If supplied,pwriteis used and the descriptor’s offset is NOT advanced.
- Return Value:
- Number, bytes written. Callers performing large writes should loop until all bytes are accounted for.
lseek¶
Reposition the file offset of an open file descriptor.
Usage:
var pos = rampart.utils.lseek(fd, offset [, whence]);
Where:
-
offsetis a Number, signed byte offset. -
whenceis an optional String ("SEEK_SET","SEEK_CUR","SEEK_END") or the equivalent integer (0/1/2; also exposed asrampart.utils.O.SEEK_SETetc. – see Open flag constants (rampart.utils.O)). Defaults to"SEEK_SET".
- Return Value:
- Number, the new file offset.
fstatFd¶
Return file status for an open integer file descriptor.
Usage:
var st = rampart.utils.fstatFd(fd);
- Return Value:
- Object, same shape as stat().
fsyncFd¶
Call fsync(2) on the
descriptor. Blocks until both data and metadata reach durable storage.
Usage:
rampart.utils.fsyncFd(fd);
fdatasyncFd¶
Like fsyncFd but only flushes data (not
metadata). On macOS, falls back to fsync because the platform lacks fdatasync.
Usage:
rampart.utils.fdatasyncFd(fd);
ftruncateFd¶
Truncate or extend the file referenced by fd to length bytes.
Usage:
rampart.utils.ftruncateFd(fd, length);
fchmodFd¶
Change permission bits on the open file descriptor. Mode argument has the same shape as chmod().
Usage:
rampart.utils.fchmodFd(fd, mode);
fchownFd¶
Change owner and/or group on the open file descriptor. Either argument may be a name String or a numeric id; negative numbers leave that side unchanged.
Usage:
rampart.utils.fchownFd(fd, user, group);
futimesFd¶
Set access and modification timestamps on the open file descriptor. Accepts either positional
(atime, mtime) arguments or an options object identical to fh.fUtimes()’s.
Usage:
rampart.utils.futimesFd(fd, atime, mtime);
/* or */
rampart.utils.futimesFd(fd, {setaccess: atime, setmodify: mtime});
Example: durable atomic write¶
The “write to tmp, fsync, rename” pattern – needed whenever a partial write would corrupt
important state – requires open() with
O.EXCL for the
lock-free create and fsyncFd() for the
durability barrier. Neither is available through fopen().
var u = rampart.utils, O = u.O;
function atomicWrite(path, data) {
var tmp = path + ".tmp." + process.pid;
var fd = u.open(tmp, O.WRONLY|O.CREAT|O.EXCL|O.TRUNC, 0o644);
try {
/* Loop until all bytes are written -- write() may return short. */
var off = 0, total = data.length;
while (off < total) {
off += u.write(fd, data.slice ? data.slice(off) : data);
}
u.fsyncFd(fd); /* the data is now durable */
} finally {
u.close(fd);
}
u.rename(tmp, path); /* atomic on POSIX -- old or new, never partial */
}
atomicWrite("/etc/myapp/state.json", JSON.stringify({n: 42}));
File Watching¶
Watch a file or directory for changes and invoke a JavaScript Function when something happens. On Linux, the kernel’s inotify (7) interface is wired into rampart’s libevent loop – events arrive synchronously without polling overhead. Other platforms automatically fall back to a polling backend that stats the path at a configurable interval.
Watchers integrate into the same event loop that drives setTimeout,
setInterval, the forkpty
pseudo-terminal, and (when used) rampart-server – so callbacks fire on the current thread alongside other
JavaScript work without blocking it.
watch¶
Begin watching a path and return a watcher object.
Usage:
var w = rampart.utils.watch(path, callback);
/* or */
var w = rampart.utils.watch(path, options, callback);
/* or */
var w = rampart.utils.watch(options, callback);
Where:
-
pathis a String, the file or directory to watch. -
callbackis a Functioncallback(event)invoked for each filesystem event. Returningfalsefrom the callback closes the watcher. -
optionsis an optional Object:-
path– String, only meaningful when the path is being supplied via the options object instead of as a positional argument. -
poll– Boolean, defaultfalse. Iftrue, force the polling backend even on Linux. Useful for files on filesystems where inotify is unreliable (NFS, some FUSE mounts). -
interval– Number, default1000. Polling interval in milliseconds. Ignored under inotify.
-
The event
Object passed to the callback has the following properties:
| Property | Description |
|---|---|
type
|
String: "change", "create", "delete", or "rename".
|
path
|
String: full path of the entry that changed. For a directory watch, this is the path of the affected child (under inotify; the polling backend reports the watched path itself). |
isDir
|
Boolean: true if the entry is a
directory.
|
- Return Value:
-
Object, the watcher. Properties:
-
path– String, the watched path. -
backend– String,"inotify"or"polling". -
close()– Function, stop watching (idempotent).
-
Example:
/* Live-reload a config file */
var w = rampart.utils.watch("/etc/myapp/config.json", function(ev) {
if (ev.type === "change" || ev.type === "create")
reloadConfig();
});
/* Stop watching after the first event */
var w2 = rampart.utils.watch("/tmp/marker", function(ev) {
console.log("first event:", ev.type);
return false; /* equivalent to w2.close() */
});
/* Force the polling backend with a custom interval */
var w3 = rampart.utils.watch({path: "/mnt/nfs/file", poll: true, interval: 500},
function(ev) { ... });
Limitations¶
- No recursive watching. Only the named path is watched; for a directory, only its immediate contents trigger events. Recursion can be implemented in user code by walking the tree (walkDir()) and installing a watcher per directory.
- No native kqueue backend. On macOS and the BSDs, the polling backend is used.
- No event debouncing. Bursts of rapid changes produce a burst of callbacks; the caller should debounce in JavaScript if needed.
-
Polling fidelity. The polling backend compares
mtime,sizeandinodebetween ticks; changes that leave all three identical (e.g. an in-place write of identical-size content within the same wall-clock second) will be missed.
Compression and Checksums¶
One-shot DEFLATE-family compression and decompression via the libdeflate library, plus the two checksums it provides (CRC-32 and Adler-32). All functions are synchronous and throw on error; no streaming API is exposed (libdeflate is one-shot only – pass the full input as a single String or Buffer).
For node-style asynchronous variants, plus the legacy stream classes (zlib.Deflate, zlib.Gzip, etc.), see require(‘zlib’) in the nodeshim docs. The synchronous functions below
are the implementation those wrappers delegate to.
gzip¶
Compress data into the gzip container format (RFC 1952).
Usage:
var compressed = rampart.utils.gzip(data [, level]);
Where:
-
datais a String or Buffer. -
levelis an optional Number – compression level from1(fastest) to12(best ratio). Defaults to6. Values outside the range are clamped.
- Return Value:
- Buffer – the gzip-compressed bytes (including the gzip header and footer).
Example:
var u = rampart.utils;
var bytes = u.gzip("Hello, World!");
u.writeFile("hello.gz", bytes);
gunzip¶
Decompress gzip-format data.
Usage:
var raw = rampart.utils.gunzip(data);
Where data is a
String or Buffer containing gzip data
(must start with the magic bytes 0x1F 0x8B).
- Return Value:
- Buffer – the decompressed bytes.
- Throws:
-
-
"bad compressed data"if the input is not valid gzip. - If the decompressed output would exceed 256 MB (zip-bomb guard); compose your own loop using inflate() if you genuinely need larger output.
-
deflate¶
Compress data into the zlib container format (RFC 1950 – a deflate stream wrapped with a 2-byte header and a trailing Adler-32 checksum).
Usage:
var compressed = rampart.utils.deflate(data [, level]);
Where data and
level are as for
gzip() above.
- Return Value:
- Buffer – the zlib-wrapped compressed bytes.
inflate¶
Decompress zlib-format data.
Usage:
var raw = rampart.utils.inflate(data);
Where data is a
String or Buffer containing zlib data.
- Return Value:
- Buffer – the decompressed bytes.
Throws if the input is not valid zlib data or if the decompressed output would exceed 256 MB.
deflateRaw¶
Compress data into raw DEFLATE format (RFC 1951 – no header, no footer, no checksum). Useful when an outer protocol already provides framing and integrity checks (e.g., PNG’s IDAT, ZIP file entries).
Usage:
var compressed = rampart.utils.deflateRaw(data [, level]);
Where data and
level are as for
gzip().
- Return Value:
- Buffer – the raw deflate bytes.
inflateRaw¶
Decompress raw DEFLATE-format data.
Usage:
var raw = rampart.utils.inflateRaw(data);
Where data is a
String or Buffer containing raw deflate
data.
- Return Value:
- Buffer – the decompressed bytes.
Throws on bad data or >256 MB output.
crc32¶
Compute the CRC-32 checksum (IEEE 802.3 polynomial – the same used by gzip and ZIP).
Usage:
var sum = rampart.utils.crc32(data [, seed]);
Where:
-
datais a String or Buffer. -
seedis an optional Number, the initial CRC-32 state. Defaults to0. Pass a previous CRC-32 value here to extend the checksum across multiple chunks of input.
- Return Value:
- Number – the 32-bit unsigned CRC.
Example:
var u = rampart.utils;
u.crc32("hello"); // -> 0x3610A686
/* incremental over two chunks */
var c = u.crc32("hel");
c = u.crc32("lo", c);
/* c === u.crc32("hello") */
adler32¶
Compute the Adler-32 checksum (RFC 1950 – the checksum used inside the zlib container). Faster than CRC-32 but with weaker collision resistance; appropriate for accidental-corruption detection, not for cryptographic integrity.
Usage:
var sum = rampart.utils.adler32(data [, seed]);
Where:
-
datais a String or Buffer. -
seedis an optional Number, the initial state. Defaults to1(the standard Adler-32 starting value – not0). Pass a previous Adler-32 value here to extend across chunks.
- Return Value:
- Number – the 32-bit unsigned Adler-32.
Rand, Hash and HyperLogLog¶
Included in rampart.utils are several non-cryptographic functions which have been optimized for speed and ease of use.
Note that the rand() and hash() functions are not of cryptographic quality. For cryptographic quality hashes and random numbers, see The Rampart-Crypto Module.
rand¶
Generate a random number using a fast, non-cryptographic random number generator.
Usage:
var rn = rampart.utils.rand([min, max]);
/* or */
var rn = rampart.utils.rand(max);
Where min is the
floor and max is the
ceiling (EXCLUSIVE) of the range of the random number to produce. If not provided, min and max default to 0.0 and 1.0 respectively.
- Return Value:
- A Number - the generated random number.
Note that if srand has not been called before use, the random number generator will be automatically seeded.
irand¶
Generate a random integer using a fast, non-cryptographic random number generator.
Usage:
var rn = rampart.utils.irand([min, max]);
/* or */
var rn = rampart.utils.irand(max);
/* or */
rampart.utils.irand([max[min,max]],callback);
Where min is the
floor and max is the
ceiling (INCLUSIVE) of the range of the random integers to produce. If not provided,
min and max default to 0 and 99 respectively.
If provided, callback is a Function callback(r,i) where r is the random integer and
i is the loop count.
The Function will be called repeatedly until it returns false.
- Return Value:
-
A Number - the generated random integer as a number. If a function
is provided, returns
undefined.
Note that if srand has not been called before use, the random number generator will be automatically seeded.
Note also because of JavaScript Number precision, the maximum and
minimum max or
min that may be
provided is 9007199254740991 and -9007199254740991 respectively.
gaussrand¶
The gaussrand([sigma]) function returns a random Number using a fast, non-cryptographic random number generator and based on a
normal distribution centered at zero (0.0), where sigma is one standard deviation. sigma is optional, defaulting to
1.0.
normrand¶
The normrand([scale]) function returns a random Number using a fast, non-cryptographic random number generator and based on a
normal distribution centered at zero (0.0) and clamped between -scale and scale.
Similar to the gaussrand above. It is equivalent to:
var nrand = scale * rampart.utils.gaussrand(1.0)/5.0;
if(nrand>scale)
nrand=scale;
else if (nrand < -scale)
nrand = -scale;
With a scale of
1.0 (the default),
the distribution of numbers has a standard deviation of 0.2.
srand¶
Seed the random number generator for use with the random functions above.
Usage:
rampart.utils.srand([random_num]);
Where random_num is
an optional number to seed the random number generator. If not specified, a number will be
derived by reading /dev/urandom.
hash¶
Calculate the hash of data.
Usage:
var myhash = rampart.utils.hash(data,options);
Where data is the
data from which the hash is calculated and options is an Object with
the following optional properties:
-
type- the type of hash to be calculated. A String, one of:-
"murmur"- A 64 bit hash using the murmur algorithm. -
"city"- A 64 bit hash using the city algorithm. -
"city128"- A 128 bit hash using the city algorithm. This is the default if not specified. -
"both"- A 192 bit hash – thecity128hash concatenated with themurmurhash.
-
-
function- Alias fortype. -
returnBuffer- a Boolean, iftrue, the hash will be returned as the binary value of the hash in a a Buffer. Iffalse(the default), the return value will be a String - a hex encoded representation of the hash.
- Return Value:
- A String or Buffer - the computed hash.
hll¶
The hll function
calculates a count of unique items based on Rampart’s own hyperloglog algorithm. It allocates and uses a
16384 byte buffer to calculate a distinct count of items added.
Usage:
var myhll = new rampart.utils.hll(name);
/* or */
var myhll = new rampart.utils.hll(name, hllBufferData);
/* or */
var myhll = new rampart.utils.hll(name [, hllBufferData], merge_hll1 [, merge_hll2, ...]);
Where:
-
nameis an arbitrary String. It may be called again with the samenamein order to retrieve the same hll Object. -
hllBufferDatais a Buffer - The raw hll buffer to initialize the new hll Object with data previously extracted using getBuffer below. -
merge_hll1,merge_hll2, etc. are hll Objects created withnew rampart.utils.hll(name)to be merged into the new (blank) return hll Object in the same manner as merge below.
- Return Value:
-
An opaque hll Object containing the following
functions:
add,addFile,count,merge, andgetBuffer.
Note that an hll can be referred to from different threads in the Rampart Server or inside Rampart threads. Each thread may specify the same hll by using the same name. In addition, the below functions are thread-safe.
hll.add¶
Add a value or values to the hll.
Usage:
var myhll = new rampart.utils.hll(name);
myhll.add(value);
Where value is a
String, Buffer or an array of
Strings and/or Buffers.
- Return Value:
- The hll Object.
hll.addFile¶
Add values to the hll from a file, with each value on a separate line.
var myhll = new rampart.utils.hll(name);
myhll.addFile(file [, delim] );
- Where
-
-
fileis a String (name of file to be read) or a file handle opened with with fopen() orrampart.utils.stdin. -
delimis an optional String, the first character of which is used as a line separator. The default value is"\n".
-
- Return Value:
- The hll Object.
hll.count¶
Get a current estimate count of distinct items added to the hll.
Usage:
var myhll = new rampart.utils.hll(name);
/* add items */
...
var mycount = myhll.count();
- Return Value:
- A Number, the estimated number of distinct items added to the hll.
hll.merge¶
Merge one or more hll files into the current hll in order to calculate an estimate of the number of distinct items of the union.
Usage:
var mergedHll = myhll.merge(myhll2 [, myhll3, ...]);
Where myhll2,
myhll3, etc. are
hlls created with new rampart.utils.hll above.
- Return Value:
- The hll Object merged and updated with the provided hlls.