| 
									
										
										
										
											2023-05-21 02:11:51 +00:00
										 |  |  | /* sheetjs.v8 (C) SheetJS -- https://sheetjs.com */ | 
					
						
							|  |  |  | /* based on the official V8 samples ("BSD-3-Clause") */ | 
					
						
							|  |  |  | #include <stdio.h>
 | 
					
						
							|  |  |  | #include <stdlib.h>
 | 
					
						
							|  |  |  | #include <string.h>
 | 
					
						
							|  |  |  | #include "include/libplatform/libplatform.h"
 | 
					
						
							|  |  |  | #include "include/v8.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; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-26 23:05:59 +00:00
										 |  |  | v8::Local<v8::Value> eval_code(v8::Isolate *isolate, v8::Local<v8::Context> context, char* code, size_t sz = -1) { | 
					
						
							|  |  |  |   v8::Local<v8::String> source = v8::String::NewFromUtf8(isolate, code, v8::NewStringType::kNormal, sz).ToLocalChecked(); | 
					
						
							| 
									
										
										
										
											2023-05-21 02:11:51 +00:00
										 |  |  |   v8::Local<v8::Script> script = v8::Script::Compile(context, source).ToLocalChecked(); | 
					
						
							|  |  |  |   return script->Run(context).ToLocalChecked(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | #define EVAL_CODE(x) eval_code(isolate, context, (char *)x)
 | 
					
						
							| 
									
										
										
										
											2023-08-26 23:05:59 +00:00
										 |  |  | #define EVAL_CODE2(x,sz) eval_code(isolate, context, (char *)x, sz)
 | 
					
						
							| 
									
										
										
										
											2023-05-21 02:11:51 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | int main(int argc, char* argv[]) { | 
					
						
							|  |  |  |   /* initialize -- this part is from the hello world example */ | 
					
						
							|  |  |  |   v8::V8::InitializeICUDefaultLocation(argv[0]); | 
					
						
							|  |  |  |   v8::V8::InitializeExternalStartupData(argv[0]); | 
					
						
							|  |  |  |   std::unique_ptr<v8::Platform> platform = v8::platform::NewDefaultPlatform(); | 
					
						
							|  |  |  |   v8::V8::InitializePlatform(platform.get()); | 
					
						
							|  |  |  |   v8::V8::Initialize(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   v8::Isolate::CreateParams create_params; | 
					
						
							|  |  |  |   create_params.array_buffer_allocator = v8::ArrayBuffer::Allocator::NewDefaultAllocator(); | 
					
						
							|  |  |  |   v8::Isolate* isolate = v8::Isolate::New(create_params); | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     v8::Isolate::Scope isolate_scope(isolate); | 
					
						
							|  |  |  |     v8::HandleScope handle_scope(isolate); | 
					
						
							|  |  |  |     v8::Local<v8::Context> context = v8::Context::New(isolate); | 
					
						
							|  |  |  |     v8::Context::Scope context_scope(context); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* load library */ | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       /* read file */ | 
					
						
							|  |  |  |       size_t sz; char *file = read_file("xlsx.full.min.js", &sz); | 
					
						
							|  |  |  |       if(!file) { perror("Error reading xlsx.full.min.js"); return 1; } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       /* evaluate */ | 
					
						
							| 
									
										
										
										
											2023-08-26 23:05:59 +00:00
										 |  |  |       v8::Local<v8::Value> result = EVAL_CODE2(file, sz); | 
					
						
							| 
									
										
										
										
											2023-05-21 02:11:51 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |       /* free */ | 
					
						
							|  |  |  |       free(file); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* get version string */ | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       v8::Local<v8::Value> result = EVAL_CODE("XLSX.version"); | 
					
						
							|  |  |  |       v8::String::Utf8Value vers(isolate, result); | 
					
						
							|  |  |  |       printf("SheetJS library version %s\n", *vers); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* read file */ | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       /* read bytes */ | 
					
						
							|  |  |  |       size_t sz; char *file = read_file(argv[1], &sz); | 
					
						
							|  |  |  |       if(!file) { perror("Error reading file"); return 1; } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       /* copy into array buffer and assign to `buf` in the global scope */ | 
					
						
							|  |  |  |       { | 
					
						
							|  |  |  |         std::unique_ptr<v8::BackingStore> back = v8::ArrayBuffer::NewBackingStore(isolate, sz); | 
					
						
							|  |  |  |         memcpy(back->Data(), file, sz); | 
					
						
							|  |  |  |         v8::Local<v8::ArrayBuffer> ab = v8::ArrayBuffer::New(isolate, std::move(back)); | 
					
						
							|  |  |  |         v8::Maybe<bool> res = context->Global()->Set(context, v8::String::NewFromUtf8Literal(isolate, "buf"), ab); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       printf("Loaded file %s\n", argv[1]); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* parse workbook and assign to global `wb` property */ | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       v8::Local<v8::Value> result = EVAL_CODE("globalThis.wb = XLSX.read(buf)"); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* print CSV of first worksheet */ | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       v8::Local<v8::Value> result = EVAL_CODE("XLSX.utils.sheet_to_csv(wb.Sheets[wb.SheetNames[0]])"); | 
					
						
							|  |  |  |       v8::String::Utf8Value csv(isolate, result); | 
					
						
							|  |  |  |       printf("%s\n", *csv); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // write sheetjsw.xlsb
 | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       v8::Local<v8::Value> result = EVAL_CODE("XLSX.write(wb, {type:'array', bookType:'xlsb'})"); | 
					
						
							|  |  |  |       v8::Local<v8::ArrayBuffer> ab = v8::Local<v8::ArrayBuffer>::Cast(result); | 
					
						
							|  |  |  |       FILE *f = fopen("sheetjsw.xlsb", "wb"); fwrite((char *)ab->Data(), 1, ab->ByteLength(), f); fclose(f); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* cleanup -- this part is from the hello world example */ | 
					
						
							|  |  |  |   isolate->Dispose(); | 
					
						
							|  |  |  |   v8::V8::Dispose(); | 
					
						
							|  |  |  |   v8::V8::DisposePlatform(); | 
					
						
							|  |  |  |   delete create_params.array_buffer_allocator; | 
					
						
							|  |  |  |   return 0; | 
					
						
							|  |  |  | } |