RTBKit
0.9
Open-source framework to create real-time ad bidding systems.
|
00001 /* utils_js.cc 00002 26 November 2010 00003 Copyright (c) 2010 Datacratic. All rights reserved. 00004 00005 */ 00006 00007 #include "v8.h" 00008 #include "utils_js.h" 00009 #include "soa/js/js_registry.h" 00010 #include "soa/js/js_wrapped.h" 00011 #include "jml/utils/smart_ptr_utils.h" 00012 #include "jml/utils/filter_streams.h" 00013 #include "jml/utils/guard.h" 00014 #include <iostream> 00015 #include <string> 00016 #include <unistd.h> 00017 #include <fcntl.h> 00018 #include <stdio.h> 00019 00020 using namespace v8; 00021 using namespace std; 00022 using namespace node; 00023 00024 namespace Datacratic { 00025 namespace JS { 00026 00027 const char * const utilsModule = "sync_utils"; 00028 00029 00030 /*****************************************************************************/ 00031 /* FOR EACH LINE */ 00032 /*****************************************************************************/ 00033 00034 static Handle<v8::Value> 00035 forEachLine(const Arguments & args) 00036 { 00037 try { 00038 string filename = getArg(args, 0, "filename"); 00039 v8::Local<v8::Function> fn = getArg(args, 1, "callback"); 00040 //cerr << "fn = " << cstr(fn) << endl; 00041 00042 bool hadError = false; 00043 00044 ML::filter_istream stream(filename); 00045 if (stream.fail() || stream.bad()) 00046 throw ML::Exception("couldn't open filename %s: %s", 00047 filename.c_str(), strerror(errno)); 00048 00049 auto onLine = [&] (const std::string & line, int lineNum) 00050 { 00051 v8::HandleScope scope; 00052 int argc = 2; 00053 v8::Handle<v8::Value> argv[argc]; 00054 argv[0] = JS::toJS(line); 00055 argv[1] = JS::toJS(lineNum); 00056 00057 v8::Handle<v8::Value> result 00058 = fn->Call(args.This(), argc, argv); 00059 00060 // Exception? 00061 if (result.IsEmpty()) hadError = true; 00062 }; 00063 00064 int numLines = 0; 00065 00066 while (stream && !hadError) { 00067 string line; 00068 std::getline(stream, line); 00069 00070 if (line == "" && stream.gcount() == 0 && stream.eof()) 00071 break; 00072 00073 if (line == "" && stream.fail()) 00074 throw ML::Exception("stream in failed mode"); 00075 00076 if (line == "" && stream.bad()) 00077 throw ML::Exception("steam is bad"); 00078 00079 onLine(line, numLines); 00080 ++numLines; 00081 } 00082 00083 return JS::toJS(numLines); 00084 } HANDLE_JS_EXCEPTIONS; 00085 } 00086 00087 static Handle<v8::Value> 00088 runCmd(const Arguments & args) 00089 { 00090 try { 00091 string cmdStr = getArg(args, 0, "cmd"); 00092 const char * cmd = cmdStr.c_str(); 00093 FILE* pipe = popen(cmd, "r"); 00094 if (!pipe) 00095 return JS::toJS("ERROR"); 00096 char buffer[128]; 00097 std::string result = ""; 00098 while(!feof(pipe)) { 00099 if(fgets(buffer, 128, pipe) != NULL) 00100 result += buffer; 00101 } 00102 pclose(pipe); 00103 00104 return JS::toJS(result); 00105 00106 /* string filename = getArg(args, 0, "filename"); 00107 int code = system(filename.c_str()); 00108 return JS::toJS(code);*/ 00109 } HANDLE_JS_EXCEPTIONS; 00110 } 00111 00112 00113 00114 /*****************************************************************************/ 00115 /* INITIALIZATION */ 00116 /*****************************************************************************/ 00117 00118 // Node.js initialization function; called to set up the utils object 00119 extern "C" void 00120 init(Handle<v8::Object> target) 00121 { 00122 Datacratic::JS::registry.init(target, utilsModule); 00123 00124 static Persistent<FunctionTemplate> fel 00125 = v8::Persistent<FunctionTemplate>::New 00126 (v8::FunctionTemplate::New(forEachLine)); 00127 target->Set(String::NewSymbol("forEachLine"), fel->GetFunction()); 00128 00129 static Persistent<FunctionTemplate> rc 00130 = v8::Persistent<FunctionTemplate>::New 00131 (v8::FunctionTemplate::New(runCmd)); 00132 target->Set(String::NewSymbol("runCmd"), rc->GetFunction()); 00133 } 00134 00135 00136 } // namespace JS 00137 } // namespace utils