[Pkg-javascript-commits] [node-ws] 05/10: Imported Upstream version 0.7.1+ds1.3777b1d7
Ximin Luo
infinity0 at pwned.gg
Mon Mar 30 02:37:19 UTC 2015
This is an automated email from the git hooks/post-receive script.
infinity0-guest pushed a commit to branch master
in repository node-ws.
commit 5f88f369a8196d1e98ff6676728e05c8388a5470
Author: Ximin Luo <infinity0 at pwned.gg>
Date: Mon Mar 30 04:08:47 2015 +0200
Imported Upstream version 0.7.1+ds1.3777b1d7
---
bin/wscat | 222 ++++++++++++++++++++++++++++++++++++++++++
binding.gyp | 8 ++
dependency.versions | 5 +
node_modules/options/index.js | 86 ++++++++++++++++
node_modules/ultron/index.js | 125 ++++++++++++++++++++++++
src/bufferutil.cc | 121 +++++++++++++++++++++++
src/validation.cc | 148 ++++++++++++++++++++++++++++
7 files changed, 715 insertions(+)
diff --git a/bin/wscat b/bin/wscat
new file mode 100755
index 0000000..5ec8046
--- /dev/null
+++ b/bin/wscat
@@ -0,0 +1,222 @@
+#!/usr/bin/env node
+
+/*!
+ * ws: a node.js websocket client
+ * Copyright(c) 2011 Einar Otto Stangvik <einaros at gmail.com>
+ * MIT Licensed
+ */
+
+/**
+ * Module dependencies.
+ */
+
+var program = require('commander')
+ , readline = require('readline')
+ , events = require('events')
+ , WebSocket = require('ws')
+ , util = require('util')
+ , fs = require('fs');
+
+/**
+ * InputReader - processes console input.
+ */
+function Console() {
+ if (!(this instanceof Console)) return new Console();
+
+ this.stdin = process.stdin;
+ this.stdout = process.stdout;
+
+ this.readlineInterface = readline.createInterface(this.stdin, this.stdout);
+
+ var self = this;
+
+ this.readlineInterface.on('line', function line(data) {
+ self.emit('line', data);
+ }).on('close', function close() {
+ self.emit('close');
+ });
+
+ this._resetInput = function() {
+ self.clear();
+ };
+}
+
+util.inherits(Console, events.EventEmitter);
+
+Console.Colors = {
+ Red: '\033[31m',
+ Green: '\033[32m',
+ Yellow: '\033[33m',
+ Blue: '\033[34m',
+ Default: '\033[39m'
+};
+
+Console.prototype.prompt = function prompt() {
+ this.readlineInterface.prompt();
+};
+
+Console.prototype.print = function print(msg, color) {
+ this.clear();
+ color = color || Console.Colors.Default;
+ this.stdout.write(color + msg + Console.Colors.Default + '\n');
+ this.prompt();
+};
+
+Console.prototype.clear = function clear() {
+ this.stdout.write('\033[2K\033[E');
+};
+
+Console.prototype.pause = function pausing() {
+ this.stdin.on('keypress', this._resetInput);
+};
+
+Console.prototype.resume = function resume() {
+ this.stdin.removeListener('keypress', this._resetInput);
+};
+
+function appender(xs) {
+ xs = xs || [];
+
+ return function (x) {
+ xs.push(x);
+ return xs;
+ };
+}
+
+function into(obj, kvals) {
+ kvals.forEach(function (kv) {
+ obj[kv[0]] = kv[1];
+ });
+
+ return obj;
+}
+
+function splitOnce(sep, str) { // sep can be either String or RegExp
+ var tokens = str.split(sep);
+ return [tokens[0], str.replace(sep, '').substr(tokens[0].length)];
+}
+
+/**
+ * The actual application
+ */
+var version = require('../package.json').version;
+
+program
+ .version(version)
+ .usage('[options] <url>')
+ .option('-l, --listen <port>', 'listen on port')
+ .option('-c, --connect <url>', 'connect to a websocket server')
+ .option('-p, --protocol <version>', 'optional protocol version')
+ .option('-o, --origin <origin>', 'optional origin')
+ .option('--host <host>', 'optional host')
+ .option('-s, --subprotocol <protocol>', 'optional subprotocol')
+ .option('-n, --no-check', 'Do not check for unauthorized certificates')
+ .option('-H, --header <header:value>', 'Set an HTTP header. Repeat to set multiple. (--connect only)', appender(), [])
+ .option('--auth <username:password>', 'Add basic HTTP authentication header. (--connect only)')
+ .parse(process.argv);
+
+if (program.listen && program.connect) {
+ console.error('\033[33merror: use either --listen or --connect\033[39m');
+ process.exit(-1);
+} else if (program.listen) {
+ var wsConsole = new Console();
+ wsConsole.pause();
+
+ var options = {};
+
+ if (program.protocol) options.protocolVersion = program.protocol;
+ if (program.origin) options.origin = program.origin;
+ if (program.subprotocol) options.protocol = program.subprotocol;
+ if (!program.check) options.rejectUnauthorized = program.check;
+
+ var ws = null;
+ var wss = new WebSocket.Server({ port: program.listen }, function listening() {
+ wsConsole.print('listening on port ' + program.listen + ' (press CTRL+C to quit)', Console.Colors.Green);
+ wsConsole.clear();
+ });
+
+ wsConsole.on('close', function close() {
+ try { ws.close(); }
+ catch (e) {}
+
+ process.exit(0);
+ });
+
+ wsConsole.on('line', function line(data) {
+ if (ws) {
+ ws.send(data, { mask: false });
+ wsConsole.prompt();
+ }
+ });
+
+ wss.on('connection', function(newClient) {
+ if (ws) return newClient.terminate();
+
+ ws = newClient;
+ wsConsole.resume();
+ wsConsole.prompt();
+ wsConsole.print('client connected', Console.Colors.Green);
+
+ ws.on('close', function close() {
+ wsConsole.print('disconnected', Console.Colors.Green);
+ wsConsole.clear();
+ wsConsole.pause();
+ ws = null;
+ }).on('error', function error(code, description) {
+ wsConsole.print('error: ' + code + (description ? ' ' + description : ''), Console.Colors.Yellow);
+ }).on('message', function message(data, flags) {
+ wsConsole.print('< ' + data, Console.Colors.Blue);
+ });
+ }).on('error', function servererrror(error) {
+ wsConsole.print('error: ' + error.toString(), Console.Colors.Yellow);
+ process.exit(-1);
+ });
+} else if (program.connect) {
+ var wsConsole = new Console();
+ var options = {};
+
+ if (program.protocol) options.protocolVersion = program.protocol;
+ if (program.origin) options.origin = program.origin;
+ if (program.subprotocol) options.protocol = program.subprotocol;
+ if (program.host) options.host = program.host;
+ if (!program.check) options.rejectUnauthorized = program.check;
+
+ var headers = into({}, (program.header || []).map(function split(s) {
+ return splitOnce(':', s);
+ }));
+
+ if (program.auth) {
+ headers.Authorization = 'Basic '+ new Buffer(program.auth).toString('base64');
+ }
+
+ options.headers = headers;
+ var ws = new WebSocket(program.connect, options);
+
+ ws.on('open', function open() {
+ wsConsole.print('connected (press CTRL+C to quit)', Console.Colors.Green);
+ wsConsole.on('line', function line(data) {
+ ws.send(data, { mask: true });
+ wsConsole.prompt();
+ });
+ }).on('close', function close() {
+ wsConsole.print('disconnected', Console.Colors.Green);
+ wsConsole.clear();
+ process.exit();
+ }).on('error', function error(code, description) {
+ wsConsole.print('error: ' + code + (description ? ' ' + description : ''), Console.Colors.Yellow);
+ process.exit(-1);
+ }).on('message', function message(data, flags) {
+ wsConsole.print('< ' + data, Console.Colors.Blue);
+ });
+
+ wsConsole.on('close', function close() {
+ if (!ws) return;
+
+ try { ws.close(); }
+ catch(e) {}
+
+ process.exit();
+ });
+} else {
+ program.help();
+}
diff --git a/binding.gyp b/binding.gyp
new file mode 100644
index 0000000..9b08e4e
--- /dev/null
+++ b/binding.gyp
@@ -0,0 +1,8 @@
+{'targets': [{'cflags': ['-O3'],
+ 'include_dirs': ['<!(node -e "require(\'nan\')")'],
+ 'sources': ['src/bufferutil.cc'],
+ 'target_name': 'bufferutil'},
+ {'cflags': ['-O3'],
+ 'include_dirs': ['<!(node -e "require(\'nan\')")'],
+ 'sources': ['src/validation.cc'],
+ 'target_name': 'validation'}]}
diff --git a/dependency.versions b/dependency.versions
new file mode 100644
index 0000000..55e8b87
--- /dev/null
+++ b/dependency.versions
@@ -0,0 +1,5 @@
+bufferutil=1.0.1
+utf-8-validate=1.0.1
+ultron=1.0.1
+options.js=0.20.gff53d0a
+wscat=0.1.gaa46950
diff --git a/node_modules/options/index.js b/node_modules/options/index.js
new file mode 100644
index 0000000..4fc45e9
--- /dev/null
+++ b/node_modules/options/index.js
@@ -0,0 +1,86 @@
+/*!
+ * Copyright(c) 2011 Einar Otto Stangvik <einaros at gmail.com>
+ * MIT Licensed
+ */
+
+var fs = require('fs');
+
+function Options(defaults) {
+ var internalValues = {};
+ var values = this.value = {};
+ Object.keys(defaults).forEach(function(key) {
+ internalValues[key] = defaults[key];
+ Object.defineProperty(values, key, {
+ get: function() { return internalValues[key]; },
+ configurable: false,
+ enumerable: true
+ });
+ });
+ this.reset = function() {
+ Object.keys(defaults).forEach(function(key) {
+ internalValues[key] = defaults[key];
+ });
+ return this;
+ };
+ this.merge = function(options, required) {
+ options = options || {};
+ if (Object.prototype.toString.call(required) === '[object Array]') {
+ var missing = [];
+ for (var i = 0, l = required.length; i < l; ++i) {
+ var key = required[i];
+ if (!(key in options)) {
+ missing.push(key);
+ }
+ }
+ if (missing.length > 0) {
+ if (missing.length > 1) {
+ throw new Error('options ' +
+ missing.slice(0, missing.length - 1).join(', ') + ' and ' +
+ missing[missing.length - 1] + ' must be defined');
+ }
+ else throw new Error('option ' + missing[0] + ' must be defined');
+ }
+ }
+ Object.keys(options).forEach(function(key) {
+ if (key in internalValues) {
+ internalValues[key] = options[key];
+ }
+ });
+ return this;
+ };
+ this.copy = function(keys) {
+ var obj = {};
+ Object.keys(defaults).forEach(function(key) {
+ if (keys.indexOf(key) !== -1) {
+ obj[key] = values[key];
+ }
+ });
+ return obj;
+ };
+ this.read = function(filename, cb) {
+ if (typeof cb == 'function') {
+ var self = this;
+ fs.readFile(filename, function(error, data) {
+ if (error) return cb(error);
+ var conf = JSON.parse(data);
+ self.merge(conf);
+ cb();
+ });
+ }
+ else {
+ var conf = JSON.parse(fs.readFileSync(filename));
+ this.merge(conf);
+ }
+ return this;
+ };
+ this.isDefined = function(key) {
+ return typeof values[key] != 'undefined';
+ };
+ this.isDefinedAndNonNull = function(key) {
+ return typeof values[key] != 'undefined' && values[key] !== null;
+ };
+ Object.freeze(values);
+ Object.freeze(this);
+}
+
+module.exports = Options;
diff --git a/node_modules/ultron/index.js b/node_modules/ultron/index.js
new file mode 100644
index 0000000..f0e8113
--- /dev/null
+++ b/node_modules/ultron/index.js
@@ -0,0 +1,125 @@
+'use strict';
+
+/**
+ * An auto incrementing id which we can use to create "unique" Ultron instances
+ * so we can track the event emitters that are added through the Ultron
+ * interface.
+ *
+ * @type {Number}
+ * @private
+ */
+var id = 0;
+
+/**
+ * Ultron is high-intelligence robot. It gathers intelligence so it can start improving
+ * upon his rudimentary design. It will learn from your EventEmitting patterns
+ * and exterminate them.
+ *
+ * @constructor
+ * @param {EventEmitter} ee EventEmitter instance we need to wrap.
+ * @api public
+ */
+function Ultron(ee) {
+ if (!(this instanceof Ultron)) return new Ultron(ee);
+
+ this.id = id++;
+ this.ee = ee;
+}
+
+/**
+ * Register a new EventListener for the given event.
+ *
+ * @param {String} event Name of the event.
+ * @param {Functon} fn Callback function.
+ * @param {Mixed} context The context of the function.
+ * @returns {Ultron}
+ * @api public
+ */
+Ultron.prototype.on = function on(event, fn, context) {
+ fn.__ultron = this.id;
+ this.ee.on(event, fn, context);
+
+ return this;
+};
+/**
+ * Add an EventListener that's only called once.
+ *
+ * @param {String} event Name of the event.
+ * @param {Function} fn Callback function.
+ * @param {Mixed} context The context of the function.
+ * @returns {Ultron}
+ * @api public
+ */
+Ultron.prototype.once = function once(event, fn, context) {
+ fn.__ultron = this.id;
+ this.ee.once(event, fn, context);
+
+ return this;
+};
+
+/**
+ * Remove the listeners we assigned for the given event.
+ *
+ * @returns {Ultron}
+ * @api public
+ */
+Ultron.prototype.remove = function remove() {
+ var args = arguments
+ , event;
+
+ //
+ // When no event names are provided we assume that we need to clear all the
+ // events that were assigned through us.
+ //
+ if (args.length === 1 && 'string' === typeof args[0]) {
+ args = args[0].split(/[, ]+/);
+ } else if (!args.length) {
+ args = [];
+
+ for (event in this.ee._events) {
+ if (this.ee._events.hasOwnProperty(event)) {
+ args.push(event);
+ }
+ }
+ }
+
+ for (var i = 0; i < args.length; i++) {
+ var listeners = this.ee.listeners(args[i]);
+
+ for (var j = 0; j < listeners.length; j++) {
+ event = listeners[j];
+
+ if (event.listener) {
+ if (event.listener.__ultron !== this.id) continue;
+ delete event.listener.__ultron;
+ } else {
+ if (event.__ultron !== this.id) continue;
+ delete event.__ultron;
+ }
+
+ this.ee.removeListener(args[i], event);
+ }
+ }
+
+ return this;
+};
+
+/**
+ * Destroy the Ultron instance, remove all listeners and release all references.
+ *
+ * @returns {Boolean}
+ * @api public
+ */
+Ultron.prototype.destroy = function destroy() {
+ if (!this.ee) return false;
+
+ this.remove();
+ this.ee = null;
+
+ return true;
+};
+
+//
+// Expose the module.
+//
+module.exports = Ultron;
diff --git a/src/bufferutil.cc b/src/bufferutil.cc
new file mode 100644
index 0000000..bd6f368
--- /dev/null
+++ b/src/bufferutil.cc
@@ -0,0 +1,121 @@
+/*!
+ * bufferutil: WebSocket buffer utils
+ * Copyright(c) 2015 Einar Otto Stangvik <einaros at gmail.com>
+ * MIT Licensed
+ */
+
+#include <v8.h>
+#include <node.h>
+#include <node_version.h>
+#include <node_buffer.h>
+#include <node_object_wrap.h>
+#include <stdlib.h>
+#include <string.h>
+#include <wchar.h>
+#include <stdio.h>
+#include "nan.h"
+
+using namespace v8;
+using namespace node;
+
+class BufferUtil : public ObjectWrap
+{
+public:
+
+ static void Initialize(v8::Handle<v8::Object> target)
+ {
+ NanScope();
+ Local<FunctionTemplate> t = NanNew<FunctionTemplate>(New);
+ t->InstanceTemplate()->SetInternalFieldCount(1);
+ NODE_SET_METHOD(t, "unmask", BufferUtil::Unmask);
+ NODE_SET_METHOD(t, "mask", BufferUtil::Mask);
+ NODE_SET_METHOD(t, "merge", BufferUtil::Merge);
+ target->Set(NanNew<String>("BufferUtil"), t->GetFunction());
+ }
+
+protected:
+
+ static NAN_METHOD(New)
+ {
+ NanScope();
+ BufferUtil* bufferUtil = new BufferUtil();
+ bufferUtil->Wrap(args.This());
+ NanReturnValue(args.This());
+ }
+
+ static NAN_METHOD(Merge)
+ {
+ NanScope();
+ Local<Object> bufferObj = args[0]->ToObject();
+ char* buffer = Buffer::Data(bufferObj);
+ Local<Array> array = Local<Array>::Cast(args[1]);
+ unsigned int arrayLength = array->Length();
+ size_t offset = 0;
+ unsigned int i;
+ for (i = 0; i < arrayLength; ++i) {
+ Local<Object> src = array->Get(i)->ToObject();
+ size_t length = Buffer::Length(src);
+ memcpy(buffer + offset, Buffer::Data(src), length);
+ offset += length;
+ }
+ NanReturnValue(NanTrue());
+ }
+
+ static NAN_METHOD(Unmask)
+ {
+ NanScope();
+ Local<Object> buffer_obj = args[0]->ToObject();
+ size_t length = Buffer::Length(buffer_obj);
+ Local<Object> mask_obj = args[1]->ToObject();
+ unsigned int *mask = (unsigned int*)Buffer::Data(mask_obj);
+ unsigned int* from = (unsigned int*)Buffer::Data(buffer_obj);
+ size_t len32 = length / 4;
+ unsigned int i;
+ for (i = 0; i < len32; ++i) *(from + i) ^= *mask;
+ from += i;
+ switch (length % 4) {
+ case 3: *((unsigned char*)from+2) = *((unsigned char*)from+2) ^ ((unsigned char*)mask)[2];
+ case 2: *((unsigned char*)from+1) = *((unsigned char*)from+1) ^ ((unsigned char*)mask)[1];
+ case 1: *((unsigned char*)from ) = *((unsigned char*)from ) ^ ((unsigned char*)mask)[0];
+ case 0:;
+ }
+ NanReturnValue(NanTrue());
+ }
+
+ static NAN_METHOD(Mask)
+ {
+ NanScope();
+ Local<Object> buffer_obj = args[0]->ToObject();
+ Local<Object> mask_obj = args[1]->ToObject();
+ unsigned int *mask = (unsigned int*)Buffer::Data(mask_obj);
+ Local<Object> output_obj = args[2]->ToObject();
+ unsigned int dataOffset = args[3]->Int32Value();
+ unsigned int length = args[4]->Int32Value();
+ unsigned int* to = (unsigned int*)(Buffer::Data(output_obj) + dataOffset);
+ unsigned int* from = (unsigned int*)Buffer::Data(buffer_obj);
+ unsigned int len32 = length / 4;
+ unsigned int i;
+ for (i = 0; i < len32; ++i) *(to + i) = *(from + i) ^ *mask;
+ to += i;
+ from += i;
+ switch (length % 4) {
+ case 3: *((unsigned char*)to+2) = *((unsigned char*)from+2) ^ *((unsigned char*)mask+2);
+ case 2: *((unsigned char*)to+1) = *((unsigned char*)from+1) ^ *((unsigned char*)mask+1);
+ case 1: *((unsigned char*)to ) = *((unsigned char*)from ) ^ *((unsigned char*)mask);
+ case 0:;
+ }
+ NanReturnValue(NanTrue());
+ }
+};
+
+#if !NODE_VERSION_AT_LEAST(0,10,0)
+extern "C"
+#endif
+void init (Handle<Object> target)
+{
+ NanScope();
+ BufferUtil::Initialize(target);
+}
+
+NODE_MODULE(bufferutil, init)
+
diff --git a/src/validation.cc b/src/validation.cc
new file mode 100644
index 0000000..264edcd
--- /dev/null
+++ b/src/validation.cc
@@ -0,0 +1,148 @@
+/*!
+ * UTF-8 validate: UTF-8 validation for WebSockets.
+ * Copyright(c) 2015 Einar Otto Stangvik <einaros at gmail.com>
+ * MIT Licensed
+ */
+
+#include <v8.h>
+#include <node.h>
+#include <node_version.h>
+#include <node_buffer.h>
+#include <node_object_wrap.h>
+#include <stdlib.h>
+#include <wchar.h>
+#include <stdio.h>
+#include "nan.h"
+
+using namespace v8;
+using namespace node;
+
+#define UNI_SUR_HIGH_START (uint32_t) 0xD800
+#define UNI_SUR_LOW_END (uint32_t) 0xDFFF
+#define UNI_REPLACEMENT_CHAR (uint32_t) 0x0000FFFD
+#define UNI_MAX_LEGAL_UTF32 (uint32_t) 0x0010FFFF
+
+static const uint8_t trailingBytesForUTF8[256] = {
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+ 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5
+};
+
+static const uint32_t offsetsFromUTF8[6] = {
+ 0x00000000, 0x00003080, 0x000E2080,
+ 0x03C82080, 0xFA082080, 0x82082080
+};
+
+static int isLegalUTF8(const uint8_t *source, const int length)
+{
+ uint8_t a;
+ const uint8_t *srcptr = source+length;
+ switch (length) {
+ default: return 0;
+ /* Everything else falls through when "true"... */
+ /* RFC3629 makes 5 & 6 bytes UTF-8 illegal
+ case 6: if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return 0;
+ case 5: if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return 0; */
+ case 4: if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return 0;
+ case 3: if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return 0;
+ case 2: if ((a = (*--srcptr)) > 0xBF) return 0;
+ switch (*source) {
+ /* no fall-through in this inner switch */
+ case 0xE0: if (a < 0xA0) return 0; break;
+ case 0xED: if (a > 0x9F) return 0; break;
+ case 0xF0: if (a < 0x90) return 0; break;
+ case 0xF4: if (a > 0x8F) return 0; break;
+ default: if (a < 0x80) return 0;
+ }
+
+ case 1: if (*source >= 0x80 && *source < 0xC2) return 0;
+ }
+ if (*source > 0xF4) return 0;
+ return 1;
+}
+
+int is_valid_utf8 (size_t len, char *value)
+{
+ /* is the string valid UTF-8? */
+ for (unsigned int i = 0; i < len; i++) {
+ uint32_t ch = 0;
+ uint8_t extrabytes = trailingBytesForUTF8[(uint8_t) value[i]];
+
+ if (extrabytes + i >= len)
+ return 0;
+
+ if (isLegalUTF8 ((uint8_t *) (value + i), extrabytes + 1) == 0) return 0;
+
+ switch (extrabytes) {
+ case 5 : ch += (uint8_t) value[i++]; ch <<= 6;
+ case 4 : ch += (uint8_t) value[i++]; ch <<= 6;
+ case 3 : ch += (uint8_t) value[i++]; ch <<= 6;
+ case 2 : ch += (uint8_t) value[i++]; ch <<= 6;
+ case 1 : ch += (uint8_t) value[i++]; ch <<= 6;
+ case 0 : ch += (uint8_t) value[i];
+ }
+
+ ch -= offsetsFromUTF8[extrabytes];
+
+ if (ch <= UNI_MAX_LEGAL_UTF32) {
+ if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END)
+ return 0;
+ } else {
+ return 0;
+ }
+ }
+
+ return 1;
+}
+
+class Validation : public ObjectWrap
+{
+public:
+
+ static void Initialize(v8::Handle<v8::Object> target)
+ {
+ NanScope();
+ Local<FunctionTemplate> t = NanNew<FunctionTemplate>(New);
+ t->InstanceTemplate()->SetInternalFieldCount(1);
+ NODE_SET_METHOD(t, "isValidUTF8", Validation::IsValidUTF8);
+ target->Set(NanNew<String>("Validation"), t->GetFunction());
+ }
+
+protected:
+
+ static NAN_METHOD(New)
+ {
+ NanScope();
+ Validation* validation = new Validation();
+ validation->Wrap(args.This());
+ NanReturnValue(args.This());
+ }
+
+ static NAN_METHOD(IsValidUTF8)
+ {
+ NanScope();
+ if (!Buffer::HasInstance(args[0])) {
+ return NanThrowTypeError("First argument needs to be a buffer");
+ }
+ Local<Object> buffer_obj = args[0]->ToObject();
+ char *buffer_data = Buffer::Data(buffer_obj);
+ size_t buffer_length = Buffer::Length(buffer_obj);
+ NanReturnValue(is_valid_utf8(buffer_length, buffer_data) == 1 ? NanTrue() : NanFalse());
+ }
+};
+#if !NODE_VERSION_AT_LEAST(0,10,0)
+extern "C"
+#endif
+void init (Handle<Object> target)
+{
+ NanScope();
+ Validation::Initialize(target);
+}
+
+NODE_MODULE(validation, init)
+
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-javascript/node-ws.git
More information about the Pkg-javascript-commits
mailing list