input.on('end', function() {
self.emit('end');
});
+ var StringDecoder = require('string_decoder').StringDecoder; // lazy load
+ this._decoder = new StringDecoder('utf8');
} else {
this.terminal ? this._ttyWrite(d, key) : this._normalWrite(d, key);
};
-// telnet on windows sends every single keystroke seperately, so we need
-// to buffer them and only fire the 'line' event when a \n is sent
-Interface.prototype._line_buffer = '';
-
Interface.prototype._normalWrite = function(b) {
if (b === undefined) {
return;
}
- this._line_buffer += b.toString();
- if (this._line_buffer.indexOf('\n') !== -1) {
- var lines = this._line_buffer.split('\n');
+ var string = this._decoder.write(b);
+ if (this._line_buffer) {
+ string = this._line_buffer + string;
+ this._line_buffer = null;
+ }
+ if (string.indexOf('\n') !== -1) {
+ // got one or more newlines; process into "line" events
+ var lines = string.split('\n');
// either '' or (concievably) the unfinished portion of the next line
- this._line_buffer = lines.pop();
+ string = lines.pop();
+ this._line_buffer = string;
lines.forEach(function(line) {
this._onLine(line + '\n');
}, this);
+ } else if (string) {
+ // no newlines this time, save what we have for next time
+ this._line_buffer = string;
}
};
});
fi.emit('data', expectedLines.join(''));
assert.equal(callCount, expectedLines.length - 1);
+
+// sending a multi-byte utf8 char over multiple writes
+var buf = Buffer('☮', 'utf8');
+fi = new FakeInput();
+rli = new readline.Interface(fi, {});
+callCount = 0;
+rli.on('line', function(line) {
+ callCount++;
+ assert.equal(line, buf.toString('utf8') + '\n');
+});
+[].forEach.call(buf, function(i) {
+ fi.emit('data', Buffer([i]));
+});
+assert.equal(callCount, 0);
+fi.emit('data', '\n');
+assert.equal(callCount, 1);