Skip to content

Instantly share code, notes, and snippets.

@abhi-bit
Created October 18, 2017 04:17
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save abhi-bit/09d0010e20d8acbbc6de2a136fdabffc to your computer and use it in GitHub Desktop.
Save abhi-bit/09d0010e20d8acbbc6de2a136fdabffc to your computer and use it in GitHub Desktop.
parse json using v8::json::parse
#include <cassert>
#include <cstdio>
#include <cstring>
#include <fstream>
#include <iostream>
#include <map>
#include <streambuf>
#include <string>
#include <thread>
#include <unistd.h>
#include <vector>
#include <atomic>
#include <include/v8.h>
#include <include/v8-debug.h>
#include <include/libplatform/libplatform.h>
using namespace std;
using namespace v8;
Isolate* isolate;
Persistent<Context> context_;
Persistent<Function> debug_user_request;
volatile std::atomic<bool> exitflag;
const string currentDateTime() {
time_t now = time(0);
struct tm tstruct;
char buf[80];
tstruct = *localtime(&now);
strftime(buf, sizeof(buf), "%Y-%m-%d.%X", &tstruct);
return buf;
}
int AsciiToUtf16(const char* input_buffer, uint16_t* output_buffer) {
int i;
for (i = 0; input_buffer[i] != '\0'; ++i) {
// ASCII does not use chars > 127, but be careful anyway.
output_buffer[i] = static_cast<unsigned char>(input_buffer[i]);
}
output_buffer[i] = 0;
return i;
}
const char* ToCString(const String::Utf8Value& value) {
return *value ? *value : "<string conversion failed>";
}
const char* ToJson(Isolate* isolate, Handle<Value> object) {
HandleScope handle_scope(isolate);
Local<Context> context = isolate->GetCurrentContext();
Local<Object> global = context->Global();
Local<Object> JSON = global->Get(String::NewFromUtf8(isolate, "JSON"))->ToObject();
Local<Function> JSON_stringify = Local<Function>::Cast(
JSON->Get(
String::NewFromUtf8(isolate, "stringify")));
Local<Value> result;
Local<Value> args[1];
args[0] = { object };
result = JSON_stringify->Call(context->Global(), 1, args);
String::Utf8Value str(result->ToString());
return ToCString(str);
}
string ObjectToString(Local<Value> value) {
String::Utf8Value utf8_value(value);
return string(*utf8_value);
}
string ToString(Isolate* isolate, Handle<Value> object) {
HandleScope handle_scope(isolate);
Local<Context> context = isolate->GetCurrentContext();
Local<Object> global = context->Global();
Local<Object> JSON = global->Get(String::NewFromUtf8(isolate, "JSON"))->ToObject();
Local<Function> JSON_stringify =
Local<Function>::Cast(JSON->Get(
String::NewFromUtf8(isolate, "stringify")));
Local<Value> result;
Local<Value> args[1];
args[0] = { object };
result = JSON_stringify->Call(context->Global(), 1, args);
return ObjectToString(result);
}
void Print(const FunctionCallbackInfo<Value>& args) {
bool first = true;
for (int i = 0; i < args.Length(); i++) {
HandleScope handle_scope(args.GetIsolate());
if (first) {
first = false;
} else {
printf(" ");
}
String::Utf8Value str(args[i]);
const char* cstr = ToJson(args.GetIsolate(), args[i]);
printf("%s", cstr);
}
printf("\n");
fflush(stdout);
}
class ArrayBufferAllocator : public v8::ArrayBuffer::Allocator {
public:
virtual void* Allocate(size_t length) {
void* data = AllocateUninitialized(length);
return data == NULL ? data : memset(data, 0, length);
}
virtual void* AllocateUninitialized(size_t length) { return malloc(length); }
virtual void Free(void* data, size_t) { free(data); }
};
void ProcessDebugUserRequest(string request) {
Locker locker(isolate);
Isolate::Scope isolate_Scope(isolate);
HandleScope handle_Scope(isolate);
Local<Context> context = Local<Context>::New(isolate, context_);
Context::Scope context_scope(context);
Handle<Value> args[1];
args[0] = JSON::Parse(
String::NewFromUtf8(isolate, request.c_str()));
Local<Function> handle_user_req_fun = Local<Function>::New(
isolate, debug_user_request);
handle_user_req_fun->Call(context->Global(), 1, args);
auto options = args[0]->ToObject(context).ToLocalChecked();
auto option_names = options->GetOwnPropertyNames();
for (int i = 0; i < static_cast<int>(option_names->Length()); i++) {
auto key = option_names->Get(i);
auto value = options->Get(key);
if (key->IsString() && value->IsString()) {
v8::String::Utf8Value utf8_key(key);
v8::String::Utf8Value utf8_val(value);
std::cout << "key: " << *utf8_key << " value: " << *utf8_val << std::endl;
}
}
}
void ProcessRequest() {
string prefix("{\"type\": \"json\", \"client\": \"Chrome Canary\", \"counter\":");
int i = 0;
while(exitflag) {
string request;
request.append(prefix);
request.append(to_string(i++));
request.append("}");
ProcessDebugUserRequest(request);
}
}
int main(int argc, char* argv[]) {
std::cout.setf( std::ios_base::unitbuf );
V8::InitializeICU();
V8::InitializeExternalStartupData(argv[0]);
Platform* platform = platform::CreateDefaultPlatform();
V8::InitializePlatform(platform);
V8::Initialize();
ArrayBufferAllocator allocator;
Isolate::CreateParams create_params;
create_params.array_buffer_allocator = &allocator;
isolate = Isolate::New(create_params);
{
Isolate::Scope isolate_scope(isolate);
HandleScope handle_scope(isolate);
Local<ObjectTemplate> global = ObjectTemplate::New(isolate);
global->Set(String::NewFromUtf8(isolate, "log"),
FunctionTemplate::New(isolate, Print));
Local<Context> context = Context::New(isolate, NULL, global);
context_.Reset(isolate, context);
Context::Scope context_scope(context);
ifstream file_name(argv[1]);
string src((istreambuf_iterator<char>(file_name)),
istreambuf_iterator<char>());
Local<String> source =
String::NewFromUtf8(isolate, src.c_str(),
NewStringType::kNormal).ToLocalChecked();
Local<Script> script = Script::Compile(context,
source).ToLocalChecked();
Local<Value> result = script->Run(context).ToLocalChecked();
Local<String> handle_user_req =
String::NewFromUtf8(isolate,
"DebugUserRequest", NewStringType::kNormal)
.ToLocalChecked();
Local<Value> handle_user_req_val;
if(!context->Global()->Get(context,
handle_user_req).ToLocal(&handle_user_req_val))
cout << "Failed to grab DebugUserRequest function " << endl;
Local<Function> handle_user_req_fun =
Local<Function>::Cast(handle_user_req_val);
assert(handle_user_req_fun->IsFunction());
debug_user_request.Reset(isolate, handle_user_req_fun);
}
exitflag = true;
cout << __FILE__ << __FUNCTION__ << __LINE__
<< "STARTING UP Process thread" << endl;
thread send_debug_user_req_thr(ProcessRequest);
sleep(1);
exitflag = false;
isolate->Dispose();
V8::Dispose();
V8::ShutdownPlatform();
delete platform;
return 0;
}
function DebugUserRequest(doc) {
if (doc.type === "json") {
log("Logged from JS world", doc.client, doc.counter);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment