Skip to content

Commit

Permalink
wrap parser because EventEmitter is pure-JS as of node 0.5.x
Browse files Browse the repository at this point in the history
should fix GitHub issue #19
  • Loading branch information
astro committed Aug 16, 2011
1 parent 59b9564 commit 2f24b62
Show file tree
Hide file tree
Showing 5 changed files with 80 additions and 27 deletions.
2 changes: 1 addition & 1 deletion bench.js
@@ -1,7 +1,7 @@
var sys = require('sys');
var node_xml = require("node-xml");
var libxml = require("libxmljs");
var expat = require('./build/default/node-expat');
var expat = require('./lib/node-expat');

function NodeXmlParser() {
var parser = new node_xml.SaxParser(function(cb) { });
Expand Down
38 changes: 38 additions & 0 deletions lib/node-expat.js
@@ -0,0 +1,38 @@
var EventEmitter = require('events').EventEmitter;
var util = require('util');
var expat = require('../build/default/node-expat');

/**
* Simple wrapper because EventEmitter has turned pure-JS as of node
* 0.5.x.
*/
exports.Parser = function(encoding) {
this.parser = new expat.Parser(encoding);

var that = this;
this.parser.emit = function() {
that.emit.apply(that, arguments);
};
};
util.inherits(exports.Parser, EventEmitter);

exports.Parser.prototype.parse = function(buf, isFinal) {
return this.parser.parse(buf, isFinal);
};

exports.Parser.prototype.setEncoding = function(encoding) {
return this.parser.setEncoding(encoding);
};

exports.Parser.prototype.getError = function() {
return this.parser.getError();
};
exports.Parser.prototype.stop = function() {
return this.parser.stop();
};
exports.Parser.prototype.pause = function() {
return this.stop();
};
exports.Parser.prototype.resume = function() {
return this.parser.resume();
};
63 changes: 39 additions & 24 deletions node-expat.cc
@@ -1,6 +1,6 @@
#include <node.h>
#include <node_version.h>
#include <node_events.h>
#include <node_object_wrap.h>
#include <node_buffer.h>
extern "C" {
#include <expat.h>
Expand All @@ -12,23 +12,22 @@ using namespace node;
static Persistent<String> sym_startElement, sym_endElement,
sym_startCdata, sym_endCdata,
sym_text, sym_processingInstruction,
sym_comment, sym_xmlDecl, sym_entityDecl;
sym_comment, sym_xmlDecl, sym_entityDecl,
sym_emit;

class Parser : public EventEmitter {
class Parser : public ObjectWrap {
public:
static void Initialize(Handle<Object> target)
{
HandleScope scope;
Local<FunctionTemplate> t = FunctionTemplate::New(New);

t->Inherit(EventEmitter::constructor_template);
t->InstanceTemplate()->SetInternalFieldCount(1);

NODE_SET_PROTOTYPE_METHOD(t, "parse", Parse);
NODE_SET_PROTOTYPE_METHOD(t, "setEncoding", SetEncoding);
NODE_SET_PROTOTYPE_METHOD(t, "getError", GetError);
NODE_SET_PROTOTYPE_METHOD(t, "stop", Stop);
NODE_SET_PROTOTYPE_METHOD(t, "pause", Stop); // Alias for node stream conventions
NODE_SET_PROTOTYPE_METHOD(t, "resume", Resume);

target->Set(String::NewSymbol("Parser"), t->GetFunction());
Expand All @@ -42,6 +41,7 @@ class Parser : public EventEmitter {
sym_comment = NODE_PSYMBOL("comment");
sym_xmlDecl = NODE_PSYMBOL("xmlDecl");
sym_entityDecl = NODE_PSYMBOL("entityDecl");
sym_emit = NODE_PSYMBOL("emit");
}

protected:
Expand All @@ -65,7 +65,7 @@ class Parser : public EventEmitter {
}

Parser(const XML_Char *encoding)
: EventEmitter()
: ObjectWrap()
{
parser = XML_ParserCreate(encoding);
assert(parser != NULL);
Expand Down Expand Up @@ -260,8 +260,10 @@ class Parser : public EventEmitter {
attr->Set(String::New(atts1[0]), String::New(atts1[1]));

/* Trigger event */
Handle<Value> argv[2] = { String::New(name), attr };
parser->Emit(sym_startElement, 2, argv);
Handle<Value> argv[3] = { sym_startElement,
String::New(name),
attr };
parser->Emit(3, argv);
}

static void EndElement(void *userData,
Expand All @@ -270,26 +272,26 @@ class Parser : public EventEmitter {
Parser *parser = reinterpret_cast<Parser *>(userData);

/* Trigger event */
Handle<Value> argv[1] = { String::New(name) };
parser->Emit(sym_endElement, 1, argv);
Handle<Value> argv[2] = { sym_endElement, String::New(name) };
parser->Emit(2, argv);
}

static void StartCdata(void *userData)
{
Parser *parser = reinterpret_cast<Parser *>(userData);

/* Trigger event */
Handle<Value> argv[0] = {};
parser->Emit(sym_startCdata, 0, argv);
Handle<Value> argv[1] = { sym_startCdata };
parser->Emit(1, argv);
}

static void EndCdata(void *userData)
{
Parser *parser = reinterpret_cast<Parser *>(userData);

/* Trigger event */
Handle<Value> argv[0] = {};
parser->Emit(sym_endCdata, 0, argv);
Handle<Value> argv[1] = { sym_endCdata };
parser->Emit(1, argv);
}

static void Text(void *userData,
Expand All @@ -298,8 +300,9 @@ class Parser : public EventEmitter {
Parser *parser = reinterpret_cast<Parser *>(userData);

/* Trigger event */
Handle<Value> argv[1] = { String::New(s, len) };
parser->Emit(sym_text, 1, argv);
Handle<Value> argv[2] = { sym_text,
String::New(s, len) };
parser->Emit(2, argv);
}

static void ProcessingInstruction(void *userData,
Expand All @@ -308,8 +311,10 @@ class Parser : public EventEmitter {
Parser *parser = reinterpret_cast<Parser *>(userData);

/* Trigger event */
Handle<Value> argv[2] = { String::New(target), String::New(data) };
parser->Emit(sym_processingInstruction, 2, argv);
Handle<Value> argv[3] = { sym_processingInstruction,
String::New(target),
String::New(data) };
parser->Emit(3, argv);
}

static void Comment(void *userData,
Expand All @@ -318,8 +323,8 @@ class Parser : public EventEmitter {
Parser *parser = reinterpret_cast<Parser *>(userData);

/* Trigger event */
Handle<Value> argv[1] = { String::New(data) };
parser->Emit(sym_comment, 1, argv);
Handle<Value> argv[2] = { sym_comment, String::New(data) };
parser->Emit(2, argv);
}

static void XmlDecl(void *userData,
Expand All @@ -329,10 +334,11 @@ class Parser : public EventEmitter {
Parser *parser = reinterpret_cast<Parser *>(userData);

/* Trigger event */
Handle<Value> argv[3] = { version ? String::New(version) : Null(),
Handle<Value> argv[4] = { sym_xmlDecl,
version ? String::New(version) : Null(),
encoding ? String::New(encoding) : Null(),
Boolean::New(standalone) };
parser->Emit(sym_xmlDecl, 3, argv);
parser->Emit(4, argv);
}

static void EntityDecl(void *userData, const XML_Char *entityName, int is_parameter_entity,
Expand All @@ -342,15 +348,24 @@ class Parser : public EventEmitter {
Parser *parser = reinterpret_cast<Parser *>(userData);

/* Trigger event */
Handle<Value> argv[7] = { entityName ? String::New(entityName) : Null(),
Handle<Value> argv[8] = { sym_entityDecl,
entityName ? String::New(entityName) : Null(),
Boolean::New(is_parameter_entity),
value ? String::New(value) : Null(),
base ? String::New(base) : Null(),
systemId ? String::New(systemId) : Null(),
publicId ? String::New(publicId) : Null(),
notationName ? String::New(notationName) : Null(),
};
parser->Emit(sym_entityDecl, 7, argv);
parser->Emit(8, argv);
}

void Emit(int argc, Handle<Value> argv[])
{
HandleScope scope;

Local<Function> emit = Local<Function>::Cast(handle_->Get(sym_emit));
emit->Call(handle_, argc, argv);
}
};

Expand Down
2 changes: 1 addition & 1 deletion package.json
@@ -1,6 +1,6 @@
{ "name": "node-expat"
,"version": "1.3.2"
,"main": "./build/default/node-expat"
,"main": "./lib/node-expat"
,"description": "NodeJS binding for fast XML parsing."
,"scripts" : { "install": "node-waf configure build"
,"update": "node-waf build"
Expand Down
2 changes: 1 addition & 1 deletion test.js
@@ -1,5 +1,5 @@
var sys = require('sys');
var expat = require('./build/default/node-expat');
var expat = require('./lib/node-expat');
var Buffer = require('buffer').Buffer;
var vows = require('vows');
var assert = require('assert');
Expand Down

0 comments on commit 2f24b62

Please sign in to comment.