[Pkg-javascript-commits] [node-expat] 88/371: Imported Upstream version 1.4.0
Jonas Smedegaard
dr at jones.dk
Sun Feb 28 09:59:48 UTC 2016
This is an automated email from the git hooks/post-receive script.
js pushed a commit to branch master
in repository node-expat.
commit f87253d94ef569eb9746e7d6737ba83faca2453b
Author: Jonas Smedegaard <dr at jones.dk>
Date: Sun Aug 21 11:00:42 2011 +0200
Imported Upstream version 1.4.0
---
.gitignore | 4 +
bench.js | 2 +-
install.sh | 4 -
lib/node-expat.js | 38 +++++++
node-expat.cc | 81 +++++++++++----
package.json | 12 ++-
test.js | 305 +++++++++++++++++++++++++++++++-----------------------
wscript | 7 ++
8 files changed, 291 insertions(+), 162 deletions(-)
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..5c68e8c
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,4 @@
+.lock-wscript
+node_modules
+build
+*.swp
diff --git a/bench.js b/bench.js
index 4db66f0..ce282a1 100644
--- a/bench.js
+++ b/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) { });
diff --git a/install.sh b/install.sh
deleted file mode 100755
index 8c8a895..0000000
--- a/install.sh
+++ /dev/null
@@ -1,4 +0,0 @@
-#!/bin/sh
-
-node-waf configure
-node-waf build
diff --git a/lib/node-expat.js b/lib/node-expat.js
new file mode 100644
index 0000000..cd7f91a
--- /dev/null
+++ b/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();
+};
diff --git a/node-expat.cc b/node-expat.cc
index 9917043..6243f07 100644
--- a/node-expat.cc
+++ b/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>
@@ -12,16 +12,16 @@ using namespace node;
static Persistent<String> sym_startElement, sym_endElement,
sym_startCdata, sym_endCdata,
sym_text, sym_processingInstruction,
- sym_comment, sym_xmlDecl;
+ 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);
@@ -40,6 +40,8 @@ public:
sym_processingInstruction = NODE_PSYMBOL("processingInstruction");
sym_comment = NODE_PSYMBOL("comment");
sym_xmlDecl = NODE_PSYMBOL("xmlDecl");
+ sym_entityDecl = NODE_PSYMBOL("entityDecl");
+ sym_emit = NODE_PSYMBOL("emit");
}
protected:
@@ -63,7 +65,7 @@ protected:
}
Parser(const XML_Char *encoding)
- : EventEmitter()
+ : ObjectWrap()
{
parser = XML_ParserCreate(encoding);
assert(parser != NULL);
@@ -75,6 +77,7 @@ protected:
XML_SetProcessingInstructionHandler(parser, ProcessingInstruction);
XML_SetCommentHandler(parser, Comment);
XML_SetXmlDeclHandler(parser, XmlDecl);
+ XML_SetEntityDeclHandler(parser, EntityDecl);
}
~Parser()
@@ -131,6 +134,9 @@ protected:
bool parseString(String &str, int isFinal)
{
int len = str.Utf8Length();
+ if (len == 0)
+ return true;
+
void *buf = XML_GetBuffer(parser, len);
assert(buf != NULL);
assert(str.WriteUtf8(static_cast<char *>(buf), len) == len);
@@ -254,8 +260,10 @@ private:
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,
@@ -264,8 +272,8 @@ private:
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)
@@ -273,8 +281,8 @@ private:
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)
@@ -282,8 +290,8 @@ private:
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,
@@ -292,8 +300,9 @@ private:
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,
@@ -302,8 +311,10 @@ private:
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,
@@ -312,8 +323,8 @@ private:
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,
@@ -323,10 +334,38 @@ private:
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,
+ const XML_Char *value, int value_length, const XML_Char *base,
+ const XML_Char *systemId, const XML_Char *publicId, const XML_Char *notationName)
+ {
+ Parser *parser = reinterpret_cast<Parser *>(userData);
+
+ /* Trigger event */
+ 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(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);
}
};
diff --git a/package.json b/package.json
index 6122ae1..605f4aa 100644
--- a/package.json
+++ b/package.json
@@ -1,9 +1,13 @@
{ "name": "node-expat"
-,"version": "1.3.0"
-,"main": "./build/default/node-expat"
+,"version": "1.4.0"
+,"main": "./lib/node-expat"
,"description": "NodeJS binding for fast XML parsing."
-,"scripts" : { "install" : "./install.sh" }
+,"scripts" : { "install": "node-waf configure build"
+ ,"update": "node-waf build"
+ ,"test": "node test.js"
+ }
,"dependencies": []
+,"devDependencies": ["vows"]
,"repositories": [{ "type": "git"
,"path": "git://github.com/astro/node-expat.git"
}]
@@ -13,7 +17,7 @@
,"email": "astro at spaceboyz.net"
,"web": "http://spaceboyz.net/~astro/"
}]
-,"contributors": ["Stephan Maka", "Derek Hammer", "Iein Valdez", "Peter Körner"]
+,"contributors": ["Stephan Maka", "Derek Hammer", "Iein Valdez", "Peter Körner", "Camilo Aguilar"]
,"licenses": [{ "type": "MIT" }]
,"engine": "node"
}
diff --git a/test.js b/test.js
index 8148ab1..d1dfe7f 100644
--- a/test.js
+++ b/test.js
@@ -1,6 +1,8 @@
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');
function collapseTexts(evs) {
var r = [];
@@ -20,11 +22,8 @@ function collapseTexts(evs) {
return r;
}
-var tests = 0, iterations = 0, fails = 0;
function expect(s, evs_expected) {
- tests++;
for(var step = s.length; step > 0; step--) {
- iterations++;
var evs_received = [];
var p = new expat.Parser("UTF-8");
//p.setEncoding("UTF-8");
@@ -52,6 +51,9 @@ function expect(s, evs_expected) {
p.addListener('endCdata', function() {
evs_received.push(['endCdata']);
});
+ p.addListener('entityDecl', function(entityName, isParameterEntity, value, base, systemId, publicId, notationName) {
+ evs_received.push(['entityDecl', entityName, isParameterEntity, value, base, systemId, publicId, notationName]);
+ });
for(var l = 0; l < s.length; l += step)
{
var end = l + step;
@@ -64,21 +66,117 @@ function expect(s, evs_expected) {
var expected = JSON.stringify(evs_expected);
var received = JSON.stringify(collapseTexts(evs_received));
- if (expected != received) {
- fails++;
- sys.puts("Fail for: " + s + " (step=" + step + ")");
- sys.puts("Expected: " + expected);
- sys.puts("Received: " + received);
- return; // don't try with smaller step size
- }
+ assert.equal(received, expected);
}
}
-function testStopResume(cb)
-{
- var p = new expat.Parser("UTF-8");
-
- var input = '\
+vows.describe('node-expat').addBatch({
+ 'single element': {
+ 'simple': function() {
+ expect("<r/>",
+ [['startElement', 'r', {}],
+ ['endElement', 'r']]);
+ },
+ 'single element with attribute': function() {
+ expect("<r foo='bar'/>",
+ [['startElement', 'r', {foo: 'bar'}],
+ ['endElement', 'r']]);
+ },
+ 'single elemeht with differently quoted attributes': function() {
+ expect("<r foo='bar' baz=\"quux\" test=\"tset\"/>",
+ [['startElement', 'r', {foo: 'bar', baz: 'quux', test: 'tset'}],
+ ['endElement', 'r']]);
+ },
+ 'single element with namespaces': function() {
+ expect("<r xmlns='http://localhost/' xmlns:x=\"http://example.com/\"></r>",
+ [['startElement', 'r', {xmlns: 'http://localhost/', 'xmlns:x': 'http://example.com/'}],
+ ['endElement', 'r']]);
+ },
+ 'single element with text content': function() {
+ expect("<r>foo</r>",
+ [['startElement', 'r', {}],
+ ['text', "foo"],
+ ['endElement', 'r']]);
+ },
+ 'single element with text content and line break': function() {
+ expect("<r>foo\nbar</r>",
+ [['startElement', 'r', {}],
+ ['text', "foo\nbar"],
+ ['endElement', 'r']]);
+ },
+ 'single element with CDATA content': function() {
+ expect("<r><![CDATA[<greeting>Hello, world!</greeting>]]></r>",
+ [['startElement', 'r', {}],
+ ['startCdata'],
+ ['text', "<greeting>Hello, world!</greeting>"],
+ ['endCdata'],
+ ['endElement', 'r']]);
+ },
+ 'single element with entity text': function() {
+ expect("<r>foo&bar</r>",
+ [['startElement', 'r', {}],
+ ['text', "foo&bar"],
+ ['endElement', 'r']]);
+ },
+ 'single element with umlaut text': function() {
+ expect("<r>ß</r>",
+ [['startElement', 'r', {}],
+ ['text', "ß"],
+ ['endElement', 'r']]);
+ },
+ 'from buffer': function() {
+ expect(new Buffer('<foo>bar</foo>'),
+ [['startElement', 'foo', {}],
+ ['text', 'bar'],
+ ['endElement', 'foo']]);
+ }
+ },
+ 'entity declaration': {
+ 'a billion laughs': function() {
+ expect('<!DOCTYPE b [<!ELEMENT b (#PCDATA)>' +
+ '<!ENTITY l0 "ha"><!ENTITY l1 "&l0;&l0;"><!ENTITY l2 "&l1;&l1;">' +
+ ']><b>&l2;</b>',
+ [["entityDecl","l0",false,"ha",null,null,null,null],
+ ["entityDecl","l1",false,"&l0;&l0;",null,null,null,null],
+ ["entityDecl","l2",false,"&l1;&l1;",null,null,null,null],
+ ["startElement","b",{}],["text","hahahaha"],["endElement","b"]]);
+ }
+ },
+ 'processing instruction': {
+ 'with parameters': function() {
+ expect("<?i like xml?>",
+ [['processingInstruction', 'i', 'like xml']]);
+ },
+ 'simple': function() {
+ expect("<?dragons?>",
+ [['processingInstruction', 'dragons', '']]);
+ },
+ 'XML declaration with encoding': function() {
+ expect("<?xml version='1.0' encoding='UTF-8'?>",
+ [['xmlDecl', '1.0', 'UTF-8', true]]);
+ },
+ 'XML declaration': function() {
+ expect("<?xml version='1.0'?>",
+ [['xmlDecl', '1.0', null, true]]);
+ }
+ },
+ 'comment': {
+ 'simple': function() {
+ expect("<!-- no comment -->",
+ [['comment', ' no comment ']]);
+ }
+ },
+ 'error': {
+ 'tag name starting with ampersand': function() {
+ expect("<&", [['error']]);
+ }
+ },
+ 'stop and resume': {
+ topic: function() {
+ var cb = this.callback;
+ var p = new expat.Parser("UTF-8");
+
+ var input = '\
<wrap> \
<short /> \
<short></short> \
@@ -86,128 +184,71 @@ function testStopResume(cb)
<short /> \
<long>foo</long> \
</wrap>';
-
- var expected = ['wrap', 'short', 'short', 'long', 'short', 'long'];
- var received = [];
-
- var tolerance = 10/100;
- var expectedRuntime = 1000;
- var start = new Date();
-
- p.addListener('startElement', function(name, attrs) {
+
+ var expected = ['wrap', 'short', 'short', 'long', 'short', 'long'];
+ var received = [];
+
+ var tolerance = 10/100;
+ var expectedRuntime = 1000;
+ var start = new Date();
+
+ p.addListener('startElement', function(name, attrs) {
received.push(name);
-
+
// suspend parser for 1/2 second
if(name == 'long') {
- p.stop();
-
- setTimeout(function() {
- p.resume();
- }, 500);
+ p.stop();
+
+ setTimeout(function() {
+ p.resume();
+ }, 500);
}
- })
-
- p.addListener('endElement', function(name) {
+ });
+
+ p.addListener('endElement', function(name) {
// finished parsing
if(name == 'wrap') {
- // test elements received (count. naming, order)
- if(JSON.stringify(expected) != JSON.stringify(received)) {
- sys.puts("Failed Stop/Resume test");
- sys.puts("Expected: " + expected);
- sys.puts("Received: " + received);
- return cb(false);
- }
-
- // test timing (+-5%)
- var now = new Date();
- var diff = now.getTime() - start.getTime();
- var max = expectedRuntime + expectedRuntime * tolerance,
- min = expectedRuntime - expectedRuntime * tolerance;
-
- if(diff > max) {
- sys.puts("Failed Stop/Resume test");
- sys.puts("Expected Runtime < " + max);
- sys.puts("Taken Runtime: " + diff);
- return cb(false);
- }
-
- if(diff < min) {
- sys.puts("Failed Stop/Resume test");
- sys.puts("Expected Runtime > " + min);
- sys.puts("Taken Runtime: " + diff);
- return cb(false);
- }
-
- return cb(true);
+ // test elements received (count. naming, order)
+ assert.equal(JSON.stringify(received), JSON.stringify(expected));
+
+ // test timing (+-5%)
+ var now = new Date();
+ var diff = now.getTime() - start.getTime();
+ var max = expectedRuntime + expectedRuntime * tolerance,
+ min = expectedRuntime - expectedRuntime * tolerance;
+
+ assert.ok(diff < max, 'Runtime within maximum expected time');
+ assert.ok(diff > min, 'Runtime at least minimum expected time');
+
+ return cb(true);
}
- });
-
- if(!p.parse(input)) {
- sys.puts("Failed Stop/Resume test: parse returned error: "+p.getError());
- return cb(false);
- }
-}
+ });
-expect("<r/>",
- [['startElement', 'r', {}],
- ['endElement', 'r']]);
-expect("<r foo='bar'/>",
- [['startElement', 'r', {foo: 'bar'}],
- ['endElement', 'r']]);
-expect("<r foo='bar' baz=\"quux\" test=\"tset\"/>",
- [['startElement', 'r', {foo: 'bar', baz: 'quux', test: 'tset'}],
- ['endElement', 'r']]);
-expect("<r xmlns='http://localhost/' xmlns:x=\"http://example.com/\"></r>",
- [['startElement', 'r', {xmlns: 'http://localhost/', 'xmlns:x': 'http://example.com/'}],
- ['endElement', 'r']]);
-expect("<r>foo</r>",
- [['startElement', 'r', {}],
- ['text', "foo"],
- ['endElement', 'r']]);
-expect("<r>foo\nbar</r>",
- [['startElement', 'r', {}],
- ['text', "foo\nbar"],
- ['endElement', 'r']]);
-expect("<r><![CDATA[<greeting>Hello, world!</greeting>]]></r>",
- [['startElement', 'r', {}],
- ['startCdata'],
- ['text', "<greeting>Hello, world!</greeting>"],
- ['endCdata'],
- ['endElement', 'r']]);
-expect("<r>foo&bar</r>",
- [['startElement', 'r', {}],
- ['text', "foo&bar"],
- ['endElement', 'r']]);
-expect("<r>ß</r>",
- [['startElement', 'r', {}],
- ['text', "ß"],
- ['endElement', 'r']]);
-expect("<?i like xml?>",
- [['processingInstruction', 'i', 'like xml']]);
-expect("<?dragons?>",
- [['processingInstruction', 'dragons', '']]);
-expect("<!-- no comment -->",
- [['comment', ' no comment ']]);
-expect("<&", [['error']]);
-expect("<?xml version='1.0' encoding='UTF-8'?>",
- [['xmlDecl', '1.0', 'UTF-8', true]]);
-expect("<?xml version='1.0'?>",
- [['xmlDecl', '1.0', null, true]]);
-expect(new Buffer('<foo>bar</foo>'),
- [['startElement', 'foo', {}],
- ['text', 'bar'],
- ['endElement', 'foo']]);
-expect(new Buffer('<foo><![CDATA[bar]]></foo>'),
- [['startElement', 'foo', {}],
- ['startCdata'],
- ['text', 'bar'],
- ['endCdata'],
- ['endElement', 'foo']]);
-
-sys.puts("Ran "+tests+" tests with "+iterations+" iterations: "+fails+" failures.");
-
-sys.puts("Starting Stop/Resume Test (wait for result...)");
-testStopResume(function(success) {
- sys.puts("Stop/Resume Test "+(success ? 'succeeded' : 'failed'));
-});
+ assert.ok(p.parse(input));
+ },
+ 'should have worked': function() {
+ assert.ok(true, 'start & stop works');
+ }
+ },
+ 'corner cases': {
+ 'parse empty string': function() {
+ var p = new expat.Parser("UTF-8");
+ p.parse('');
+ assert.ok(true, "Did not segfault");
+ },
+
+ 'parsing twice the same document with the same parser instance should be fine': 'reset() not yet implemented'
+ /*function() {
+ var p = new expat.Parser("UTF-8");
+ var xml = "<foo>bar</foo>";
+ var result = p.parse(xml);
+ assert.ok(result);
+ assert.isNull(p.getError());
+ var result2 = p.parse(xml);
+ assert.isNull(p.getError());
+ assert.ok(result2);
+
+ }*/
+ }
+}).run();
diff --git a/wscript b/wscript
index ff67c1e..66922b9 100644
--- a/wscript
+++ b/wscript
@@ -8,9 +8,16 @@ def set_options(opt):
def configure(conf):
conf.check_tool('compiler_cxx')
conf.check_tool('node_addon')
+ conf.check( header_name='expat.h',
+ mandatory = True,
+ errmsg = "not installed")
+
+ conf.env['LIB_EXPAT'] = ['expat']
+
def build(bld):
obj = bld.new_task_gen('cxx', 'shlib', 'node_addon')
obj.target = 'node-expat'
obj.source = 'node-expat.cc'
obj.lib = 'expat'
+ obj.uselib = 'EXPAT'
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-javascript/node-expat.git
More information about the Pkg-javascript-commits
mailing list