From 5dbed7d9ca1bbd6efcf00bb2bab56ae0d86d6e1f Mon Sep 17 00:00:00 2001 From: eliang Date: Thu, 19 Dec 2013 00:52:04 +0800 Subject: [PATCH] Add support for UTF-16. --- index.js | 89 ++++++++++++++++++++++++++++++++++++++++++++++++++ test/buffer.js | 18 ++++++++++ 2 files changed, 107 insertions(+) diff --git a/index.js b/index.js index ce7e854..ecddf51 100644 --- a/index.js +++ b/index.js @@ -143,6 +143,14 @@ Buffer.byteLength = function (str, encoding) { case 'base64': return base64ToBytes(str).length + case 'ucs2': + case 'ucs-2': + case 'utf16le': + case 'utf-16le': + case 'utf16be': + case 'utf-16be': + return str.length * 2 + default: throw new Error('Unknown encoding') } @@ -232,6 +240,21 @@ function _base64Write (buf, string, offset, length) { return Buffer._charsWritten = blitBuffer(base64ToBytes(string), buf, offset, length) } +function _utf16leWrite (buf, string, offset, length) { + var bytes, pos + return Buffer._charsWritten = blitBuffer(utf16leToBytes(string), buf, offset, length) +} + +function _utf16leWrite (buf, string, offset, length) { + var bytes, pos + return Buffer._charsWritten = blitBuffer(utf16leToBytes(string), buf, offset, length) +} + +function _utf16beWrite (buf, string, offset, length) { + var bytes, pos + return Buffer._charsWritten = blitBuffer(utf16beToBytes(string), buf, offset, length) +} + function BufferWrite (string, offset, length, encoding) { // Support both (string, offset, length, encoding) // and the legacy (string, encoding, offset, length) @@ -276,6 +299,16 @@ function BufferWrite (string, offset, length, encoding) { case 'base64': return _base64Write(this, string, offset, length) + case 'ucs2': + case 'ucs-2': + case 'utf16le': + case 'utf-16le': + return _utf16leWrite(this, string, offset, length) + + case 'utf16be': + case 'utf-16be': + return _utf16beWrite(this, string, offset, length) + default: throw new Error('Unknown encoding') } @@ -313,6 +346,16 @@ function BufferToString (encoding, start, end) { case 'base64': return _base64Slice(self, start, end) + case 'ucs2': + case 'ucs-2': + case 'utf16le': + case 'utf-16le': + return _utf16leSlice(self, start, end) + + case 'utf16be': + case 'utf-16be': + return _utf16beSlice(self, start, end) + default: throw new Error('Unknown encoding') } @@ -406,6 +449,24 @@ function _hexSlice (buf, start, end) { return out } +function _utf16leSlice (buf, start, end) { + var bytes = buf.slice(start, end) + var res = '' + for (var i = 0; i < bytes.length; i += 2) { + res += String.fromCharCode(bytes[i] + bytes[i+1] * 256) + } + return res +} + +function _utf16beSlice (buf, start, end) { + var bytes = buf.slice(start, end) + var res = '' + for (var i = 0; i < bytes.length; i += 2) { + res += String.fromCharCode(bytes[i] * 256 + bytes[i+1]) + } + return res +} + // TODO: add test that modifying the new buffer slice will modify memory in the // original buffer! Use code from: // http://nodejs.org/api/buffer.html#buffer_buf_slice_start_end @@ -1090,6 +1151,34 @@ function asciiToBytes (str) { return byteArray } +function utf16leToBytes (str) { + var c, hi, lo + var byteArray = [] + for (var i = 0; i < str.length; i++) { + c = str.charCodeAt(i) + hi = c >> 8 + lo = c % 256 + byteArray.push(lo) + byteArray.push(hi) + } + + return byteArray +} + +function utf16beToBytes (str) { + var c, hi, lo + var byteArray = [] + for (var i = 0; i < str.length; i++) { + c = str.charCodeAt(i) + hi = c >> 8 + lo = c % 256 + byteArray.push(hi) + byteArray.push(lo) + } + + return byteArray +} + function base64ToBytes (str) { return base64.toByteArray(str) } diff --git a/test/buffer.js b/test/buffer.js index 0d8ff7b..dfab08c 100644 --- a/test/buffer.js +++ b/test/buffer.js @@ -28,6 +28,24 @@ test('utf8 to utf8', function (t) { t.end(); }); +test('utf16be to hexutf16', function (t) { + t.plan(1); + t.equal( + new B("abcd", "utf16be").toString('hex'), + '0061006200630064' + ); + t.end(); +}); + +test('utf16le to hex', function (t) { + t.plan(1); + t.equal( + new B("abcd", "utf16le").toString('hex'), + '6100620063006400' + ); + t.end(); +}); + test('ascii buffer to base64', function (t) { t.plan(1); t.equal( -- 2.34.1