forked from sheetjs/docs.sheetjs.com
		
	jerry
This commit is contained in:
		
							parent
							
								
									963168e7b4
								
							
						
					
					
						commit
						6e3b91f9e5
					
				@ -38,11 +38,10 @@ Under the hood, `ArrayBuffer` objects represent raw binary data. "Typed arrays"
 | 
			
		||||
such as `Float64Array` and `Float32Array` are objects designed for efficient
 | 
			
		||||
interpretation and mutation of `ArrayBuffer` data.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
:::note pass
 | 
			
		||||
 | 
			
		||||
`ArrayBuffer` are roughly analogous to heap-allocated memory. Typed arrays
 | 
			
		||||
behave like typed pointers.
 | 
			
		||||
`ArrayBuffer` objects are roughly analogous to heap-allocated memory. Typed
 | 
			
		||||
arrays behave like typed pointers.
 | 
			
		||||
 | 
			
		||||
**JavaScript**
 | 
			
		||||
 | 
			
		||||
@ -262,7 +261,7 @@ arrays of arrays.
 | 
			
		||||
A single typed array can be converted to a pure JS array with `Array.from`:
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
const arr = Array.from(column);
 | 
			
		||||
const arr = Array.from(row);
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
An array of arrays can be created from the array:
 | 
			
		||||
 | 
			
		||||
@ -386,7 +386,7 @@ https.get('https://sheetjs.com/pres.numbers', function(res) {
 | 
			
		||||
 | 
			
		||||
<details><summary><b>Complete Example</b> (click to show)</summary>
 | 
			
		||||
 | 
			
		||||
:::note
 | 
			
		||||
:::note Tested Environments
 | 
			
		||||
 | 
			
		||||
This demo was last tested on 2024 January 15 against NodeJS `20.11.0`
 | 
			
		||||
 | 
			
		||||
@ -433,7 +433,7 @@ async function parse_from_url(url) {
 | 
			
		||||
 | 
			
		||||
<details><summary><b>Complete Example</b> (click to show)</summary>
 | 
			
		||||
 | 
			
		||||
:::note
 | 
			
		||||
:::note Tested Environments
 | 
			
		||||
 | 
			
		||||
This demo was last tested on 2024 January 15 against NodeJS `20.11.0`
 | 
			
		||||
 | 
			
		||||
@ -512,7 +512,7 @@ request(url, {encoding: null}, function(err, res, data) {
 | 
			
		||||
 | 
			
		||||
<details><summary><b>Complete Example</b> (click to show)</summary>
 | 
			
		||||
 | 
			
		||||
:::note
 | 
			
		||||
:::note Tested Environments
 | 
			
		||||
 | 
			
		||||
This demo was last tested on 2024 January 15 against request `2.88.2`
 | 
			
		||||
 | 
			
		||||
@ -554,7 +554,7 @@ async function workbook_dl_axios(url) {
 | 
			
		||||
 | 
			
		||||
<details><summary><b>Complete Example</b> (click to show)</summary>
 | 
			
		||||
 | 
			
		||||
:::note
 | 
			
		||||
:::note Tested Environments
 | 
			
		||||
 | 
			
		||||
This demo was last tested on 2024 January 15 against Axios `1.6.5`
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -301,7 +301,7 @@ This demo was tested in the following environments:
 | 
			
		||||
| macOS 14.1.2   | `darwin-arm` | `v2.6.0` | 2023-12-01 |
 | 
			
		||||
| Windows 10     | `win10-x64`  | `v2.6.0` | 2023-12-09 |
 | 
			
		||||
| Windows 11     | `win11-arm`  | `v2.6.0` | 2023-12-01 |
 | 
			
		||||
| Linux (HoloOS) | `linux-x64`  | `v2.6.0` | 2023-10-11 |
 | 
			
		||||
| Linux (HoloOS) | `linux-x64`  | `v2.7.1` | 2024-01-22 |
 | 
			
		||||
| Linux (Debian) | `linux-arm`  | `v2.6.0` | 2023-12-01 |
 | 
			
		||||
 | 
			
		||||
:::
 | 
			
		||||
 | 
			
		||||
@ -261,7 +261,7 @@ This demo was tested in the following environments:
 | 
			
		||||
| macOS 14.0     | `darwin-arm` | `v1.5.2` | 2023-10-18 |
 | 
			
		||||
| Windows 10     | `win10-x64`  | `v1.5.0` | 2023-10-01 |
 | 
			
		||||
| Windows 11     | `win11-arm`  | `v1.5.7` | 2023-12-01 |
 | 
			
		||||
| Linux (HoloOS) | `linux-x64`  | `v1.5.2` | 2023-10-11 |
 | 
			
		||||
| Linux (HoloOS) | `linux-x64`  | `v1.5.9` | 2024-01-23 |
 | 
			
		||||
| Linux (Debian) | `linux-arm`  | `v1.5.7` | 2023-12-01 |
 | 
			
		||||
 | 
			
		||||
:::
 | 
			
		||||
 | 
			
		||||
@ -421,7 +421,7 @@ This demo was last tested in the following deployments:
 | 
			
		||||
| `win10-x64`  | `1.37.1` | 2023-10-09 |
 | 
			
		||||
| `win11-x64`  | `1.37.2` | 2023-10-14 |
 | 
			
		||||
| `win11-arm`  | `1.38.4` | 2023-12-01 |
 | 
			
		||||
| `linux-x64`  | `1.37.1` | 2023-10-11 |
 | 
			
		||||
| `linux-x64`  | `1.39.4` | 2024-01-22 |
 | 
			
		||||
| `linux-arm`  | `1.38.4` | 2023-12-01 |
 | 
			
		||||
 | 
			
		||||
:::
 | 
			
		||||
 | 
			
		||||
@ -41,7 +41,7 @@ setting the environment variable on supported platforms.
 | 
			
		||||
:::note pass
 | 
			
		||||
 | 
			
		||||
Most of the integration functions are not documented. This explanation is based
 | 
			
		||||
on version `3.0.0-beta-2056`.
 | 
			
		||||
on version `3.0.0`.
 | 
			
		||||
 | 
			
		||||
:::
 | 
			
		||||
 | 
			
		||||
@ -108,7 +108,7 @@ byte[] buf = File.ReadAllBytes(filename);
 | 
			
		||||
Jint natively supports `Uint8Array` construction from the byte array:
 | 
			
		||||
 | 
			
		||||
```csharp
 | 
			
		||||
Jint.Native.JsValue u8 = engine.Realm.Intrinsics.Uint8Array.Construct(buf);
 | 
			
		||||
Jint.Native.JsValue u8 = engine.Intrinsics.Uint8Array.Construct(buf);
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
`Jint.Engine#SetValue` will assign the `Uint8Array` to a scope variable in JS:
 | 
			
		||||
@ -163,11 +163,11 @@ This demo was tested in the following deployments:
 | 
			
		||||
 | 
			
		||||
| Architecture | Jint Version      | Date       |
 | 
			
		||||
|:-------------|:------------------|:-----------|
 | 
			
		||||
| `darwin-x64` | `3.0.0-beta-2055` | 2023-11-14 |
 | 
			
		||||
| `darwin-x64` | `3.0.0`           | 2024-01-22 |
 | 
			
		||||
| `darwin-arm` | `3.0.0-beta-2056` | 2023-12-01 |
 | 
			
		||||
| `win10-x64`  | `3.0.0-beta-2053` | 2023-10-28 |
 | 
			
		||||
| `win11-arm`  | `3.0.0-beta-2056` | 2023-12-01 |
 | 
			
		||||
| `linux-x64`  | `3.0.0-beta-2052` | 2023-10-11 |
 | 
			
		||||
| `linux-x64`  | `3.0.0`           | 2024-01-22 |
 | 
			
		||||
| `linux-arm`  | `3.0.0-beta-2056` | 2023-12-01 |
 | 
			
		||||
 | 
			
		||||
:::
 | 
			
		||||
@ -211,10 +211,18 @@ Click "OK" in each window (3 windows) and restart your computer.
 | 
			
		||||
 | 
			
		||||
<details><summary><b>Installation Notes</b> (click to show)</summary>
 | 
			
		||||
 | 
			
		||||
For macOS x64 and ARM64, install with Homebrew: `brew install dotnet@6`
 | 
			
		||||
For macOS x64 and ARM64, install the `dotnet-sdk` Cask with Homebrew:
 | 
			
		||||
 | 
			
		||||
```bash
 | 
			
		||||
brew install --cask dotnet-sdk
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
For Steam Deck Holo and other Arch Linux x64 distributions, the `dotnet-sdk` and
 | 
			
		||||
`dotnet-runtime` packages should be installed using `pacman`.
 | 
			
		||||
`dotnet-runtime` packages should be installed using `pacman`:
 | 
			
		||||
 | 
			
		||||
```bash
 | 
			
		||||
sudo pacman -Syu dotnet-sdk dotnet-runtime
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
<https://dotnet.microsoft.com/en-us/download/dotnet/6.0> is the official source
 | 
			
		||||
for Windows and ARM64 Linux versions.
 | 
			
		||||
@ -230,7 +238,7 @@ for Windows and ARM64 Linux versions.
 | 
			
		||||
```bash
 | 
			
		||||
mkdir SheetJSJint
 | 
			
		||||
cd SheetJSJint
 | 
			
		||||
dotnet new console --framework net6.0
 | 
			
		||||
dotnet new console
 | 
			
		||||
dotnet run
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
@ -238,7 +246,7 @@ dotnet run
 | 
			
		||||
 | 
			
		||||
```bash
 | 
			
		||||
dotnet nuget add source https://www.myget.org/F/jint/api/v3/index.json
 | 
			
		||||
dotnet add package Jint --version 3.0.0-beta-2056
 | 
			
		||||
dotnet add package Jint --version 3.0.0
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
To verify Jint is installed, replace `Program.cs` with the following:
 | 
			
		||||
@ -309,7 +317,7 @@ Console.WriteLine("SheetJS version {0}", engine.Evaluate("XLSX.version"));
 | 
			
		||||
 | 
			
		||||
/* Read and Parse File */
 | 
			
		||||
byte[] filedata = File.ReadAllBytes(args[0]);
 | 
			
		||||
Jint.Native.JsValue u8 = engine.Realm.Intrinsics.Uint8Array.Construct(filedata);
 | 
			
		||||
Jint.Native.JsValue u8 = engine.Intrinsics.Uint8Array.Construct(filedata);
 | 
			
		||||
engine.SetValue("buf", u8);
 | 
			
		||||
engine.Evaluate("var wb = XLSX.read(buf);");
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -27,7 +27,7 @@ command-line tool for reading data from files.
 | 
			
		||||
:::note pass
 | 
			
		||||
 | 
			
		||||
Many QuickJS functions are not documented. The explanation was verified against
 | 
			
		||||
the latest release (commit `daa35bc`).
 | 
			
		||||
the latest release (commit `9e561d5`).
 | 
			
		||||
 | 
			
		||||
:::
 | 
			
		||||
 | 
			
		||||
@ -266,10 +266,10 @@ This demo was tested in the following deployments:
 | 
			
		||||
| `darwin-arm` | `2788d71`  | 2023-10-18 |
 | 
			
		||||
| `win10-x64`  | `daa35bc`  | 2023-12-09 |
 | 
			
		||||
| `win11-arm`  | `03cc5ec`  | 2023-12-01 |
 | 
			
		||||
| `linux-x64`  | `03cc5ec`  | 2023-12-07 |
 | 
			
		||||
| `linux-x64`  | `9e561d5`  | 2024-01-22 |
 | 
			
		||||
| `linux-arm`  | `03cc5ec`  | 2023-12-01 |
 | 
			
		||||
 | 
			
		||||
When the demo was tested, commit `daa35bc` corresponded to the latest release.
 | 
			
		||||
When the demo was tested, commit `9e561d5` corresponded to the latest release.
 | 
			
		||||
 | 
			
		||||
:::
 | 
			
		||||
 | 
			
		||||
@ -285,7 +285,7 @@ tests were run entirely within Windows Subsystem for Linux.
 | 
			
		||||
```bash
 | 
			
		||||
git clone https://github.com/bellard/quickjs
 | 
			
		||||
cd quickjs
 | 
			
		||||
git checkout daa35bc
 | 
			
		||||
git checkout 9e561d5
 | 
			
		||||
make
 | 
			
		||||
cd ..
 | 
			
		||||
```
 | 
			
		||||
@ -342,10 +342,9 @@ This demo was tested in the following environments:
 | 
			
		||||
 | 
			
		||||
| Git Commit | Date       |
 | 
			
		||||
|:-----------|:-----------|
 | 
			
		||||
| `daa35bc`  | 2023-12-09 |
 | 
			
		||||
| `2788d71`  | 2023-12-09 |
 | 
			
		||||
| `9e561d5`  | 2024-01-22 |
 | 
			
		||||
 | 
			
		||||
When the demo was tested, commit `daa35bc` corresponded to the latest release.
 | 
			
		||||
When the demo was tested, commit `9e561d5` corresponded to the latest release.
 | 
			
		||||
 | 
			
		||||
:::
 | 
			
		||||
 | 
			
		||||
@ -354,7 +353,7 @@ When the demo was tested, commit `daa35bc` corresponded to the latest release.
 | 
			
		||||
```bash
 | 
			
		||||
git clone https://github.com/bellard/quickjs
 | 
			
		||||
cd quickjs
 | 
			
		||||
git checkout daa35bc
 | 
			
		||||
git checkout 9e561d5
 | 
			
		||||
make
 | 
			
		||||
cd ..
 | 
			
		||||
cp quickjs/qjs .
 | 
			
		||||
 | 
			
		||||
@ -16,8 +16,8 @@ ChakraCore is an embeddable JS engine written in C++.
 | 
			
		||||
[SheetJS](https://sheetjs.com) is a JavaScript library for reading and writing
 | 
			
		||||
data from spreadsheets.
 | 
			
		||||
 | 
			
		||||
This demo uses Hermes and SheetJS to pull data from a spreadsheet and print CSV
 | 
			
		||||
rows. We'll explore how to load SheetJS in a ChakraCore context and process
 | 
			
		||||
This demo uses ChakraCore and SheetJS to pull data from a spreadsheet and print
 | 
			
		||||
CSV rows. We'll explore how to load SheetJS in a ChakraCore context and process
 | 
			
		||||
spreadsheets from a C++ program.
 | 
			
		||||
 | 
			
		||||
The ["Integration Example"](#integration-example) section includes a complete
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										473
									
								
								docz/docs/03-demos/42-engines/23-jerryscript.md
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										473
									
								
								docz/docs/03-demos/42-engines/23-jerryscript.md
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,473 @@
 | 
			
		||||
---
 | 
			
		||||
title: C + JerryScript
 | 
			
		||||
pagination_prev: demos/bigdata/index
 | 
			
		||||
pagination_next: solutions/input
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
import current from '/version.js';
 | 
			
		||||
import CodeBlock from '@theme/CodeBlock';
 | 
			
		||||
 | 
			
		||||
[JerryScript](https://jerryscript.net/) is a lightweight JavaScript engine. It
 | 
			
		||||
is designed for microcontrollers and similar environments.
 | 
			
		||||
 | 
			
		||||
[SheetJS](https://sheetjs.com) is a JavaScript library for reading and writing
 | 
			
		||||
data from spreadsheets.
 | 
			
		||||
 | 
			
		||||
This demo uses JerryScript and SheetJS to pull data from a spreadsheet and print
 | 
			
		||||
CSV rows. We'll explore how to load SheetJS in a JerryScript realm and process
 | 
			
		||||
spreadsheets from C programs.
 | 
			
		||||
 | 
			
		||||
The ["Integration Example"](#integration-example) section includes a complete
 | 
			
		||||
command-line tool for reading data from files.
 | 
			
		||||
 | 
			
		||||
:::caution pass
 | 
			
		||||
 | 
			
		||||
This demo requires a much larger heap size than is normally used in JerryScript
 | 
			
		||||
deployments! In local testing, the following sizes were needed:
 | 
			
		||||
 | 
			
		||||
- 8192 (8M) for <https://sheetjs.com/pres.xlsx>
 | 
			
		||||
- 65536 (64M) for <https://sheetjs.com/pres.numbers>
 | 
			
		||||
 | 
			
		||||
:::
 | 
			
		||||
 | 
			
		||||
:::note Tested Environments
 | 
			
		||||
 | 
			
		||||
This demo was tested in the following environments:
 | 
			
		||||
 | 
			
		||||
| Architecture | Commit    | Date       |
 | 
			
		||||
|:-------------|:----------|:-----------|
 | 
			
		||||
| `darwin-x64` | `514fa67` | 2024-01-22 |
 | 
			
		||||
| `darwin-arm` | `ef4cb2b` | 2023-12-08 |
 | 
			
		||||
| `win11-x64`  | `ef4cb2b` | 2023-12-08 |
 | 
			
		||||
| `win11-arm`  | `ef4cb2b` | 2023-12-08 |
 | 
			
		||||
| `linux-x64`  | `ef4cb2b` | 2023-12-08 |
 | 
			
		||||
| `linux-arm`  | `ef4cb2b` | 2023-12-08 |
 | 
			
		||||
 | 
			
		||||
The Windows tests were run in WSL.
 | 
			
		||||
 | 
			
		||||
Debian and WSL require the `cmake`, `python3` and `python-is-python3` packages.
 | 
			
		||||
 | 
			
		||||
:::
 | 
			
		||||
 | 
			
		||||
## Integration Details
 | 
			
		||||
 | 
			
		||||
:::info pass
 | 
			
		||||
 | 
			
		||||
The official JerryScript documentation and examples are out of date. This
 | 
			
		||||
explanation was verified against the latest release (commit `514fa67`).
 | 
			
		||||
 | 
			
		||||
:::
 | 
			
		||||
 | 
			
		||||
### Initialize JerryScript
 | 
			
		||||
 | 
			
		||||
The global engine instance can be initialized with `jerry_init` and cleaned up
 | 
			
		||||
with `jerry_cleanup`:
 | 
			
		||||
 | 
			
		||||
```c
 | 
			
		||||
#include "jerryscript.h"
 | 
			
		||||
 | 
			
		||||
int main (int argc, char **argv) {
 | 
			
		||||
  /* Initialize engine */
 | 
			
		||||
/* highlight-next-line */
 | 
			
		||||
  jerry_init(JERRY_INIT_EMPTY);
 | 
			
		||||
 | 
			
		||||
  // ... use engine methods ...
 | 
			
		||||
 | 
			
		||||
  /* cleanup before exiting */
 | 
			
		||||
/* highlight-next-line */
 | 
			
		||||
  jerry_cleanup();
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
API methods use `jerry_value_t` values to represent JS values and miscellany.
 | 
			
		||||
Values representing errors can be distinguished using `jerry_value_is_error`.
 | 
			
		||||
`jerry_value_t` values can be freed with `jerry_value_free`.
 | 
			
		||||
 | 
			
		||||
### Evaluate Code
 | 
			
		||||
 | 
			
		||||
Evaluating code involves two steps:
 | 
			
		||||
 | 
			
		||||
- `jerry_parse` will parse the script
 | 
			
		||||
- `jerry_run` will run the parsed script object
 | 
			
		||||
 | 
			
		||||
:::note pass
 | 
			
		||||
 | 
			
		||||
The return value of `jerry_parse` is a `jerry_value_t` value that can be safely
 | 
			
		||||
freed after `jerry_run`.
 | 
			
		||||
 | 
			
		||||
:::
 | 
			
		||||
 | 
			
		||||
The following `eval_str` function parses and executes scripts. If parsing fails,
 | 
			
		||||
the function will return the parsing error. If parsing succeeds, the function
 | 
			
		||||
will return the result of executing the code.
 | 
			
		||||
 | 
			
		||||
```c
 | 
			
		||||
jerry_value_t eval_str(const char *code, size_t sz) {
 | 
			
		||||
  /* try to parse code */
 | 
			
		||||
  jerry_value_t parsed = jerry_parse(code, sz, NULL);
 | 
			
		||||
  /* return the parse error if parsing failed */
 | 
			
		||||
  if(jerry_value_is_error(parsed)) return parsed;
 | 
			
		||||
 | 
			
		||||
  /* run the code */
 | 
			
		||||
  jerry_value_t out = jerry_run(parsed);
 | 
			
		||||
  /* free the parsed representation */
 | 
			
		||||
  jerry_value_free(parsed);
 | 
			
		||||
 | 
			
		||||
  /* return the result */
 | 
			
		||||
  return out;
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### Load SheetJS Scripts
 | 
			
		||||
 | 
			
		||||
[SheetJS Standalone scripts](/docs/getting-started/installation/standalone) can
 | 
			
		||||
be parsed and run in JerryScript.
 | 
			
		||||
 | 
			
		||||
Scripts can be read from the filesystem using standard C functions:
 | 
			
		||||
 | 
			
		||||
```c
 | 
			
		||||
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); fseek(f, 0, SEEK_SET); }
 | 
			
		||||
  char *buf = (char *)malloc(fsize * sizeof(char));
 | 
			
		||||
  *sz = fread((void *) buf, 1, fsize, f) - 1;
 | 
			
		||||
  fclose(f);
 | 
			
		||||
  return buf;
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
The shim script must be evaluated before the main library. In both cases, after
 | 
			
		||||
reading the script file, the previous `eval_str` function can run the code:
 | 
			
		||||
 | 
			
		||||
```c
 | 
			
		||||
  /* evaluate shim.min.js */
 | 
			
		||||
  {
 | 
			
		||||
    size_t sz; const jerry_char_t *script = (jerry_char_t *)read_file("shim.min.js", &sz);
 | 
			
		||||
    jerry_value_t result = eval_str(script, sz);
 | 
			
		||||
    if(jerry_value_is_error(result)) { // failed to parse / execute
 | 
			
		||||
      fprintf(stderr, "Failed to evaluate shim.min.js"); return 1;
 | 
			
		||||
    }
 | 
			
		||||
    jerry_value_free(result);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /* evaluate xlsx.full.min.js */
 | 
			
		||||
  {
 | 
			
		||||
    size_t sz; const jerry_char_t *script = (jerry_char_t *)read_file("xlsx.full.min.js", &sz);
 | 
			
		||||
    jerry_value_t result = eval_str(script, sz);
 | 
			
		||||
    if(jerry_value_is_error(result)) { // failed to parse / execute
 | 
			
		||||
      fprintf(stderr, "Failed to evaluate xlsx.full.min.js"); return 1;
 | 
			
		||||
    }
 | 
			
		||||
    jerry_value_free(result);
 | 
			
		||||
  }
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### Reading Files
 | 
			
		||||
 | 
			
		||||
Binary file data can be passed from C to JerryScript with `ArrayBuffer` objects.
 | 
			
		||||
 | 
			
		||||
#### Creating ArrayBuffers
 | 
			
		||||
 | 
			
		||||
`jerry_arraybuffer` will generate an `ArrayBuffer` object of specified length.
 | 
			
		||||
After creating the array, `jerry_arraybuffer_write` will copy data.
 | 
			
		||||
 | 
			
		||||
The following `load_file` function reads a file from the filesystem and loads
 | 
			
		||||
the data into an `ArrayBuffer`:
 | 
			
		||||
 | 
			
		||||
```c
 | 
			
		||||
static jerry_value_t load_file(const char *filename) {
 | 
			
		||||
  /* read file */
 | 
			
		||||
  size_t len; char *buf = read_file(filename, &len);
 | 
			
		||||
  if(!buf) return 0;
 | 
			
		||||
 | 
			
		||||
  /* create ArrayBuffer */
 | 
			
		||||
  jerry_value_t out = jerry_arraybuffer(len);
 | 
			
		||||
  /* copy file data into ArrayBuffer */
 | 
			
		||||
  jerry_arraybuffer_write(out, 0, (const uint8_t*)buf, len);
 | 
			
		||||
  return out;
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
The process may fail. The result should be tested with `jerry_value_is_error`:
 | 
			
		||||
 | 
			
		||||
```c
 | 
			
		||||
  jerry_value_t ab = load_file("pres.xlsx");
 | 
			
		||||
  if(!ab || jerry_value_is_error(ab)) { // failed to create ArrayBuffer
 | 
			
		||||
    fprintf(stderr, "Failed to read pres.xlsx"); return 1;
 | 
			
		||||
  }
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
#### Creating Global Variable
 | 
			
		||||
 | 
			
		||||
The `ArrayBuffer` object must be bound to a variable before it can be used.
 | 
			
		||||
 | 
			
		||||
:::note pass
 | 
			
		||||
 | 
			
		||||
The goal is to bind the `ArrayBuffer` to the `buf` property in global scope.
 | 
			
		||||
 | 
			
		||||
:::
 | 
			
		||||
 | 
			
		||||
1) Get the global `this` variable (using `jerry_current_realm`):
 | 
			
		||||
 | 
			
		||||
```c
 | 
			
		||||
  /* get the global variable */
 | 
			
		||||
  jerry_value_t this = jerry_current_realm();
 | 
			
		||||
  if(jerry_value_is_error(this)) { // failed to get global object
 | 
			
		||||
    fprintf(stderr, "Failed to get global object"); return 1;
 | 
			
		||||
  }
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
2) Create a JerryScript string (`"buf"`) for the property:
 | 
			
		||||
 | 
			
		||||
```c
 | 
			
		||||
  /* create a string "buf" for the property access */
 | 
			
		||||
  jerry_value_t prop = jerry_string_sz("buf");
 | 
			
		||||
  if(jerry_value_is_error(this)) { // failed to create "buf"
 | 
			
		||||
    fprintf(stderr, "Failed to create string"); return 1;
 | 
			
		||||
  }
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
3) Assign the property using `jerry_object_set`:
 | 
			
		||||
 | 
			
		||||
```c
 | 
			
		||||
  /* set global["buf"] to the ArrayBuffer */
 | 
			
		||||
  jerry_value_t set = jerry_object_set(this, prop, ab);
 | 
			
		||||
  if(jerry_value_is_error(set)) { // failed to set property
 | 
			
		||||
    fprintf(stderr, "Failed to assign ArrayBuffer"); return 1;
 | 
			
		||||
  }
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
#### Parsing Data
 | 
			
		||||
 | 
			
		||||
:::note pass
 | 
			
		||||
 | 
			
		||||
The goal is to run the equivalent of the following JavaScript code:
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
/* `buf` is the `ArrayBuffer` from the previous step */
 | 
			
		||||
var wb = XLSX.read(buf);
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
:::
 | 
			
		||||
 | 
			
		||||
The `ArrayBuffer` from the previous step is available in the `buf` variable.
 | 
			
		||||
That `ArrayBuffer` can be passed to the SheetJS `read` method[^1], which will
 | 
			
		||||
parse the raw data and return a SheetJS workbook object[^2].
 | 
			
		||||
 | 
			
		||||
`var wb = XLSX.read(buf)` can be stored in a byte array and evaluated directly:
 | 
			
		||||
 | 
			
		||||
```c
 | 
			
		||||
  /* run `var wb = XLSX.read(buf)` */
 | 
			
		||||
  {
 | 
			
		||||
    const jerry_char_t code[] = "var wb = XLSX.read(buf);";
 | 
			
		||||
    jerry_value_t result = eval_str(code, sizeof(code) - 1);
 | 
			
		||||
    if(jerry_value_is_error(result)) {
 | 
			
		||||
      fprintf(stderr, "Failed to parse file"); return 1;
 | 
			
		||||
    }
 | 
			
		||||
    jerry_value_free(result);
 | 
			
		||||
  }
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
#### Generating CSV
 | 
			
		||||
 | 
			
		||||
:::note pass
 | 
			
		||||
 | 
			
		||||
The goal is to run the equivalent of the following JavaScript code:
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
/* `wb` is the workbook from the previous step */
 | 
			
		||||
XLSX.utils.sheet_to_csv(wb.Sheets[wb.SheetNames[0]])
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
:::
 | 
			
		||||
 | 
			
		||||
A SheetJS workbook object can contain multiple sheet objects[^3]. The `Sheets`
 | 
			
		||||
property is an object whose keys are sheet names and whose values are sheet
 | 
			
		||||
objects. The `SheetNames` property is an array of worksheet names.
 | 
			
		||||
 | 
			
		||||
The first sheet name can be found at `wb.SheetNames[0]`. The first sheet object
 | 
			
		||||
can be found at `wb.Sheets[wb.SheetNames[0]]`.
 | 
			
		||||
 | 
			
		||||
The SheetJS `sheet_to_csv` utility function[^4] accepts a sheet object and
 | 
			
		||||
generates a JS string.
 | 
			
		||||
 | 
			
		||||
Combining everything, `XLSX.utils.sheet_to_csv(wb.Sheets[wb.SheetNames[0]])`
 | 
			
		||||
generates a CSV string based on the first worksheet in the workbook `wb`:
 | 
			
		||||
 | 
			
		||||
```c
 | 
			
		||||
  const jerry_char_t code[] = "XLSX.utils.sheet_to_csv(wb.Sheets[wb.SheetNames[0]])";
 | 
			
		||||
  jerry_value_t csv = eval_str(code, sizeof(code) - 1);
 | 
			
		||||
  if(jerry_value_is_error(result)) { // CSV generation failed
 | 
			
		||||
    fprintf(stderr, "Failed to generate csv"); return 1;
 | 
			
		||||
  }
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
#### Pulling Strings
 | 
			
		||||
 | 
			
		||||
JerryScript exposes encoding-aware methods to pull JS strings into C. The
 | 
			
		||||
`JERRY_ENCODING_UTF8` encoding forces UTF8 interpretations.
 | 
			
		||||
 | 
			
		||||
The `jerry_string_size` function returns the number of bytes required to store
 | 
			
		||||
the string. After allocating memory, `jerry_string_to_buffer` will copy data.
 | 
			
		||||
The following `pull_str` function uses `malloc`:
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
char *pull_str(jerry_value_t str, size_t *sz) {
 | 
			
		||||
  /* determine string size in bytes */
 | 
			
		||||
  jerry_size_t str_sz = jerry_string_size(str, JERRY_ENCODING_UTF8);
 | 
			
		||||
 | 
			
		||||
  /* allocate memory */
 | 
			
		||||
  jerry_char_t *buf = (jerry_char_t *)malloc(str_sz + 1);
 | 
			
		||||
 | 
			
		||||
  /* copy from JS string to C byte array */
 | 
			
		||||
  jerry_string_to_buffer(str, JERRY_ENCODING_UTF8, buf, str_sz + 1);
 | 
			
		||||
 | 
			
		||||
  /* pass back size and return the pointer */
 | 
			
		||||
  *sz = str_sz;
 | 
			
		||||
  return (char *)buf;
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
This function can be used to pull the `csv` value from the previous section:
 | 
			
		||||
 | 
			
		||||
```c
 | 
			
		||||
  size_t sz; char *buf = pull_str(result, &sz);
 | 
			
		||||
  printf("%s\n", buf);
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## Complete Example
 | 
			
		||||
 | 
			
		||||
The "Integration Example" covers a traditional integration in a C application,
 | 
			
		||||
while the "CLI Test" demonstrates other concepts using the `jerry` CLI tool.
 | 
			
		||||
 | 
			
		||||
### Integration Example
 | 
			
		||||
 | 
			
		||||
1) Create a project folder:
 | 
			
		||||
 | 
			
		||||
```bash
 | 
			
		||||
mkdir SheetJSJerry
 | 
			
		||||
cd SheetJSJerry
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
2) Clone the repository and build the library with required options:
 | 
			
		||||
 | 
			
		||||
```bash
 | 
			
		||||
git clone --depth=1 https://github.com/jerryscript-project/jerryscript.git
 | 
			
		||||
cd jerryscript
 | 
			
		||||
python tools/build.py --error-messages=ON --logging=ON --mem-heap=8192 --cpointer-32bit=ON
 | 
			
		||||
cd ..
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
3) Download the SheetJS Standalone script, shim script and test file. Move all
 | 
			
		||||
three files to the `SheetJSJerry` directory:
 | 
			
		||||
 | 
			
		||||
<ul>
 | 
			
		||||
<li><a href={`https://cdn.sheetjs.com/xlsx-${current}/package/dist/xlsx.full.min.js`}>xlsx.full.min.js</a></li>
 | 
			
		||||
<li><a href={`https://cdn.sheetjs.com/xlsx-${current}/package/dist/shim.min.js`}>shim.min.js</a></li>
 | 
			
		||||
<li><a href="https://sheetjs.com/pres.xlsx">pres.xlsx</a></li>
 | 
			
		||||
</ul>
 | 
			
		||||
 | 
			
		||||
<CodeBlock language="bash">{`\
 | 
			
		||||
curl -LO https://cdn.sheetjs.com/xlsx-${current}/package/dist/shim.min.js
 | 
			
		||||
curl -LO https://cdn.sheetjs.com/xlsx-${current}/package/dist/xlsx.full.min.js
 | 
			
		||||
curl -LO https://sheetjs.com/pres.xlsx`}
 | 
			
		||||
</CodeBlock>
 | 
			
		||||
 | 
			
		||||
4) Download [`sheetjs.jerry.c`](pathname:///jerryscript/sheetjs.jerry.c) into
 | 
			
		||||
the same folder:
 | 
			
		||||
 | 
			
		||||
```bash
 | 
			
		||||
curl -LO https://docs.sheetjs.com/jerryscript/sheetjs.jerry.c
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
5) Build the sample application:
 | 
			
		||||
 | 
			
		||||
```bash
 | 
			
		||||
gcc -o sheetjs.jerry -Ijerryscript/jerry-ext/include -Ijerryscript/jerry-math/include -Ijerryscript/jerry-core/include -ljerry-ext -ljerry-port -ljerry-core  -Ljerryscript/build/lib sheetjs.jerry.c -Wno-pointer-sign
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
6) Run the test program:
 | 
			
		||||
 | 
			
		||||
```bash
 | 
			
		||||
./sheetjs.jerry pres.xlsx
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
If successful, the program will print contents of the first sheet as CSV rows.
 | 
			
		||||
 | 
			
		||||
### CLI Test
 | 
			
		||||
 | 
			
		||||
:::note pass
 | 
			
		||||
 | 
			
		||||
Due to limitations of the standalone binary, this demo will encode a test file
 | 
			
		||||
as a Base64 string and directly add it to an amalgamated script.
 | 
			
		||||
 | 
			
		||||
:::
 | 
			
		||||
 | 
			
		||||
0) Build the library and command line tool with required options:
 | 
			
		||||
 | 
			
		||||
```bash
 | 
			
		||||
git clone --depth=1 https://github.com/jerryscript-project/jerryscript.git
 | 
			
		||||
cd jerryscript
 | 
			
		||||
python tools/build.py --error-messages=ON --logging=ON --mem-heap=8192 --cpointer-32bit=ON
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
1) Download the SheetJS Standalone script, shim script and test file. Move all
 | 
			
		||||
three files to the `jerryscript` cloned repo directory:
 | 
			
		||||
 | 
			
		||||
<ul>
 | 
			
		||||
<li><a href={`https://cdn.sheetjs.com/xlsx-${current}/package/dist/xlsx.full.min.js`}>xlsx.full.min.js</a></li>
 | 
			
		||||
<li><a href={`https://cdn.sheetjs.com/xlsx-${current}/package/dist/shim.min.js`}>shim.min.js</a></li>
 | 
			
		||||
<li><a href="https://sheetjs.com/pres.xlsx">pres.xlsx</a></li>
 | 
			
		||||
</ul>
 | 
			
		||||
 | 
			
		||||
<CodeBlock language="bash">{`\
 | 
			
		||||
curl -LO https://cdn.sheetjs.com/xlsx-${current}/package/dist/shim.min.js
 | 
			
		||||
curl -LO https://cdn.sheetjs.com/xlsx-${current}/package/dist/xlsx.full.min.js
 | 
			
		||||
curl -LO https://sheetjs.com/pres.xlsx`}
 | 
			
		||||
</CodeBlock>
 | 
			
		||||
 | 
			
		||||
2) Bundle the test file and create `payload.js`:
 | 
			
		||||
 | 
			
		||||
```bash
 | 
			
		||||
node -e "fs.writeFileSync('payload.js', 'var payload = \"' + fs.readFileSync('pres.xlsx').toString('base64') + '\";')"
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
3) Create support scripts:
 | 
			
		||||
 | 
			
		||||
- `global.js` creates a `global` variable and defines a fake `console`:
 | 
			
		||||
 | 
			
		||||
```js title="global.js"
 | 
			
		||||
var global = (function(){ return this; }).call(null);
 | 
			
		||||
var console = { log: function(x) { print(x); } };
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
- `jerry.js` will call `XLSX.read` and `XLSX.utils.sheet_to_csv`:
 | 
			
		||||
 | 
			
		||||
```js title="jerry.js"
 | 
			
		||||
var wb = XLSX.read(payload, {type:'base64'});
 | 
			
		||||
console.log(XLSX.utils.sheet_to_csv(wb.Sheets[wb.SheetNames[0]]));
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
4) Create the amalgamation `xlsx.jerry.js`:
 | 
			
		||||
 | 
			
		||||
```bash
 | 
			
		||||
cat global.js xlsx.full.min.js payload.js jerry.js > xlsx.jerry.js
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
The final script defines `global` before loading the standalone library.  Once
 | 
			
		||||
ready, it will read the bundled test data and print the contents as CSV.
 | 
			
		||||
 | 
			
		||||
5) Run the script using the `jerry` standalone binary:
 | 
			
		||||
 | 
			
		||||
```bash
 | 
			
		||||
build/bin/jerry xlsx.jerry.js; echo $?
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
If successful, the contents of the test file will be displayed in CSV rows. The
 | 
			
		||||
status code `0` will be printed after the rows.
 | 
			
		||||
 | 
			
		||||
[^1]: See [`read` in "Reading Files"](/docs/api/parse-options)
 | 
			
		||||
[^2]: See ["Workbook Object" in "SheetJS Data Model"](/docs/csf/book)
 | 
			
		||||
[^3]: See ["Sheet Objects"](/docs/csf/sheet)
 | 
			
		||||
[^4]: See [`sheet_to_csv` in "CSV and Text"](/docs/api/utilities/csv#delimiter-separated-output)
 | 
			
		||||
@ -26,7 +26,7 @@ This demo showcases a number of JS engines and language bindings.
 | 
			
		||||
 | 
			
		||||
Common browser and NodeJS APIs are often missing from light-weight JS engines.
 | 
			
		||||
 | 
			
		||||
**Global**
 | 
			
		||||
#### Global
 | 
			
		||||
 | 
			
		||||
Some engines do not provide `globalThis` or `global` or `window`.  A `global`
 | 
			
		||||
variable can be exposed in one line that should be run in the JS engine:
 | 
			
		||||
@ -35,16 +35,17 @@ variable can be exposed in one line that should be run in the JS engine:
 | 
			
		||||
var global = (function(){ return this; }).call(null);
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
**Console**
 | 
			
		||||
#### Console
 | 
			
		||||
 | 
			
		||||
Some engines do not provide a `console` object.  `console.log` can be shimmed
 | 
			
		||||
using the engine functionality.  For example, `hermes`[^1] provides `print()`:
 | 
			
		||||
Some engines do not provide a `console` object but offer other ways to print to
 | 
			
		||||
standard output. For example, Hermes[^1] provides `print()`. A `console` object
 | 
			
		||||
should be created using the engine print function:
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
var console = { log: function(x) { print(x); } };
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
**Binary Data**
 | 
			
		||||
#### Binary Data
 | 
			
		||||
 | 
			
		||||
Some engines do not provide easy ways to exchange binary data.  For example, it
 | 
			
		||||
is common to pass null-terminated arrays, which would truncate XLSX, XLS, and
 | 
			
		||||
@ -53,7 +54,7 @@ other exports.  APIs that accept pointers without length should be avoided.
 | 
			
		||||
Base64 strings are safe for passing between JS and native code, but they should
 | 
			
		||||
only be used when there is no safe way to pass `ArrayBuffer` or `Uint8Array`.
 | 
			
		||||
 | 
			
		||||
**Byte Conventions**
 | 
			
		||||
#### Byte Conventions
 | 
			
		||||
 | 
			
		||||
Java has no native concept of unsigned bytes. Values in a `byte[]` are limited
 | 
			
		||||
to the range `-128 .. 127`. They need to be fixed within the JS engine.
 | 
			
		||||
@ -116,123 +117,12 @@ Swift and Objective-C.
 | 
			
		||||
 | 
			
		||||
This demo has been moved [to a dedicated page](/docs/demos/engines/jsc).
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### JerryScript
 | 
			
		||||
 | 
			
		||||
JerryScript is a lightweight JavaScript engine designed for use in low-memory
 | 
			
		||||
environments like microcontrollers.  As part of the build suite, the project
 | 
			
		||||
generates a C library and a standalone CLI tool.
 | 
			
		||||
environments including microcontrollers.
 | 
			
		||||
 | 
			
		||||
The simplest way to interact with the engine is to pass Base64 strings.
 | 
			
		||||
 | 
			
		||||
:::note Tested Environments
 | 
			
		||||
 | 
			
		||||
This demo was tested in the following environments:
 | 
			
		||||
 | 
			
		||||
| Architecture | Commit    | Date       |
 | 
			
		||||
|:-------------|:----------|:-----------|
 | 
			
		||||
| `darwin-x64` | `ef4cb2b` | 2023-12-08 |
 | 
			
		||||
| `darwin-arm` | `ef4cb2b` | 2023-12-08 |
 | 
			
		||||
| `win11-x64`  | `ef4cb2b` | 2023-12-08 |
 | 
			
		||||
| `win11-arm`  | `ef4cb2b` | 2023-12-08 |
 | 
			
		||||
| `linux-x64`  | `ef4cb2b` | 2023-12-08 |
 | 
			
		||||
| `linux-arm`  | `ef4cb2b` | 2023-12-08 |
 | 
			
		||||
 | 
			
		||||
The Windows tests were run in WSL.
 | 
			
		||||
 | 
			
		||||
Debian and WSL require the `cmake`, `python3` and `python-is-python3` packages.
 | 
			
		||||
 | 
			
		||||
:::
 | 
			
		||||
 | 
			
		||||
:::note pass
 | 
			
		||||
 | 
			
		||||
While applications should link against the official libraries, the standalone tool
 | 
			
		||||
is useful for verifying functionality.
 | 
			
		||||
 | 
			
		||||
:::
 | 
			
		||||
 | 
			
		||||
:::caution pass
 | 
			
		||||
 | 
			
		||||
This demo requires a much larger heap size than is normally used in JerryScript
 | 
			
		||||
deployments! In local testing, the following sizes were needed:
 | 
			
		||||
 | 
			
		||||
- 8192 (8M) for <https://sheetjs.com/pres.xlsx>
 | 
			
		||||
- 65536 (64M) for <https://sheetjs.com/pres.numbers>
 | 
			
		||||
 | 
			
		||||
This works on a Raspberry Pi.
 | 
			
		||||
 | 
			
		||||
:::
 | 
			
		||||
 | 
			
		||||
<details><summary><b>Complete Example</b> (click to show)</summary>
 | 
			
		||||
 | 
			
		||||
Due to limitations of the standalone binary, this demo will encode a test file
 | 
			
		||||
as a Base64 string and directly add it to an amalgamated script.
 | 
			
		||||
 | 
			
		||||
0) Build the library and command line tool with required options:
 | 
			
		||||
 | 
			
		||||
```bash
 | 
			
		||||
git clone --depth=1 https://github.com/jerryscript-project/jerryscript.git
 | 
			
		||||
cd jerryscript
 | 
			
		||||
python tools/build.py --error-messages=ON --logging=ON --mem-heap=8192 --cpointer-32bit=ON
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
1) Download the SheetJS Standalone script, shim script and test file. Move all
 | 
			
		||||
three files to the `jerryscript` cloned repo directory:
 | 
			
		||||
 | 
			
		||||
<ul>
 | 
			
		||||
<li><a href={`https://cdn.sheetjs.com/xlsx-${current}/package/dist/xlsx.full.min.js`}>xlsx.full.min.js</a></li>
 | 
			
		||||
<li><a href={`https://cdn.sheetjs.com/xlsx-${current}/package/dist/shim.min.js`}>shim.min.js</a></li>
 | 
			
		||||
<li><a href="https://sheetjs.com/pres.xlsx">pres.xlsx</a></li>
 | 
			
		||||
</ul>
 | 
			
		||||
 | 
			
		||||
<CodeBlock language="bash">{`\
 | 
			
		||||
curl -LO https://cdn.sheetjs.com/xlsx-${current}/package/dist/shim.min.js
 | 
			
		||||
curl -LO https://cdn.sheetjs.com/xlsx-${current}/package/dist/xlsx.full.min.js
 | 
			
		||||
curl -LO https://sheetjs.com/pres.xlsx`}
 | 
			
		||||
</CodeBlock>
 | 
			
		||||
 | 
			
		||||
2) Bundle the test file and create `payload.js`:
 | 
			
		||||
 | 
			
		||||
```bash
 | 
			
		||||
node -e "fs.writeFileSync('payload.js', 'var payload = \"' + fs.readFileSync('pres.xlsx').toString('base64') + '\";')"
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
3) Create support scripts:
 | 
			
		||||
 | 
			
		||||
- `global.js` creates a `global` variable and defines a fake `console`:
 | 
			
		||||
 | 
			
		||||
```js title="global.js"
 | 
			
		||||
var global = (function(){ return this; }).call(null);
 | 
			
		||||
var console = { log: function(x) { print(x); } };
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
- `jerry.js` will call `XLSX.read` and `XLSX.utils.sheet_to_csv`:
 | 
			
		||||
 | 
			
		||||
```js title="jerry.js"
 | 
			
		||||
/* sheetjs (C) 2013-present  SheetJS -- https://sheetjs.com */
 | 
			
		||||
var wb = XLSX.read(payload, {type:'base64'});
 | 
			
		||||
console.log(XLSX.utils.sheet_to_csv(wb.Sheets[wb.SheetNames[0]]));
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
4) Create the amalgamation `xlsx.jerry.js`:
 | 
			
		||||
 | 
			
		||||
```bash
 | 
			
		||||
cat global.js xlsx.full.min.js payload.js jerry.js > xlsx.jerry.js
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
The final script defines `global` before loading the standalone library.  Once
 | 
			
		||||
ready, it will read the bundled test data and print the contents as CSV.
 | 
			
		||||
 | 
			
		||||
5) Run the script using the `jerry` standalone binary:
 | 
			
		||||
 | 
			
		||||
```bash
 | 
			
		||||
build/bin/jerry xlsx.jerry.js; echo $?
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
If successful, the contents of the test file will be displayed in CSV rows. The
 | 
			
		||||
status code `0` will be printed after the rows.
 | 
			
		||||
 | 
			
		||||
</details>
 | 
			
		||||
This demo has been moved [to a dedicated page](/docs/demos/engines/jerryscript).
 | 
			
		||||
 | 
			
		||||
### Jint
 | 
			
		||||
 | 
			
		||||
@ -240,14 +130,12 @@ Jint is an embeddable JS engine for .NET written in C#.
 | 
			
		||||
 | 
			
		||||
This demo has been moved [to a dedicated page](/docs/demos/engines/jint).
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### Nashorn
 | 
			
		||||
 | 
			
		||||
Nashorn shipped with some versions of Java.  It is now a standalone library.
 | 
			
		||||
 | 
			
		||||
This demo has been moved [to a dedicated page](/docs/demos/engines/nashorn).
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### QuickJS
 | 
			
		||||
 | 
			
		||||
QuickJS is an embeddable JS engine written in C.  It provides a separate set of
 | 
			
		||||
@ -256,14 +144,12 @@ the standalone browser scripts.
 | 
			
		||||
 | 
			
		||||
This demo has been moved [to a dedicated page](/docs/demos/engines/quickjs).
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### Rhino
 | 
			
		||||
 | 
			
		||||
Rhino is an ES3+ engine in Java.
 | 
			
		||||
 | 
			
		||||
This demo has been moved [to a dedicated page](/docs/demos/engines/rhino).
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### V8
 | 
			
		||||
 | 
			
		||||
V8 is an embeddable JS engine written in C++. It powers Chromium and Chrome,
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										143
									
								
								docz/static/jerryscript/sheetjs.jerry.c
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										143
									
								
								docz/static/jerryscript/sheetjs.jerry.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,143 @@
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
 | 
			
		||||
#include "jerryscript.h"
 | 
			
		||||
 | 
			
		||||
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); fseek(f, 0, SEEK_SET); }
 | 
			
		||||
  char *buf = (char *)malloc(fsize * sizeof(char));
 | 
			
		||||
  *sz = fread((void *) buf, 1, fsize, f) - 1;
 | 
			
		||||
  fclose(f);
 | 
			
		||||
  return buf;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
jerry_value_t eval_str(const char *code, size_t sz) {
 | 
			
		||||
  jerry_value_t parsed = jerry_parse(code, sz, NULL);
 | 
			
		||||
  if(jerry_value_is_error(parsed)) return parsed;
 | 
			
		||||
 | 
			
		||||
  jerry_value_t out = jerry_run(parsed);
 | 
			
		||||
  jerry_value_free(parsed);
 | 
			
		||||
 | 
			
		||||
  return out;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static jerry_value_t load_file(const char *filename) {
 | 
			
		||||
  size_t len; char *buf = read_file(filename, &len);
 | 
			
		||||
  if(!buf) return 0;
 | 
			
		||||
 | 
			
		||||
  jerry_value_t out = jerry_arraybuffer(len);
 | 
			
		||||
  jerry_arraybuffer_write(out, 0, (const uint8_t*)buf, len);
 | 
			
		||||
  return out;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
char *pull_str(jerry_value_t str, size_t *sz) {
 | 
			
		||||
  jerry_size_t str_sz = jerry_string_size(str, JERRY_ENCODING_UTF8);
 | 
			
		||||
  jerry_char_t *buf = (jerry_char_t *)malloc(str_sz + 1);
 | 
			
		||||
  jerry_string_to_buffer(str, JERRY_ENCODING_UTF8, buf, str_sz + 1);
 | 
			
		||||
  *sz = str_sz;
 | 
			
		||||
  return (char *)buf;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int main (int argc, char **argv) {
 | 
			
		||||
  int res = 0;
 | 
			
		||||
 | 
			
		||||
  /* Initialize engine */
 | 
			
		||||
  jerry_init(JERRY_INIT_EMPTY);
 | 
			
		||||
 | 
			
		||||
  /* evaluate shim.min.js */
 | 
			
		||||
  {
 | 
			
		||||
    size_t sz; const jerry_char_t *script = (jerry_char_t *)read_file("shim.min.js", &sz);
 | 
			
		||||
    jerry_value_t result = eval_str(script, sz);
 | 
			
		||||
    if(jerry_value_is_error(result)) {
 | 
			
		||||
      fprintf(stderr, "Failed to evaluate shim.min.js");
 | 
			
		||||
      res = 1;
 | 
			
		||||
      goto cleanup;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    jerry_value_free(result);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /* evaluate xlsx.full.min.js */
 | 
			
		||||
  {
 | 
			
		||||
    size_t sz; const jerry_char_t *script = read_file("xlsx.full.min.js", &sz);
 | 
			
		||||
    jerry_value_t result = eval_str(script, sz);
 | 
			
		||||
    if(jerry_value_is_error(result)) {
 | 
			
		||||
      fprintf(stderr, "Failed to evaluate xlsx.full.min.js");
 | 
			
		||||
      res = 2;
 | 
			
		||||
      goto cleanup;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    jerry_value_free(result);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /* load spreadsheet */
 | 
			
		||||
  jerry_value_t ab = load_file(argv[1]);
 | 
			
		||||
  if(!ab || jerry_value_is_error(ab)) {
 | 
			
		||||
    fprintf(stderr, "Failed to read %s", argv[1]);
 | 
			
		||||
    res = 3;
 | 
			
		||||
    goto exeunt;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /* assign to `buf` in the global scope */
 | 
			
		||||
  {
 | 
			
		||||
    /* get `this` */
 | 
			
		||||
    jerry_value_t this = jerry_current_realm();
 | 
			
		||||
    if(jerry_value_is_error(this)) {
 | 
			
		||||
      fprintf(stderr, "Failed to get global object");
 | 
			
		||||
      res = 4;
 | 
			
		||||
      goto exeunt;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* create "buf" str */
 | 
			
		||||
    jerry_value_t prop = jerry_string_sz("buf");
 | 
			
		||||
    if(jerry_value_is_error(this)) {
 | 
			
		||||
      fprintf(stderr, "Failed to create string");
 | 
			
		||||
      res = 5;
 | 
			
		||||
      goto exeunt;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* equivalent of `this["buf"] = buf` */
 | 
			
		||||
    jerry_value_t set = jerry_object_set(this, prop, ab);
 | 
			
		||||
    if(jerry_value_is_error(set)) {
 | 
			
		||||
      fprintf(stderr, "Failed to assign ArrayBuffer");
 | 
			
		||||
      res = 6;
 | 
			
		||||
      goto exeunt;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /* run `var wb = XLSX.read(buf)` */
 | 
			
		||||
  {
 | 
			
		||||
    const jerry_char_t code[] = "var wb = XLSX.read(buf);";
 | 
			
		||||
    jerry_value_t result = eval_str(code, sizeof(code) - 1);
 | 
			
		||||
    if(jerry_value_is_error(result)) {
 | 
			
		||||
      fprintf(stderr, "Failed to parse file");
 | 
			
		||||
      res = 7;
 | 
			
		||||
      goto exeunt;
 | 
			
		||||
    }
 | 
			
		||||
    jerry_value_free(result);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /* run `XLSX.utils.sheet_to_csv(wb.Sheets[wb.SheetNames[0]])` and print result */
 | 
			
		||||
  {
 | 
			
		||||
    const jerry_char_t code[] = "XLSX.utils.sheet_to_csv(wb.Sheets[wb.SheetNames[0]])";
 | 
			
		||||
    jerry_value_t result = eval_str(code, sizeof(code) - 1);
 | 
			
		||||
    if(jerry_value_is_error(result)) {
 | 
			
		||||
      fprintf(stderr, "Failed to generate csv");
 | 
			
		||||
      res = 8;
 | 
			
		||||
    } else {
 | 
			
		||||
      size_t sz; char *buf = pull_str(result, &sz);
 | 
			
		||||
      printf("%s\n", buf);
 | 
			
		||||
    }
 | 
			
		||||
    jerry_value_free(result);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
exeunt:
 | 
			
		||||
  jerry_value_free(ab);
 | 
			
		||||
 | 
			
		||||
cleanup:
 | 
			
		||||
  /* Cleanup engine */
 | 
			
		||||
  jerry_cleanup();
 | 
			
		||||
  return res;
 | 
			
		||||
}
 | 
			
		||||
										
											Binary file not shown.
										
									
								
							| 
		 Before Width: | Height: | Size: 138 KiB After Width: | Height: | Size: 47 KiB  | 
										
											Binary file not shown.
										
									
								
							| 
		 Before Width: | Height: | Size: 40 KiB After Width: | Height: | Size: 39 KiB  | 
		Loading…
	
		Reference in New Issue
	
	Block a user