forked from sheetjs/docs.sheetjs.com
112 lines
2.8 KiB
C
112 lines
2.8 KiB
C
|
#include <stdio.h>
|
||
|
#include <stdlib.h>
|
||
|
#include <JavaScriptCore/JavaScript.h>
|
||
|
|
||
|
/* simple wrapper to read the entire script file */
|
||
|
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(buf, 1, fsize, f);
|
||
|
fclose(f);
|
||
|
return buf;
|
||
|
}
|
||
|
|
||
|
#define JS_STR_TO_C \
|
||
|
JSStringRef str = JSValueToStringCopy(ctx, result, NULL); \
|
||
|
size_t sz = JSStringGetMaximumUTF8CStringSize(str); \
|
||
|
char *buf = (char *)malloc(sz); \
|
||
|
JSStringGetUTF8CString(str, buf, sz); \
|
||
|
|
||
|
#define DOIT(cmd) \
|
||
|
JSStringRef script = JSStringCreateWithUTF8CString(cmd); \
|
||
|
JSValueRef result = JSEvaluateScript(ctx, script, NULL, NULL, 0, NULL); \
|
||
|
JSStringRelease(script);
|
||
|
|
||
|
int main(int argc, char **argv) {
|
||
|
int res = 0;
|
||
|
size_t sz = 0;
|
||
|
char *file = NULL;
|
||
|
|
||
|
/* initialize */
|
||
|
JSGlobalContextRef ctx = JSGlobalContextCreate(NULL);
|
||
|
/* JSC does not expose a standard "global" by default */
|
||
|
{ DOIT("var global = (function(){ return this; }).call(null);") }
|
||
|
|
||
|
/* load library */
|
||
|
{
|
||
|
file = read_file("xlsx.full.min.js", &sz);
|
||
|
DOIT(file);
|
||
|
free(file);
|
||
|
}
|
||
|
|
||
|
/* get version string */
|
||
|
{
|
||
|
DOIT("XLSX.version")
|
||
|
|
||
|
if(!JSValueIsString(ctx, result)) {
|
||
|
printf("Could not get SheetJS version.\n");
|
||
|
res = 1; goto cleanup;
|
||
|
}
|
||
|
|
||
|
JS_STR_TO_C
|
||
|
|
||
|
printf("SheetJS library version %s\n", buf);
|
||
|
free(buf);
|
||
|
JSStringRelease(str);
|
||
|
}
|
||
|
|
||
|
/* read file */
|
||
|
file = read_file(argv[1], &sz);
|
||
|
{
|
||
|
/* push data to JSC */
|
||
|
JSValueRef u8 = JSObjectMakeTypedArrayWithBytesNoCopy(ctx, kJSTypedArrayTypeUint8Array, file, sz, NULL, NULL, NULL);
|
||
|
|
||
|
/* assign to `global.buf` */
|
||
|
JSObjectRef global = JSContextGetGlobalObject(ctx);
|
||
|
JSStringRef key = JSStringCreateWithUTF8CString("buf");
|
||
|
JSObjectSetProperty(ctx, global, key, u8, 0, NULL);
|
||
|
JSStringRelease(key);
|
||
|
}
|
||
|
|
||
|
/* parse workbook and print CSV */
|
||
|
{
|
||
|
DOIT(
|
||
|
"var wb = XLSX.read(global.buf);"
|
||
|
"var ws = wb.Sheets[wb.SheetNames[0]];"
|
||
|
"XLSX.utils.sheet_to_csv(ws)"
|
||
|
)
|
||
|
|
||
|
if(!JSValueIsString(ctx, result)) {
|
||
|
printf("Could not generate CSV.\n");
|
||
|
res = 2; goto cleanup;
|
||
|
}
|
||
|
|
||
|
JS_STR_TO_C
|
||
|
|
||
|
printf("%s\n", buf);
|
||
|
free(buf);
|
||
|
JSStringRelease(str);
|
||
|
}
|
||
|
|
||
|
/* write file */
|
||
|
{
|
||
|
DOIT("XLSX.write(wb, {type:'buffer', bookType:'xlsb'});")
|
||
|
|
||
|
/* pull Uint8Array data back to C */
|
||
|
JSObjectRef u8 = JSValueToObject(ctx, result, NULL);
|
||
|
size_t sz = JSObjectGetTypedArrayLength(ctx, u8, NULL);
|
||
|
char *buf = (char *)JSObjectGetTypedArrayBytesPtr(ctx, u8, NULL);
|
||
|
|
||
|
/* save file */
|
||
|
FILE *f = fopen("sheetjsw.xlsb", "wb"); fwrite(buf, 1, sz, f); fclose(f);
|
||
|
}
|
||
|
|
||
|
cleanup:
|
||
|
// Release the JavaScript context
|
||
|
JSGlobalContextRelease(ctx);
|
||
|
if(file) free(file);
|
||
|
|
||
|
return res;
|
||
|
}
|