Browse Source

Use some more Binary/F methods for Buffer

v0.7.4-release
Ryan Dahl 15 years ago
parent
commit
08a09bb50a
  1. 31
      doc/api.markdown
  2. 37
      lib/buffer.js
  3. 21
      lib/http.js
  4. 34
      lib/net.js
  5. 6
      test/simple/test-buffer.js

31
doc/api.markdown

@ -31,10 +31,10 @@ All of the examples in the documentation can be run similarly.
Pure Javascript is Unicode friendly but not nice to pure binary data. When Pure Javascript is Unicode friendly but not nice to pure binary data. When
dealing with TCP streams or the file system, it's necessary to handle octet dealing with TCP streams or the file system, it's necessary to handle octet
streams. Node has several stratagies for manipulating, creating, and streams. Node has several strategies for manipulating, creating, and
consuming octet streams. consuming octet streams.
Raw data is stored in instaces of the `Buffer` class. A `Buffer` is similar Raw data is stored in instances of the `Buffer` class. A `Buffer` is similar
to an array of integers but correspond to a raw memory allocation outside to an array of integers but correspond to a raw memory allocation outside
the V8 heap. A `Buffer` cannot be resized. the V8 heap. A `Buffer` cannot be resized.
Access the class at `require('buffer').Buffer`. Access the class at `require('buffer').Buffer`.
@ -59,29 +59,14 @@ Binary (`"binary"`). `"ascii"` and `"binary"` only look at the first 8 bits
of the 16bit JavaScript string characters. The following `Buffer` methods of the 16bit JavaScript string characters. The following `Buffer` methods
allow decoding and encoding of strings: allow decoding and encoding of strings:
- **`buffer.utf8Write(string, offset)`**: Writes `string` to the buffer at - **`buffer.write(string, encoding, offset)`**: Writes `string` to the buffer at
`offset` using UTF-8 encoding. Returns the number of octets written. If `offset` using the given encoding. Returns number of octets written. If
`buffer` did not contain enough space to fit the entire string it will write `buffer` did not contain enough space to fit the entire string it will write
a partial amount of the string. However, this method will not write partial a partial amount of the string. In the case of `encoding=='utf8'`, the
characters. method will not write partial characters.
- **`buffer.binaryWrite(string, offset)`**: Writes `string` to the buffer at - **`buffer.toString(encoding, start, end)`**: Decodes and returns a string assuming
`offset` using binary encoding - that is it will only use the first 8 bits in the given encoding beginning at `start` and ending at `end`.
of each character. Write a partial string if not enough space remains.
Returns number of octets written.
- **`buffer.asciiWrite(string, offset)`**: Writes `string` to the buffer at
`offset` using ASCII encoding. Faster than `utf8Write()`. Write a partial
string if not enough space remains. Returns number of octets written.
- **`buffer.utf8Slice(start, end)`**: Decodes and returns a string assuming
UTF-8 encoding beginning at `start` and ending at `end`.
- **`buffer.binarySlice(start, end)`**: Decodes and returns a string assuming
binary encoding beginning at `start` and ending at `end`.
- **`buffer.asciiSlice(start, end)`**: Decodes and returns a string assuming
ASCII encoding beginning at `start` and ending at `end`.

37
lib/buffer.js

@ -18,19 +18,46 @@ Buffer.prototype.inspect = function () {
}; };
Buffer.prototype.toString = function (encoding, start, stop) { Buffer.prototype.toString = function (encoding, start, stop) {
encoding = encoding || 'utf8'; encoding = (encoding || 'utf8').toLowerCase();
if (!start) start = 0; if (!start) start = 0;
if (!stop) stop = this.length; if (!stop) stop = this.length;
if (encoding == 'utf8') { switch (encoding) {
case 'utf8':
case 'utf-8':
return this.utf8Slice(start, stop); return this.utf8Slice(start, stop);
} else if (encoding == 'ascii') {
case 'ascii':
return this.asciiSlice(start, stop); return this.asciiSlice(start, stop);
} else if (encoding == 'binary') {
case 'binary':
return this.binarySlice(start, stop); return this.binarySlice(start, stop);
} else {
default:
throw new Error('Unknown encoding');
}
};
Buffer.prototype.write = function (string, encoding, offset) {
encoding = (encoding || 'utf8').toLowerCase();
switch (encoding) {
case 'utf8':
case 'utf-8':
return this.utf8Write(string, offset);
case 'ascii':
return this.asciiWrite(string, offset);
case 'binary':
return this.binaryWrite(string, offset);
default:
throw new Error('Unknown encoding'); throw new Error('Unknown encoding');
} }
}; };

21
lib/http.js

@ -31,7 +31,7 @@ function newParser (type) {
// Only servers will get URL events. // Only servers will get URL events.
parser.onURL = function (b, start, len) { parser.onURL = function (b, start, len) {
var slice = b.asciiSlice(start, start+len); var slice = b.toString('ascii', start, start+len);
if (parser.incoming.url) { if (parser.incoming.url) {
parser.incoming.url += slice; parser.incoming.url += slice;
} else { } else {
@ -41,7 +41,7 @@ function newParser (type) {
}; };
parser.onHeaderField = function (b, start, len) { parser.onHeaderField = function (b, start, len) {
var slice = b.asciiSlice(start, start+len).toLowerCase(); var slice = b.toString('ascii', start, start+len).toLowerCase();
if (parser.value) { if (parser.value) {
parser.incoming._addHeaderLine(parser.field, parser.value); parser.incoming._addHeaderLine(parser.field, parser.value);
parser.field = null; parser.field = null;
@ -55,7 +55,7 @@ function newParser (type) {
}; };
parser.onHeaderValue = function (b, start, len) { parser.onHeaderValue = function (b, start, len) {
var slice = b.asciiSlice(start, start+len); var slice = b.toString('ascii', start, start+len);
if (parser.value) { if (parser.value) {
parser.value += slice; parser.value += slice;
} else { } else {
@ -88,20 +88,7 @@ function newParser (type) {
if (!enc) { if (!enc) {
parser.incoming.emit('data', b.slice(start, start+len)); parser.incoming.emit('data', b.slice(start, start+len));
} else { } else {
var string; var string = b.toString(enc, start, start+len);
switch (enc) {
case 'utf8':
string = b.utf8Slice(start, start+len);
break;
case 'ascii':
string = b.asciiSlice(start, start+len);
break;
case 'binary':
string = b.binarySlice(start, start+len);
break;
default:
throw new Error('Unsupported encoding ' + enc + '. Use Buffer');
}
parser.incoming.emit('data', string); parser.incoming.emit('data', string);
} }
}; };

34
lib/net.js

@ -308,22 +308,7 @@ function initStream (self) {
// Optimization: emit the original buffer with end points // Optimization: emit the original buffer with end points
if (self.ondata) self.ondata(pool, start, end); if (self.ondata) self.ondata(pool, start, end);
} else { } else {
// TODO remove me - we should only output Buffer var string = pool.toString(self._encoding, start, end);
var string;
switch (self._encoding) {
case 'utf8':
string = pool.utf8Slice(start, end);
break;
case 'ascii':
string = pool.asciiSlice(start, end);
break;
case 'binary':
string = pool.binarySlice(start, end);
break;
default:
throw new Error('Unsupported encoding ' + self._encoding + '. Use Buffer');
}
self.emit('data', string); self.emit('data', string);
} }
} }
@ -442,21 +427,16 @@ Stream.prototype._writeOut = function (data, encoding) {
allocNewPool(); allocNewPool();
} }
if (encoding == 'binary') { if (encoding == 'utf8' || encoding == 'utf-8') {
bytesWritten = pool.binaryWrite(data, pool.used);
charsWritten = bytesWritten;
} else if (encoding == 'ascii') {
bytesWritten = pool.asciiWrite(data, pool.used);
charsWritten = bytesWritten;
} else {
// default to utf8 // default to utf8
bytesWritten = pool.utf8Write(data, pool.used); bytesWritten = pool.write(data, 'utf8', pool.used);
// XXX Hacky way to find out the number of characters written. // XXX Hacky way to find out the number of characters written.
// Waiting for a more optimal way: http://codereview.chromium.org/1539013 // Waiting for a more optimal way: http://codereview.chromium.org/1539013
var _s = pool.utf8Slice(pool.used, pool.used + bytesWritten); var _s = pool.toString('utf8', pool.used, pool.used + bytesWritten);
charsWritten = _s.length; charsWritten = _s.length;
} else {
bytesWritten = pool.write(data, encoding, pool.used);
charsWritten = bytesWritten;
} }
assert(bytesWritten > 0); assert(bytesWritten > 0);

6
test/simple/test-buffer.js

@ -34,12 +34,12 @@ for (var j = 0; j < 500; j++) {
for (var i = 0; i < asciiString.length; i++) { for (var i = 0; i < asciiString.length; i++) {
b[i] = asciiString.charCodeAt(i); b[i] = asciiString.charCodeAt(i);
} }
var asciiSlice = b.asciiSlice(0, asciiString.length); var asciiSlice = b.toString('ascii', 0, asciiString.length);
assert.equal(asciiString, asciiSlice); assert.equal(asciiString, asciiSlice);
var written = b.asciiWrite(asciiString, offset); var written = b.asciiWrite(asciiString, offset);
assert.equal(asciiString.length, written); assert.equal(asciiString.length, written);
var asciiSlice = b.asciiSlice(offset, offset+asciiString.length); var asciiSlice = b.toString('ascii', offset, offset+asciiString.length);
assert.equal(asciiString, asciiSlice); assert.equal(asciiString, asciiSlice);
var sliceA = b.slice(offset, offset+asciiString.length); var sliceA = b.slice(offset, offset+asciiString.length);
@ -91,7 +91,7 @@ var testValue = '\u00F6\u65E5\u672C\u8A9E'; // ö日本語
var buffer = new Buffer(32); var buffer = new Buffer(32);
var size = buffer.utf8Write(testValue, 0); var size = buffer.utf8Write(testValue, 0);
puts('bytes written to buffer: ' + size); puts('bytes written to buffer: ' + size);
var slice = buffer.utf8Slice(0, size); var slice = buffer.toString('utf8', 0, size);
assert.equal(slice, testValue); assert.equal(slice, testValue);

Loading…
Cancel
Save