Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

UTF8 fixes and ns.Stream emitter #1

Closed
wants to merge 7 commits into from

2 participants

@josh
  1. Added more edge case test coverage
  2. Fixed utf8 length in nsPayload where a string in passed in. I think we always want to convert string inputs into buffers so we can compute the real byte length.
  3. Added a a Stream class that can wrap another a readable stream but will emit payloads as data instead of broken chunks.

It'd be great if you would publish netstring to npm.

Thanks, Josh.

josh added some commits
@josh josh Test payload length with leading colon ccd71a0
@josh josh Test empty payload is incomplete 175ff13
@josh josh Test empty payload 6f3ea97
@josh josh Fix writing empty netstring 809f01c
@josh josh Fix utf8 lengths
Length should always be the number of bytes in the string,
not always String.length.

If a string is passed to nsPayload, convert it to a Buffer
so we can compute the number of bytes in the string.
9c2c06d
@josh josh Add Stream e877a93
@josh josh Add npm package e9b9c7c
@pgriess
Owner

Pulled into master.

This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Sep 28, 2010
  1. @josh
  2. @josh

    Test empty payload is incomplete

    josh authored
  3. @josh

    Test empty payload

    josh authored
  4. @josh

    Fix writing empty netstring

    josh authored
  5. @josh

    Fix utf8 lengths

    josh authored
    Length should always be the number of bytes in the string,
    not always String.length.
    
    If a string is passed to nsPayload, convert it to a Buffer
    so we can compute the number of bytes in the string.
  6. @josh

    Add Stream

    josh authored
  7. @josh

    Add npm package

    josh authored
This page is out of date. Refresh to see the latest.
Showing with 123 additions and 6 deletions.
  1. +49 −6 lib/ns.js
  2. +22 −0 package.json
  3. +52 −0 test/test.js
View
55 lib/ns.js
@@ -2,6 +2,8 @@
var assert = require('assert');
var Buffer = require('buffer').Buffer;
+var events = require('events');
+var sys = require('sys');
// Get the length of the netstring payload (i.e. excluding header and footer)
// pointed to by Buffer or String 'buf'. Returns -1 if the buffer is
@@ -63,6 +65,10 @@ exports.nsLength = nsLength;
var nsPayload = function(buf, off) {
off = off || 0;
+ if (typeof buf === 'string') {
+ buf = new Buffer(buf.substring(0, buf.length));
+ }
+
var len = nsPayloadLength(buf, off);
if (len < 0) {
return len;
@@ -77,11 +83,7 @@ var nsPayload = function(buf, off) {
var start = off + (nsLen - len - 1);
- if (typeof buf === 'string') {
- return buf.substring(start, start + len);
- } else if (typeof buf === 'object') {
- return buf.slice(start, start + len);
- }
+ return buf.slice(start, start + len);
};
exports.nsPayload = nsPayload;
@@ -126,7 +128,7 @@ var nsWrite = function(pay, payStart, payEnd, buf, bufOff) {
payEnd = (payEnd === undefined) ? pay.length : payEnd;
bufOff = bufOff || 0;
- if (payStart < 0 || payStart >= pay.length) {
+ if (payStart < 0 || payStart > pay.length) {
throw new Error('payStart is out of bounds');
}
@@ -172,3 +174,44 @@ var nsWrite = function(pay, payStart, payEnd, buf, bufOff) {
}
};
exports.nsWrite = nsWrite;
+
+var Stream = function(s) {
+ var self = this;
+
+ events.EventEmitter.call(self);
+
+ self.buf = null;
+
+ s.addListener('data', function(d) {
+ if (self.buf) {
+ var b = new Buffer(self.buf.length + d.length);
+ self.buf.copy(b, 0, 0, self.buf.length);
+ d.copy(b, self.buf.length, 0, d.length);
+
+ self.buf = b;
+ } else {
+ self.buf = d;
+ }
+
+ while (self.buf && self.buf.length > 0) {
+ try {
+ pay = nsPayload(self.buf);
+
+ if (pay == -1) {
+ break;
+ }
+
+ var nsLen = nsWriteLength(pay.length);
+ self.buf = self.buf.slice(nsLen, self.buf.length);
+
+ self.emit('data', pay);
+ } catch (exception) {
+ self.emit('error', exception);
+ break;
+ }
+ }
+ });
+}
+
+sys.inherits(Stream, events.EventEmitter);
+exports.Stream = Stream;
View
22 package.json
@@ -0,0 +1,22 @@
+{
+ "name" : "netstring",
+ "version" : "0.1.0",
+ "description" : "A netstring implementation",
+ "author" : "Peter Griess <pg@std.in>",
+ "engines" : {
+ "node" : ">=0.1.98"
+ },
+ "repositories" : [
+ {
+ "type" : "git",
+ "url" : "http://github.com/pgriess/node-netstring"
+ }
+ ],
+ "licenses" : [
+ {
+ "type" : "BSD",
+ "url" : "http://github.com/pgriess/node-netstring/blob/master/LICENSE"
+ }
+ ],
+ "main" : "./lib/ns.js"
+}
View
52 test/test.js
@@ -2,6 +2,7 @@
var at = require('./async_testing');
var Buffer = require('buffer').Buffer;
+var events = require('events');
var ns = require('../lib/ns');
(function() {
@@ -20,6 +21,7 @@ var ns = require('../lib/ns');
as.equal(ns.nsPayloadLength('30:'), 30);
},
'incomplete' : function(as) {
+ as.equal(ns.nsPayloadLength(''), -1);
as.equal(ns.nsPayloadLength('30'), -1);
},
'leading zero' : function(as) {
@@ -27,6 +29,10 @@ var ns = require('../lib/ns');
ex(as, '03:', 'Invalid netstring with leading 0');
ex(as, '00:', 'Invalid netstring with leading 0');
},
+ 'leading colon' : function(as) {
+ ex(as, ':', 'Invalid netstring with leading \':\'');
+ ex(as, ':a', 'Invalid netstring with leading \':\'');
+ },
'invalid char' : function(as) {
ex(as, '3;', 'Unexpected character \';\' found at offset 1');
ex(as, ';', 'Unexpected character \';\' found at offset 0');
@@ -50,6 +56,7 @@ var ns = require('../lib/ns');
as.equal(ns.nsLength('30:'), 34);
},
'incomplete' : function(as) {
+ as.equal(ns.nsLength(''), -1);
as.equal(ns.nsLength('30'), -1);
},
});
@@ -77,14 +84,20 @@ var ns = require('../lib/ns');
ts.addTests({
'simple' : function(as) {
+ as.equal(ns.nsPayload('0:,'), '');
as.equal(ns.nsPayload('3:abc,'), 'abc');
as.equal(ns.nsPayload(new Buffer('3:abc,')), 'abc');
},
'incomplete' : function(as) {
+ as.equal(ns.nsPayload(''), -1);
as.equal(ns.nsPayload('3'), -1);
as.equal(ns.nsPayload('3:ab'), -1);
as.equal(ns.nsPayload('3:abc'), -1);
},
+ 'utf8' : function(as) {
+ as.equal(ns.nsPayload('3:☃,'), '');
+ as.equal(ns.nsPayload(new Buffer('3:☃,')), '');
+ }
});
ts.runTests();
@@ -119,9 +132,14 @@ var ns = require('../lib/ns');
ts.addTests({
'simple' : function(as) {
+ as.equal(ns.nsWrite(''), '0:,');
as.equal(ns.nsWrite('abc'), '3:abc,');
as.equal(ns.nsWrite('a'), '1:a,');
},
+ 'utf8' : function(as) {
+ as.equal(ns.nsWrite(''), '3:☃,');
+ as.equal(ns.nsWrite(new Buffer('')), '3:☃,');
+ },
'start' : function(as) {
as.equal(ns.nsWrite('abc', 1), '2:bc,');
as.equal(ns.nsWrite('abc', 0), '3:abc,');
@@ -149,3 +167,37 @@ var ns = require('../lib/ns');
ts.runTests();
})();
+
+(function() {
+ var ts = new at.TestSuite('Stream');
+
+ ts.addTests({
+ 'simple' : function(as) {
+ var is = new events.EventEmitter();
+ var ins = new ns.Stream(is);
+
+ var MSGS = [
+ "abc",
+ "hello world!",
+ "café",
+ "a",
+ "b",
+ "c"
+ ];
+
+ var msgsReceived = 0;
+ ins.addListener('data', function(d) {
+ as.equal(d.toString(), MSGS[msgsReceived]);
+ msgsReceived++;
+ });
+
+ is.emit('data', new Buffer("3:abc,"));
+ is.emit('data', new Buffer("12:hello"));
+ is.emit('data', new Buffer(" world!,"));
+ is.emit('data', new Buffer("5:café,"));
+ is.emit('data', new Buffer("1:a,1:b,1:c,"));
+ }
+ });
+
+ ts.runTests();
+})();
Something went wrong with that request. Please try again.