5.2 KiB
title | pagination_prev | pagination_next |
---|---|---|
C + QuickJS | demos/bigdata/index | solutions/input |
import current from '/version.js'; import CodeBlock from '@theme/CodeBlock';
QuickJS is an embeddable JS engine written in C. It provides a separate set of functions for interacting with the filesystem and the global object. It can run the standalone browser scripts.
The Standalone scripts can be parsed and evaluated in a QuickJS context.
Integration Details
Initialize QuickJS
QuickJS provides a global
object through JS_GetGlobalObject
:
/* initialize */
JSRuntime *rt = JS_NewRuntime();
JSContext *ctx = JS_NewContext(rt);
/* obtain reference to global object */
JSValue global = JS_GetGlobalObject(ctx);
/* DO WORK HERE */
/* free after use */
JS_FreeValue(ctx, global);
/* cleanup */
JS_FreeContext(ctx);
JS_FreeRuntime(rt);
:::warning
All values must be freed with JS_FreeValue
before calling JS_FreeContext
!
JS_IsException
should be used for validation.
Cleanup and validation code is omitted from the discussion. The integration example shows structured validation and controlled memory usage.
:::
Load SheetJS Scripts
The main library can be loaded by reading the script from the file system and evaluating in the QuickJS context:
static char *read_file(const char *filename, size_t *sz) {
FILE *f = fopen(filename, "rb");
if(!f) return NULL;
long fsize; { fseek(f, 0, SEEK_END); fsize = ftell(f); fsee (f, 0, SEEK_SET); }
char *buf = (char *)malloc(fsize * sizeof(char));
*sz = fread((void *) buf, 1, fsize, f);
fclose(f);
return buf;
}
// ...
/* load library */
{
size_t len; char *buf = read_file("xlsx.full.min.js", &len);
JS_Eval(ctx, buf, len, "<input>", 0);
free(buf);
}
To confirm the library is loaded, XLSX.version
can be inspected:
/* obtain reference to the XLSX object */
JSValue XLSX = JS_GetPropertyStr(ctx, global, "XLSX");
/* print version */
JSValue version = JS_GetPropertyStr(ctx, XLSX, "version");
size_t vlen; const char *vers = JS_ToCStringLen(ctx, &vlen, version);
printf("Version: %s\n", vers);
Reading Files
JS_NewArrayBuffer
can generate an ArrayBuffer
from a C byte array. The
function signature expects uint8_t *
instead of char *
:
/* read file */
size_t dlen; uint8_t * dbuf = (uint8_t *)read_file("pres.numbers", &dlen);
/* load data into array buffer */
JSValue ab = JS_NewArrayBuffer(ctx, dbuf, dlen, NULL, NULL, 0);
/* obtain reference to the XLSX object */
JSValue XLSX = JS_GetPropertyStr(ctx, global, "XLSX");
/* call XLSX.read(ab) */
JSValue XLSX_read = JS_GetPropertyStr(ctx, XLSX, "read");
JSValue args[] = { ab };
JSValue wb = JS_Call(ctx, XLSX_read, XLSX, 1, args);
Complete Example
The "Integration Example" covers a traditional integration in a C application,
while the "CLI Test" demonstrates other concepts using the quickjs
CLI tool.
Integration Example
:::note
This demo was tested in the following deployments:
Architecture | Git Commit | Date |
---|---|---|
darwin-x64 |
2788d71 |
2023-02-12 |
linux-x64 |
2788d71 |
2023-06-02 |
:::
- Build
libquickjs.a
:
git clone https://github.com/bellard/quickjs
cd quickjs
git checkout 2788d71
make
cd ..
- Copy
libquickjs.a
andquickjs.h
into the working directory:
cp quickjs/libquickjs.a .
cp quickjs/quickjs.h .
- Download
sheetjs.quick.c
:
curl -LO https://docs.sheetjs.com/quickjs/sheetjs.quick.c
- Build the sample application:
gcc -o sheetjs.quick -Wall -lm sheetjs.quick.c libquickjs.a
This program tries to parse the file specified by the first argument
- Download the standalone script and test file:
- xlsx.full.min.js
- pres.numbers
{\ curl -LO https://cdn.sheetjs.com/xlsx-${current}/package/dist/xlsx.full.min.js curl -LO https://sheetjs.com/pres.numbers
}
- Run the test program:
./sheetjs.quick pres.numbers
If successful, the program will print the library version number, file size, first worksheet name, and the contents of the first sheet as CSV rows.
CLI Test
:::note
This demo was last tested on 2023 March 11 against QuickJS 2021-03-27
.
:::
-
Ensure
quickjs
command line utility is installed -
Download the standalone script and the test file:
- xlsx.full.min.js
- pres.numbers
{\ curl -LO https://cdn.sheetjs.com/xlsx-${current}/package/dist/xlsx.full.min.js curl -LO https://sheetjs.com/pres.numbers
}
- Download
SheetJSQuick.js
curl -LO https://docs.sheetjs.com/quickjs/SheetJSQuick.js
- Test the program:
quickjs SheetJSQuick.js
If successful, the script will generate SheetJSQuick.xlsx
.