Skip to content

Instantly share code, notes, and snippets.

@shimondoodkin
Created October 14, 2010 02:43
Show Gist options
  • Select an option

  • Save shimondoodkin/625445 to your computer and use it in GitHub Desktop.

Select an option

Save shimondoodkin/625445 to your computer and use it in GitHub Desktop.
#include <v8.h>
#include <node.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <dirent.h>
using namespace std;
using namespace node;
using namespace v8;
extern "C" void init (Handle<Object>);
static Handle<Value> OpendirAsync (const Arguments&);
static int Opendir (eio_req *);
static int Opendir_After (eio_req *);
/*
static Handle<Value> DoSomething2Async (const Arguments&);
static int DoSomething2 (eio_req *);
static int DoSomething2_After (eio_req *);
*?
/*
static Handle<Value> ReadDir(const Arguments& args) {
HandleScope scope;
if (args.Length() < 1 || !args[0]->IsString()) {
return THROW_BAD_ARGS;
}
String::Utf8Value path(args[0]->ToString());
if (args[1]->IsFunction()) {
ASYNC_CALL(readdir, args[1], *path, 0 ) // 0= flags
} else {
DIR *dir = opendir(*path);
if (!dir) return ThrowException(ErrnoException(errno, NULL, "", *path));
struct dirent *ent;
Local<Array> files = Array::New();
char *name;
int i = 0;
while (ent = readdir(dir)) {
name = ent->d_name;
if (name[0] != '.' || (name[1] && (name[1] != '.' || name[2]))) {
files->Set(Integer::New(i), String::New(name));
i++;
}
}
closedir(dir);
return scope.Close(files);
}
}
*/
struct opendir_simple_request {
//int y;
DIR *dir;
Persistent<Function> cb;
Persistent<String> path;
// maybe it matters to put the char[] last? not sure.
//char name[1];
};
static Handle<Value> OpendirAsync (const Arguments& args) {
HandleScope scope;
const char *usage = "usage: Opendir(path, cb)";
if (args.Length() != 2) {
return ThrowException(Exception::Error(String::New(usage)));
}
Local<Function> cb = Local<Function>::Cast(args[1]);
Local<String> path = Local<String>::Cast(args[0]);
opendir_simple_request *sr = (opendir_simple_request *)
malloc(sizeof(struct opendir_simple_request) + 1);
sr->cb = Persistent<Function>::New(cb);
sr->path = Persistent<String>::New(path);
eio_custom(Opendir, EIO_PRI_DEFAULT, Opendir_After, sr);
ev_ref(EV_DEFAULT_UC);
return Undefined();
}
// this function happens on the thread pool
static int Opendir (eio_req *req) {
struct opendir_simple_request * sr = (struct opendir_simple_request *)req->data;
//sleep(2); // just to make it less pointless to be async.
String::Utf8Value path(sr->path->ToString());
DIR *dir = opendir(*path);
sr->dir=dir;
//req->result = sr->x + sr->y;
return 0;
}
static int Opendir_After (eio_req *req) {
HandleScope scope;
ev_unref(EV_DEFAULT_UC);
struct opendir_simple_request * sr = (struct opendir_simple_request *)req->data;
Local<Value> argv[1];
//argv[1] = Integer::New(req->result);
External <Handle> ex((void **)sr->dir);
argv[0] = ex;
argv[0] = Local<Value>::New(Null());
//argv[0] = Local<Value>::New(Null());
//argv[0] = Local<Value>::New(Null());
//v8::Handle<v8::External> class_ptr
//v8::Handle<v8::External> class_ptr = v8::External::New(foo);
//argv[0]= class_ptr;
//static v8::Local<T> v8::Local<T>::New(v8::Handle<T>) [with T = v8::Value]
//Handle<DIR> x(sr->dir);
// argv[0] = Local<DIR>::New(sr->dir);
//argv[0] = Persistent<Value>::New((sr->dir));
//argv[0] = Handle::New(sr->dir);
//argv[2] = String::New(sr->name);
if (!sr->dir)
{
//int errno=1;
ThrowException(Exception::Error(String::New("Opendir error...")));
//return ThrowException(ErrnoException(errno, NULL, "", *path));
}
TryCatch try_catch;
sr->cb->Call(Context::GetCurrent()->Global(), 1, argv);
if (try_catch.HasCaught()) {
FatalException(try_catch);
}
closedir(sr->dir);
sr->cb.Dispose();
sr->path.Dispose();
free(sr);
return 0;
}
/*
struct simple2_request {
int x;
int y;
Persistent<Function> cb;
Local<Value> js_result;
};
static Handle<Value> DoSomething2Async (const Arguments& args) {
HandleScope scope;
const char *usage = "usage: doSomething2(x, y, cb)";
if (args.Length() != 3) {
return ThrowException(Exception::Error(String::New(usage)));
}
int x = args[0]->Int32Value();
int y = args[1]->Int32Value();
Local<Function> cb = Local<Function>::Cast(args[2]);
simple2_request *sr = (simple2_request *)
malloc(sizeof(struct simple2_request));
sr->cb = Persistent<Function>::New(cb);
sr->x = x;
sr->y = y;
eio_custom(DoSomething2, EIO_PRI_DEFAULT, DoSomething2_After, sr);
ev_ref(EV_DEFAULT_UC);
return Undefined();
}
// this function happens on the thread pool
static int DoSomething2 (eio_req *req) {
HandleScope scope;
struct simple2_request *sr = (struct simple2_request *)req->data;
sr->js_result = scope.Close(Integer::New(sr->x + sr->y));
return 0;
}
static int DoSomething2_After (eio_req *req) {
HandleScope scope;
ev_unref(EV_DEFAULT_UC);
struct simple2_request * sr = (struct simple2_request *)req->data;
Local<Value> argv[3];
argv[0] = Local<Value>::New(Null());
argv[1] = sr->js_result;
TryCatch try_catch;
sr->cb->Call(Context::GetCurrent()->Global(), 2, argv);
if (try_catch.HasCaught()) {
FatalException(try_catch);
}
sr->cb.Dispose();
free(sr);
return 0;
}
*/
extern "C" void init (Handle<Object> target) {
HandleScope scope;
NODE_SET_METHOD(target, "Opendir", OpendirAsync);
//NODE_SET_METHOD(target, "doSomething2", DoSomething2Async);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment