[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