/* sheetjs-hermes.cpp Copyright (c) SheetJS LLC. */ #include #include "hermes/hermes.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); fclose(f); return buf; } /* Unfortunately the library provides no C-friendly Buffer classes */ class CBuffer : public facebook::jsi::Buffer { public: CBuffer(const uint8_t *data, size_t size) : buf(data), sz(size) {} size_t size() const override { return sz; } const uint8_t *data() const override { return buf; } private: const uint8_t *buf; size_t sz; }; /* ArrayBuffer constructor expects MutableBuffer*/ class CMutableBuffer : public facebook::jsi::MutableBuffer { public: CMutableBuffer(uint8_t *data, size_t size) : buf(data), sz(size) {} size_t size() const override { return sz; } uint8_t *data() override { return buf; } private: uint8_t *buf; size_t sz; }; int main(int argc, char **argv) { std::unique_ptr rt(facebook::hermes::makeHermesRuntime()); /* setup */ try { auto src = std::make_shared( "var global = (function(){ return this; }).call(null);" "var console = { log: function(x) { print(x); } };" ); auto js = rt->prepareJavaScript(src, std::string("")); rt->evaluatePreparedJavaScript(js); } catch (const facebook::jsi::JSIException &e) { std::cerr << "JavaScript terminated via uncaught exception: " << e.what() << '\n'; return 1; } /* load SheetJS library */ try { size_t sz; char *xlsx_full_min_js = read_file("xlsx.full.min.js", &sz); auto src = std::make_shared(CBuffer((uint8_t *)xlsx_full_min_js, sz)); auto js = rt->prepareJavaScript(src, std::string("xlsx.full.min.js")); rt->evaluatePreparedJavaScript(js); } catch (const facebook::jsi::JSIException &e) { std::cerr << "JavaScript terminated via uncaught exception: " << e.what() << '\n'; return 1; } /* print library version */ try { auto src = std::make_shared( "console.log('SheetJS Library Version: ' + XLSX.version)" ); auto js = rt->prepareJavaScript(src, std::string("")); rt->evaluatePreparedJavaScript(js); } catch (const facebook::jsi::JSIException &e) { std::cerr << "JavaScript terminated via uncaught exception: " << e.what() << '\n'; return 1; } try { /* load payload as ArrayBuffer */ size_t sz; char *data = read_file(argv[1], &sz); auto payload = std::make_shared(CMutableBuffer((uint8_t *)data, sz)); auto ab = facebook::jsi::ArrayBuffer(*rt, payload); /* define stub function to read and convert first sheet to CSV */ auto src = std::make_shared( "(function(buf) {" "var wb = XLSX.read(buf);" "return XLSX.utils.sheet_to_csv(wb.Sheets[wb.SheetNames[0]]);" "})" ); auto js = rt->prepareJavaScript(src, std::string("")); auto func = rt->evaluatePreparedJavaScript(js); /* call stub function and capture result */ auto csv = func.asObject(*rt).asFunction(*rt).call(*rt, ab); /* interpret as utf8 and print to stdout */ std::string str = csv.getString(*rt).utf8(*rt); std::cout << str << std::endl; } catch (const facebook::jsi::JSIException &e) { std::cerr << "JavaScript terminated via uncaught exception: " << e.what() << std::endl; return 1; } return 0; }