Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

code import

  • Loading branch information...
commit ec2bbc5db7b43a75499017442ebbb2f03c7b26a2 1 parent b99473b
Conrad Pankoff authored November 27, 2012
1  .gitignore
... ...
@@ -0,0 +1 @@
  1
+/node_modules
26  LICENSE.md
Source Rendered
... ...
@@ -0,0 +1,26 @@
  1
+Copyright (c) 2012, Deoxxa Development
  2
+======================================
  3
+All rights reserved.
  4
+--------------------
  5
+  
  6
+Redistribution and use in source and binary forms, with or without
  7
+modification, are permitted provided that the following conditions are met:  
  8
+1. Redistributions of source code must retain the above copyright
  9
+   notice, this list of conditions and the following disclaimer.  
  10
+2. Redistributions in binary form must reproduce the above copyright
  11
+   notice, this list of conditions and the following disclaimer in the
  12
+   documentation and/or other materials provided with the distribution.  
  13
+3. Neither the name of Deoxxa Development nor the names of its contributors
  14
+   may be used to endorse or promote products derived from this software
  15
+   without specific prior written permission.  
  16
+  
  17
+THIS SOFTWARE IS PROVIDED BY DEOXXA DEVELOPMENT ''AS IS'' AND ANY
  18
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  19
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  20
+DISCLAIMED. IN NO EVENT SHALL DEOXXA DEVELOPMENT BE LIABLE FOR ANY
  21
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  22
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  23
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  24
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  25
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  26
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
63  README.md
Source Rendered
... ...
@@ -0,0 +1,63 @@
  1
+IRC-Protocol
  2
+============
  3
+
  4
+Streaming parser and serialiser for IRC protocol data.
  5
+
  6
+Overview
  7
+--------
  8
+
  9
+This module allows you to consume and produce IRC protocol messages. It doesn't
  10
+contain any logic, leaving that up to the developer. Also everything is streams.
  11
+
  12
+Installation
  13
+------------
  14
+
  15
+Available via [npm](http://npmjs.org/):
  16
+
  17
+> $ npm install irc-protocol
  18
+
  19
+Or via git:
  20
+
  21
+> $ git clone git://github.com/deoxxa/irc-protocol.git node_modules/irc-protocol
  22
+
  23
+Usage
  24
+-----
  25
+
  26
+Also see [proxy.js](https://github.com/deoxxa/irc-protocol/blob/master/proxy.js).
  27
+
  28
+```javascript
  29
+#!/usr/bin/env node
  30
+
  31
+var net = require("net"),
  32
+    IRCProtocol = require("./index");
  33
+
  34
+var server = net.createServer(function(local) {
  35
+  var local_parser = new IRCProtocol.Parser(),
  36
+      remote_parser = new IRCProtocol.Parser(),
  37
+      local_serialiser = new IRCProtocol.Serialiser(),
  38
+      remote_serialiser = new IRCProtocol.Serialiser();
  39
+
  40
+  var remote = net.createConnection(6667, "127.0.0.1");
  41
+
  42
+  local.pipe(local_parser).pipe(local_serialiser).pipe(remote);
  43
+  remote.pipe(remote_parser).pipe(remote_serialiser).pipe(local);
  44
+
  45
+  local_serialiser.on("data", function(data) { process.stdout.write(">> " + data); });
  46
+  remote_serialiser.on("data", function(data) { process.stdout.write("<< " + data); });
  47
+});
  48
+
  49
+server.listen(6668);
  50
+```
  51
+
  52
+License
  53
+-------
  54
+
  55
+3-clause BSD. A copy is included with the source.
  56
+
  57
+Contact
  58
+-------
  59
+
  60
+* GitHub ([deoxxa](http://github.com/deoxxa))
  61
+* Twitter ([@deoxxa](http://twitter.com/deoxxa))
  62
+* ADN ([@deoxxa](https://alpha.app.net/deoxxa))
  63
+* Email ([deoxxa@fknsrs.biz](mailto:deoxxa@fknsrs.biz))
2  index.js
... ...
@@ -0,0 +1,2 @@
  1
+exports.Parser = require("./parser");
  2
+exports.Serialiser = require("./serialiser");
22  package.json
... ...
@@ -0,0 +1,22 @@
  1
+{
  2
+  "name": "irc-protocol",
  3
+  "version": "0.0.0",
  4
+  "description": "Streaming parser and serialiser for IRC protocol data",
  5
+  "main": "index.js",
  6
+  "dependencies": {
  7
+    "steez": "~0.4.2"
  8
+  },
  9
+  "repository": {
  10
+    "type": "git",
  11
+    "url": "git://github.com/deoxxa/irc-protocol.git"
  12
+  },
  13
+  "keywords": [
  14
+    "irc",
  15
+    "protocol",
  16
+    "parser",
  17
+    "serialiser",
  18
+    "stream"
  19
+  ],
  20
+  "author": "Conrad Pankoff <deoxxa@fknsrs.biz> (http://www.fknsrs.biz/)",
  21
+  "license": "BSD"
  22
+}
163  parser.js
... ...
@@ -0,0 +1,163 @@
  1
+var Steez = require("steez"),
  2
+    util = require("util");
  3
+
  4
+var Parser = module.exports = function Parser() {
  5
+  Steez.call(this);
  6
+
  7
+  this.buffer = "";
  8
+};
  9
+util.inherits(Parser, Steez);
  10
+
  11
+Parser.prototype.write = function write(data) {
  12
+  data = data.toString();
  13
+
  14
+  this.buffer += data;
  15
+
  16
+  var parts = this.buffer.split(/\r\n/);
  17
+
  18
+  this.buffer = parts.pop();
  19
+
  20
+  parts.forEach(function(part) {
  21
+    if (part.length > 510) {
  22
+      this.emit("error", new Error("line length is too long"));
  23
+      return;
  24
+    }
  25
+
  26
+    try {
  27
+      var message = this.parse(part);
  28
+      this.emit("data", message);
  29
+    } catch (e) {
  30
+      this.emit("error", e);
  31
+    }
  32
+  }.bind(this));
  33
+
  34
+  if (this.buffer.length > 510) {
  35
+    this.emit("error", new Error("line length is too long"));
  36
+  }
  37
+
  38
+  return this.writable && !this.paused;
  39
+};
  40
+
  41
+var RE_NICK = /^([a-z][a-z0-9\-\[\]\\`^\{\}]*)(?: |!|@)/i,
  42
+    RE_USER = /^([^ \r\n@]+)/,
  43
+    RE_SERVER = /^((?:[a-z][a-z0-9-]*\.)*(?:[a-z][a-z0-9-]*))/i,
  44
+    RE_COMMAND = /^(\d{3}|[A-Z]+)/;
  45
+
  46
+Parser.prototype.parse = function parse(text, state) {
  47
+  if (typeof state !== "object" || state === null) { state = {offset: 0}; }
  48
+
  49
+  var message = {};
  50
+
  51
+  if (text[state.offset] === ":") {
  52
+    state.offset++;
  53
+    message.prefix = this.parse_prefix(text, state);
  54
+  }
  55
+
  56
+  message.command = this.parse_command(text, state);
  57
+
  58
+  message.parameters = this.parse_parameters(text, state);
  59
+
  60
+  return message;
  61
+};
  62
+
  63
+Parser.prototype.parse_prefix = function parse_prefix(text, state) {
  64
+  var prefix = {};
  65
+
  66
+  var nick;
  67
+
  68
+  if (nick = this.parse_nick(text, state)) {
  69
+    prefix.nick = nick;
  70
+
  71
+    if (text[state.offset] === "!") {
  72
+      state.offset++;
  73
+      prefix.user = this.parse_user(text, state);
  74
+    }
  75
+
  76
+    if (text[state.offset] === "@") {
  77
+      state.offset++;
  78
+      prefix.server = this.parse_server(text, state);
  79
+    }
  80
+  } else {
  81
+    prefix.server = this.parse_server(text, state);
  82
+  }
  83
+
  84
+  if (text[state.offset] !== " ") {
  85
+    throw new Error("expected whitespace after prefix information");
  86
+  }
  87
+
  88
+  while (text[state.offset] === " ") {
  89
+    state.offset++;
  90
+  }
  91
+
  92
+  return prefix;
  93
+};
  94
+
  95
+Parser.prototype.parse_nick = function parse_nick(text, state) {
  96
+  var nick = (RE_NICK.exec(text.substr(state.offset)) || {})[1];
  97
+
  98
+  if (nick) {
  99
+    state.offset += nick.length;
  100
+  }
  101
+
  102
+  return nick;
  103
+};
  104
+
  105
+Parser.prototype.parse_user = function parse_user(text, state) {
  106
+  var user = (RE_USER.exec(text.substr(state.offset)) || {})[1];
  107
+
  108
+  if (user) {
  109
+    state.offset += user.length;
  110
+  }
  111
+
  112
+  return user;
  113
+};
  114
+
  115
+Parser.prototype.parse_server = function parse_server(text, state) {
  116
+  var server = (RE_SERVER.exec(text.substr(state.offset)) || {})[1];
  117
+
  118
+  if (server) {
  119
+    state.offset += server.length;
  120
+  }
  121
+
  122
+  return server;
  123
+};
  124
+
  125
+Parser.prototype.parse_command = function parse_command(text, state) {
  126
+  var command = (RE_COMMAND.exec(text.substr(state.offset)) || {})[1];
  127
+
  128
+  if (command) {
  129
+    state.offset += command.length;
  130
+  }
  131
+
  132
+  while(text[state.offset] === " ") {
  133
+    state.offset++;
  134
+  }
  135
+
  136
+  return command;
  137
+};
  138
+
  139
+Parser.prototype.parse_parameters = function parse_parameters(text, state) {
  140
+  var parameters = [];
  141
+
  142
+  while (state.offset < text.length) {
  143
+    var parameter = null;
  144
+
  145
+    if (text[state.offset] === ":") {
  146
+      state.offset++;
  147
+      parameter = text.substr(state.offset);
  148
+    } else {
  149
+      parameter = (text.substr(state.offset).match(/^(\S+)/) || {})[1];
  150
+    }
  151
+
  152
+    if (typeof parameter === "string") {
  153
+      parameters.push(parameter);
  154
+      state.offset += parameter.length;
  155
+    }
  156
+
  157
+    while (text[state.offset] === " ") {
  158
+      state.offset++;
  159
+    }
  160
+  }
  161
+
  162
+  return parameters;
  163
+};
21  proxy.js
... ...
@@ -0,0 +1,21 @@
  1
+#!/usr/bin/env node
  2
+
  3
+var net = require("net"),
  4
+    IRCProtocol = require("./index");
  5
+
  6
+var server = net.createServer(function(local) {
  7
+  var local_parser = new IRCProtocol.Parser(),
  8
+      remote_parser = new IRCProtocol.Parser(),
  9
+      local_serialiser = new IRCProtocol.Serialiser(),
  10
+      remote_serialiser = new IRCProtocol.Serialiser();
  11
+
  12
+  var remote = net.createConnection(6667, "127.0.0.1");
  13
+
  14
+  local.pipe(local_parser).pipe(local_serialiser).pipe(remote);
  15
+  remote.pipe(remote_parser).pipe(remote_serialiser).pipe(local);
  16
+
  17
+  local_serialiser.on("data", function(data) { process.stdout.write(">> " + data); });
  18
+  remote_serialiser.on("data", function(data) { process.stdout.write("<< " + data); });
  19
+});
  20
+
  21
+server.listen(6668);
31  serialiser.js
... ...
@@ -0,0 +1,31 @@
  1
+var Steez = require("steez"),
  2
+    util = require("util");
  3
+
  4
+var Serialiser = module.exports = function Serialiser() {
  5
+  Steez.call(this);
  6
+};
  7
+util.inherits(Serialiser, Steez);
  8
+
  9
+Serialiser.prototype.write = function write(message) {
  10
+  this.emit("data", this.format_message(message) + "\r\n");
  11
+
  12
+  return this.writable && !this.paused;
  13
+};
  14
+
  15
+Serialiser.prototype.format_message = function format_message(message) {
  16
+  return [(message.prefix ? ":" + this.format_prefix(message.prefix) + " " : ""), this.format_parameters([message.command].concat(message.parameters || []))].join("");
  17
+};
  18
+
  19
+Serialiser.prototype.format_prefix = function format_prefix(prefix) {
  20
+  if (prefix.nick && (prefix.user || prefix.server)) {
  21
+    return prefix.nick + (prefix.user ? "!" + prefix.user : "") + (prefix.server ? "@" + prefix.server : "");
  22
+  } else if (prefix.nick) {
  23
+    return prefix.nick;
  24
+  } else if (prefix.server) {
  25
+    return prefix.server;
  26
+  }
  27
+};
  28
+
  29
+Serialiser.prototype.format_parameters = function format_parameters(parameters) {
  30
+  return parameters.map(function(e) { return ((e.indexOf(" ") !== -1) ? ":" : "") + e; }).join(" ");
  31
+};

0 notes on commit ec2bbc5

Please sign in to comment.
Something went wrong with that request. Please try again.