[Pkg-javascript-commits] [node-string-decoder] 01/03: Imported Upstream version 0.10.25
Sebastiaan Couwenberg
sebastic at moszumanska.debian.org
Sat Mar 7 22:38:26 UTC 2015
This is an automated email from the git hooks/post-receive script.
sebastic pushed a commit to branch master
in repository node-string-decoder.
commit ee674149d9858e75360ecef4421a47c3e3689f30
Author: Bas Couwenberg <sebastic at xs4all.nl>
Date: Sat Mar 7 23:13:23 2015 +0100
Imported Upstream version 0.10.25
---
.gitignore | 1 +
LICENSE | 20 ++++
README.md | 7 ++
build/.gitignore | 1 +
build/build.js | 94 ++++++++++++++++
build/files.js | 36 ++++++
build/package.json | 12 ++
build/test-replacements.js | 24 ++++
index.js | 200 +++++++++++++++++++++++++++++++++
package.json | 25 +++++
test/common.js | 200 +++++++++++++++++++++++++++++++++
test/simple/test-string-decoder-end.js | 75 +++++++++++++
test/simple/test-string-decoder.js | 163 +++++++++++++++++++++++++++
13 files changed, 858 insertions(+)
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..b512c09
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+node_modules
\ No newline at end of file
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..6de584a
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,20 @@
+Copyright Joyent, Inc. and other Node contributors.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to permit
+persons to whom the Software is furnished to do so, subject to the
+following conditions:
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..4d2aa00
--- /dev/null
+++ b/README.md
@@ -0,0 +1,7 @@
+**string_decoder.js** (`require('string_decoder')`) from Node.js core
+
+Copyright Joyent, Inc. and other Node contributors. See LICENCE file for details.
+
+Version numbers match the versions found in Node core, e.g. 0.10.24 matches Node 0.10.24, likewise 0.11.10 matches Node 0.11.10. **Prefer the stable version over the unstable.**
+
+The *build/* directory contains a build script that will scrape the source from the [joyent/node](https://github.com/joyent/node) repo given a specific Node version.
\ No newline at end of file
diff --git a/build/.gitignore b/build/.gitignore
new file mode 100644
index 0000000..3c3629e
--- /dev/null
+++ b/build/.gitignore
@@ -0,0 +1 @@
+node_modules
diff --git a/build/build.js b/build/build.js
new file mode 100755
index 0000000..46470cf
--- /dev/null
+++ b/build/build.js
@@ -0,0 +1,94 @@
+#!/usr/bin/env node
+
+const hyperquest = require('hyperzip')(require('hyperdirect'))
+ , bl = require('bl')
+ , fs = require('fs')
+ , path = require('path')
+ , cheerio = require('cheerio')
+
+ , files = require('./files')
+ , testReplace = require('./test-replacements')
+
+ , srcurlpfx = 'https://raw.github.com/joyent/node/v' + process.argv[2] + '-release/'
+ , libsrcurl = srcurlpfx + 'lib/'
+ , testsrcurl = srcurlpfx + 'test/simple/'
+ , testlisturl = 'https://github.com/joyent/node/tree/v' + process.argv[2] + '-release/test/simple'
+ , libourroot = path.join(__dirname, '../')
+ , testourroot = path.join(__dirname, '../test/simple/')
+
+
+function processFile (url, out, replacements) {
+ hyperquest(url).pipe(bl(function (err, data) {
+ if (err)
+ throw err
+
+ data = data.toString()
+ replacements.forEach(function (replacement) {
+ data = data.replace.apply(data, replacement)
+ })
+
+ fs.writeFile(out, data, 'utf8', function (err) {
+ if (err)
+ throw err
+
+ console.log('Wrote', out)
+ })
+ }))
+}
+
+function processLibFile (file) {
+ var replacements = files[file]
+ , url = libsrcurl + file
+ , out = path.join(libourroot, replacements.out || file)
+
+ processFile(url, out, replacements)
+}
+
+
+function processTestFile (file) {
+ var replacements = testReplace.all
+ , url = testsrcurl + file
+ , out = path.join(testourroot, file)
+
+ if (testReplace[file])
+ replacements = replacements.concat(testReplace[file])
+
+ processFile(url, out, replacements)
+}
+
+
+if (!/0\.1\d\.\d+/.test(process.argv[2])) {
+ console.log('Usage: build.js <node version>')
+ return process.exit(-1)
+}
+
+
+//--------------------------------------------------------------------
+// Grab & process files in ../lib/
+
+Object.keys(files).forEach(processLibFile)
+
+//--------------------------------------------------------------------
+// Discover, grab and process all test-string-decoder* files on joyent/node
+
+hyperquest(testlisturl).pipe(bl(function (err, data) {
+ if (err)
+ throw err
+
+ var $ = cheerio.load(data.toString())
+
+ $('table.files .js-directory-link').each(function () {
+ var file = $(this).text()
+ if (/^test-string-decoder/.test(file) || file == 'common.js')
+ processTestFile(file)
+ })
+}))
+
+//--------------------------------------------------------------------
+// Grab the joyent/node test/common.js
+
+processFile(
+ testsrcurl + '../common.js'
+ , path.join(testourroot, '../common.js')
+ , testReplace['common.js']
+)
\ No newline at end of file
diff --git a/build/files.js b/build/files.js
new file mode 100644
index 0000000..7396a4f
--- /dev/null
+++ b/build/files.js
@@ -0,0 +1,36 @@
+/* This file lists the files to be fetched from the node repo
+ * in the /lib/ directory which will be placed in the ../lib/
+ * directory after having each of the "replacements" in the
+ * array for that file applied to it. The replacements are
+ * simply the arguments to String#replace, so they can be
+ * strings, regexes, functions.
+ */
+
+module.exports['string_decoder.js'] = [
+
+ // pull in Bufer as a require
+ // add Buffer.isEncoding where missing
+ [
+ /^(\/\/ USE OR OTHER DEALINGS IN THE SOFTWARE\.)/m
+ , '$1\n\nvar Buffer = require(\'buffer\').Buffer;'
+ + '\n'
+ + '\nvar isBufferEncoding = Buffer.isEncoding'
+ + '\n || function(encoding) {'
+ + '\n switch (encoding && encoding.toLowerCase()) {'
+ + '\n case \'hex\': case \'utf8\': case \'utf-8\': case \'ascii\': case \'binary\': case \'base64\': case \'ucs2\': case \'ucs-2\': case \'utf16le\': case \'utf-16le\': case \'raw\': return true;'
+ + '\n default: return false;'
+ + '\n }'
+ + '\n }'
+ + '\n'
+
+ ]
+
+ // use custom Buffer.isEncoding reference
+ , [
+ /Buffer\.isEncoding\(/g
+ , 'isBufferEncoding\('
+ ]
+
+]
+
+module.exports['string_decoder.js'].out = 'index.js'
\ No newline at end of file
diff --git a/build/package.json b/build/package.json
new file mode 100644
index 0000000..f7ee6a4
--- /dev/null
+++ b/build/package.json
@@ -0,0 +1,12 @@
+{
+ "name": "string_decoder-build",
+ "version": "0.0.0",
+ "description": "",
+ "main": "build.js",
+ "dependencies": {
+ "bl": "~0.6.0",
+ "hyperzip": "0.0.0",
+ "hyperdirect": "0.0.0",
+ "cheerio": "~0.13.1"
+ }
+}
diff --git a/build/test-replacements.js b/build/test-replacements.js
new file mode 100644
index 0000000..5bbf602
--- /dev/null
+++ b/build/test-replacements.js
@@ -0,0 +1,24 @@
+module.exports.all = [
+ [
+ /require\(['"]string_decoder['"]\)/g
+ , 'require(\'../../\')'
+ ]
+
+]
+
+module.exports['common.js'] = [
+ [
+ /^ setImmediate,$/m
+ , ' typeof setImmediate == \'undefined\' ? null : setImmediate,'
+ ]
+
+ , [
+ /^ clearImmediate,$/m
+ , ' typeof clearImmediate == \'undefined\' ? null : clearImmediate,'
+ ]
+
+ , [
+ /^ global];$/m
+ , ' global].filter(Boolean);'
+ ]
+]
diff --git a/index.js b/index.js
new file mode 100644
index 0000000..2e44a03
--- /dev/null
+++ b/index.js
@@ -0,0 +1,200 @@
+// Copyright Joyent, Inc. and other Node contributors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to permit
+// persons to whom the Software is furnished to do so, subject to the
+// following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+// USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+var Buffer = require('buffer').Buffer;
+
+var isBufferEncoding = Buffer.isEncoding
+ || function(encoding) {
+ switch (encoding && encoding.toLowerCase()) {
+ case 'hex': case 'utf8': case 'utf-8': case 'ascii': case 'binary': case 'base64': case 'ucs2': case 'ucs-2': case 'utf16le': case 'utf-16le': case 'raw': return true;
+ default: return false;
+ }
+ }
+
+
+function assertEncoding(encoding) {
+ if (encoding && !isBufferEncoding(encoding)) {
+ throw new Error('Unknown encoding: ' + encoding);
+ }
+}
+
+var StringDecoder = exports.StringDecoder = function(encoding) {
+ this.encoding = (encoding || 'utf8').toLowerCase().replace(/[-_]/, '');
+ assertEncoding(encoding);
+ switch (this.encoding) {
+ case 'utf8':
+ // CESU-8 represents each of Surrogate Pair by 3-bytes
+ this.surrogateSize = 3;
+ break;
+ case 'ucs2':
+ case 'utf16le':
+ // UTF-16 represents each of Surrogate Pair by 2-bytes
+ this.surrogateSize = 2;
+ this.detectIncompleteChar = utf16DetectIncompleteChar;
+ break;
+ case 'base64':
+ // Base-64 stores 3 bytes in 4 chars, and pads the remainder.
+ this.surrogateSize = 3;
+ this.detectIncompleteChar = base64DetectIncompleteChar;
+ break;
+ default:
+ this.write = passThroughWrite;
+ return;
+ }
+
+ this.charBuffer = new Buffer(6);
+ this.charReceived = 0;
+ this.charLength = 0;
+};
+
+
+StringDecoder.prototype.write = function(buffer) {
+ var charStr = '';
+ var offset = 0;
+
+ // if our last write ended with an incomplete multibyte character
+ while (this.charLength) {
+ // determine how many remaining bytes this buffer has to offer for this char
+ var i = (buffer.length >= this.charLength - this.charReceived) ?
+ this.charLength - this.charReceived :
+ buffer.length;
+
+ // add the new bytes to the char buffer
+ buffer.copy(this.charBuffer, this.charReceived, offset, i);
+ this.charReceived += (i - offset);
+ offset = i;
+
+ if (this.charReceived < this.charLength) {
+ // still not enough chars in this buffer? wait for more ...
+ return '';
+ }
+
+ // get the character that was split
+ charStr = this.charBuffer.slice(0, this.charLength).toString(this.encoding);
+
+ // lead surrogate (D800-DBFF) is also the incomplete character
+ var charCode = charStr.charCodeAt(charStr.length - 1);
+ if (charCode >= 0xD800 && charCode <= 0xDBFF) {
+ this.charLength += this.surrogateSize;
+ charStr = '';
+ continue;
+ }
+ this.charReceived = this.charLength = 0;
+
+ // if there are no more bytes in this buffer, just emit our char
+ if (i == buffer.length) return charStr;
+
+ // otherwise cut off the characters end from the beginning of this buffer
+ buffer = buffer.slice(i, buffer.length);
+ break;
+ }
+
+ var lenIncomplete = this.detectIncompleteChar(buffer);
+
+ var end = buffer.length;
+ if (this.charLength) {
+ // buffer the incomplete character bytes we got
+ buffer.copy(this.charBuffer, 0, buffer.length - lenIncomplete, end);
+ this.charReceived = lenIncomplete;
+ end -= lenIncomplete;
+ }
+
+ charStr += buffer.toString(this.encoding, 0, end);
+
+ var end = charStr.length - 1;
+ var charCode = charStr.charCodeAt(end);
+ // lead surrogate (D800-DBFF) is also the incomplete character
+ if (charCode >= 0xD800 && charCode <= 0xDBFF) {
+ var size = this.surrogateSize;
+ this.charLength += size;
+ this.charReceived += size;
+ this.charBuffer.copy(this.charBuffer, size, 0, size);
+ this.charBuffer.write(charStr.charAt(charStr.length - 1), this.encoding);
+ return charStr.substring(0, end);
+ }
+
+ // or just emit the charStr
+ return charStr;
+};
+
+StringDecoder.prototype.detectIncompleteChar = function(buffer) {
+ // determine how many bytes we have to check at the end of this buffer
+ var i = (buffer.length >= 3) ? 3 : buffer.length;
+
+ // Figure out if one of the last i bytes of our buffer announces an
+ // incomplete char.
+ for (; i > 0; i--) {
+ var c = buffer[buffer.length - i];
+
+ // See http://en.wikipedia.org/wiki/UTF-8#Description
+
+ // 110XXXXX
+ if (i == 1 && c >> 5 == 0x06) {
+ this.charLength = 2;
+ break;
+ }
+
+ // 1110XXXX
+ if (i <= 2 && c >> 4 == 0x0E) {
+ this.charLength = 3;
+ break;
+ }
+
+ // 11110XXX
+ if (i <= 3 && c >> 3 == 0x1E) {
+ this.charLength = 4;
+ break;
+ }
+ }
+
+ return i;
+};
+
+StringDecoder.prototype.end = function(buffer) {
+ var res = '';
+ if (buffer && buffer.length)
+ res = this.write(buffer);
+
+ if (this.charReceived) {
+ var cr = this.charReceived;
+ var buf = this.charBuffer;
+ var enc = this.encoding;
+ res += buf.slice(0, cr).toString(enc);
+ }
+
+ return res;
+};
+
+function passThroughWrite(buffer) {
+ return buffer.toString(this.encoding);
+}
+
+function utf16DetectIncompleteChar(buffer) {
+ var incomplete = this.charReceived = buffer.length % 2;
+ this.charLength = incomplete ? 2 : 0;
+ return incomplete;
+}
+
+function base64DetectIncompleteChar(buffer) {
+ var incomplete = this.charReceived = buffer.length % 3;
+ this.charLength = incomplete ? 3 : 0;
+ return incomplete;
+}
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..45f7db9
--- /dev/null
+++ b/package.json
@@ -0,0 +1,25 @@
+{
+ "name": "string_decoder",
+ "version": "0.10.25",
+ "description": "The string_decoder module from Node core",
+ "main": "index.js",
+ "dependencies": {},
+ "devDependencies": {
+ "tap": "~0.4.8"
+ },
+ "scripts": {
+ "test": "tap test/simple/*.js"
+ },
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/rvagg/string_decoder.git"
+ },
+ "homepage": "https://github.com/rvagg/string_decoder",
+ "keywords": [
+ "string",
+ "decoder",
+ "browser",
+ "browserify"
+ ],
+ "license": "MIT"
+}
diff --git a/test/common.js b/test/common.js
new file mode 100644
index 0000000..ed5ff08
--- /dev/null
+++ b/test/common.js
@@ -0,0 +1,200 @@
+// Copyright Joyent, Inc. and other Node contributors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to permit
+// persons to whom the Software is furnished to do so, subject to the
+// following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+// USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+var path = require('path');
+var assert = require('assert');
+
+exports.testDir = path.dirname(__filename);
+exports.fixturesDir = path.join(exports.testDir, 'fixtures');
+exports.libDir = path.join(exports.testDir, '../lib');
+exports.tmpDir = path.join(exports.testDir, 'tmp');
+exports.PORT = +process.env.NODE_COMMON_PORT || 12346;
+
+if (process.platform === 'win32') {
+ exports.PIPE = '\\\\.\\pipe\\libuv-test';
+} else {
+ exports.PIPE = exports.tmpDir + '/test.sock';
+}
+
+var util = require('util');
+for (var i in util) exports[i] = util[i];
+//for (var i in exports) global[i] = exports[i];
+
+function protoCtrChain(o) {
+ var result = [];
+ for (; o; o = o.__proto__) { result.push(o.constructor); }
+ return result.join();
+}
+
+exports.indirectInstanceOf = function(obj, cls) {
+ if (obj instanceof cls) { return true; }
+ var clsChain = protoCtrChain(cls.prototype);
+ var objChain = protoCtrChain(obj);
+ return objChain.slice(-clsChain.length) === clsChain;
+};
+
+
+exports.ddCommand = function(filename, kilobytes) {
+ if (process.platform === 'win32') {
+ var p = path.resolve(exports.fixturesDir, 'create-file.js');
+ return '"' + process.argv[0] + '" "' + p + '" "' +
+ filename + '" ' + (kilobytes * 1024);
+ } else {
+ return 'dd if=/dev/zero of="' + filename + '" bs=1024 count=' + kilobytes;
+ }
+};
+
+
+exports.spawnCat = function(options) {
+ var spawn = require('child_process').spawn;
+
+ if (process.platform === 'win32') {
+ return spawn('more', [], options);
+ } else {
+ return spawn('cat', [], options);
+ }
+};
+
+
+exports.spawnPwd = function(options) {
+ var spawn = require('child_process').spawn;
+
+ if (process.platform === 'win32') {
+ return spawn('cmd.exe', ['/c', 'cd'], options);
+ } else {
+ return spawn('pwd', [], options);
+ }
+};
+
+
+// Turn this off if the test should not check for global leaks.
+exports.globalCheck = true;
+
+process.on('exit', function() {
+ if (!exports.globalCheck) return;
+ var knownGlobals = [setTimeout,
+ setInterval,
+ typeof setImmediate == 'undefined' ? null : setImmediate,
+ clearTimeout,
+ clearInterval,
+ typeof clearImmediate == 'undefined' ? null : clearImmediate,
+ console,
+ Buffer,
+ process,
+ global].filter(Boolean);
+
+ if (global.gc) {
+ knownGlobals.push(gc);
+ }
+
+ if (global.DTRACE_HTTP_SERVER_RESPONSE) {
+ knownGlobals.push(DTRACE_HTTP_SERVER_RESPONSE);
+ knownGlobals.push(DTRACE_HTTP_SERVER_REQUEST);
+ knownGlobals.push(DTRACE_HTTP_CLIENT_RESPONSE);
+ knownGlobals.push(DTRACE_HTTP_CLIENT_REQUEST);
+ knownGlobals.push(DTRACE_NET_STREAM_END);
+ knownGlobals.push(DTRACE_NET_SERVER_CONNECTION);
+ knownGlobals.push(DTRACE_NET_SOCKET_READ);
+ knownGlobals.push(DTRACE_NET_SOCKET_WRITE);
+ }
+ if (global.COUNTER_NET_SERVER_CONNECTION) {
+ knownGlobals.push(COUNTER_NET_SERVER_CONNECTION);
+ knownGlobals.push(COUNTER_NET_SERVER_CONNECTION_CLOSE);
+ knownGlobals.push(COUNTER_HTTP_SERVER_REQUEST);
+ knownGlobals.push(COUNTER_HTTP_SERVER_RESPONSE);
+ knownGlobals.push(COUNTER_HTTP_CLIENT_REQUEST);
+ knownGlobals.push(COUNTER_HTTP_CLIENT_RESPONSE);
+ }
+
+ if (global.ArrayBuffer) {
+ knownGlobals.push(ArrayBuffer);
+ knownGlobals.push(Int8Array);
+ knownGlobals.push(Uint8Array);
+ knownGlobals.push(Uint8ClampedArray);
+ knownGlobals.push(Int16Array);
+ knownGlobals.push(Uint16Array);
+ knownGlobals.push(Int32Array);
+ knownGlobals.push(Uint32Array);
+ knownGlobals.push(Float32Array);
+ knownGlobals.push(Float64Array);
+ knownGlobals.push(DataView);
+ }
+
+ for (var x in global) {
+ var found = false;
+
+ for (var y in knownGlobals) {
+ if (global[x] === knownGlobals[y]) {
+ found = true;
+ break;
+ }
+ }
+
+ if (!found) {
+ console.error('Unknown global: %s', x);
+ assert.ok(false, 'Unknown global found');
+ }
+ }
+});
+
+
+var mustCallChecks = [];
+
+
+function runCallChecks(exitCode) {
+ if (exitCode !== 0) return;
+
+ var failed = mustCallChecks.filter(function(context) {
+ return context.actual !== context.expected;
+ });
+
+ failed.forEach(function(context) {
+ console.log('Mismatched %s function calls. Expected %d, actual %d.',
+ context.name,
+ context.expected,
+ context.actual);
+ console.log(context.stack.split('\n').slice(2).join('\n'));
+ });
+
+ if (failed.length) process.exit(1);
+}
+
+
+exports.mustCall = function(fn, expected) {
+ if (typeof expected !== 'number') expected = 1;
+
+ var context = {
+ expected: expected,
+ actual: 0,
+ stack: (new Error).stack,
+ name: fn.name || '<anonymous>'
+ };
+
+ // add the exit listener only once to avoid listener leak warnings
+ if (mustCallChecks.length === 0) process.on('exit', runCallChecks);
+
+ mustCallChecks.push(context);
+
+ return function() {
+ context.actual++;
+ return fn.apply(this, arguments);
+ };
+};
diff --git a/test/simple/test-string-decoder-end.js b/test/simple/test-string-decoder-end.js
new file mode 100644
index 0000000..869a411
--- /dev/null
+++ b/test/simple/test-string-decoder-end.js
@@ -0,0 +1,75 @@
+// Copyright Joyent, Inc. and other Node contributors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to permit
+// persons to whom the Software is furnished to do so, subject to the
+// following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+// USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+// verify that the string decoder works getting 1 byte at a time,
+// the whole buffer at once, and that both match the .toString(enc)
+// result of the entire buffer.
+
+var assert = require('assert');
+var SD = require('../../').StringDecoder;
+var encodings = ['base64', 'hex', 'utf8', 'utf16le', 'ucs2'];
+
+var bufs = [ '☃💩', 'asdf' ].map(function(b) {
+ return new Buffer(b);
+});
+
+// also test just arbitrary bytes from 0-15.
+for (var i = 1; i <= 16; i++) {
+ var bytes = new Array(i).join('.').split('.').map(function(_, j) {
+ return j + 0x78;
+ });
+ bufs.push(new Buffer(bytes));
+}
+
+encodings.forEach(testEncoding);
+
+console.log('ok');
+
+function testEncoding(encoding) {
+ bufs.forEach(function(buf) {
+ testBuf(encoding, buf);
+ });
+}
+
+function testBuf(encoding, buf) {
+ console.error('# %s', encoding, buf);
+
+ // write one byte at a time.
+ var s = new SD(encoding);
+ var res1 = '';
+ for (var i = 0; i < buf.length; i++) {
+ res1 += s.write(buf.slice(i, i + 1));
+ }
+ res1 += s.end();
+
+ // write the whole buffer at once.
+ var res2 = '';
+ var s = new SD(encoding);
+ res2 += s.write(buf);
+ res2 += s.end();
+
+ // .toString() on the buffer
+ var res3 = buf.toString(encoding);
+
+ console.log('expect=%j', res3);
+ assert.equal(res1, res3, 'one byte at a time should match toString');
+ assert.equal(res2, res3, 'all bytes at once should match toString');
+}
diff --git a/test/simple/test-string-decoder.js b/test/simple/test-string-decoder.js
new file mode 100644
index 0000000..7f69f7e
--- /dev/null
+++ b/test/simple/test-string-decoder.js
@@ -0,0 +1,163 @@
+// Copyright Joyent, Inc. and other Node contributors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to permit
+// persons to whom the Software is furnished to do so, subject to the
+// following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+// USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+var common = require('../common');
+var assert = require('assert');
+var StringDecoder = require('../../').StringDecoder;
+var decoder = new StringDecoder('utf8');
+
+
+
+var buffer = new Buffer('$');
+assert.deepEqual('$', decoder.write(buffer));
+
+buffer = new Buffer('¢');
+assert.deepEqual('', decoder.write(buffer.slice(0, 1)));
+assert.deepEqual('¢', decoder.write(buffer.slice(1, 2)));
+
+buffer = new Buffer('€');
+assert.deepEqual('', decoder.write(buffer.slice(0, 1)));
+assert.deepEqual('', decoder.write(buffer.slice(1, 2)));
+assert.deepEqual('€', decoder.write(buffer.slice(2, 3)));
+
+buffer = new Buffer([0xF0, 0xA4, 0xAD, 0xA2]);
+var s = '';
+s += decoder.write(buffer.slice(0, 1));
+s += decoder.write(buffer.slice(1, 2));
+s += decoder.write(buffer.slice(2, 3));
+s += decoder.write(buffer.slice(3, 4));
+assert.ok(s.length > 0);
+
+// CESU-8
+buffer = new Buffer('EDA0BDEDB18D', 'hex'); // THUMBS UP SIGN (in CESU-8)
+var s = '';
+s += decoder.write(buffer.slice(0, 1));
+s += decoder.write(buffer.slice(1, 2));
+s += decoder.write(buffer.slice(2, 3)); // complete lead surrogate
+assert.equal(s, '');
+s += decoder.write(buffer.slice(3, 4));
+s += decoder.write(buffer.slice(4, 5));
+s += decoder.write(buffer.slice(5, 6)); // complete trail surrogate
+assert.equal(s, '\uD83D\uDC4D'); // THUMBS UP SIGN (in UTF-16)
+
+var s = '';
+s += decoder.write(buffer.slice(0, 2));
+s += decoder.write(buffer.slice(2, 4)); // complete lead surrogate
+assert.equal(s, '');
+s += decoder.write(buffer.slice(4, 6)); // complete trail surrogate
+assert.equal(s, '\uD83D\uDC4D'); // THUMBS UP SIGN (in UTF-16)
+
+var s = '';
+s += decoder.write(buffer.slice(0, 3)); // complete lead surrogate
+assert.equal(s, '');
+s += decoder.write(buffer.slice(3, 6)); // complete trail surrogate
+assert.equal(s, '\uD83D\uDC4D'); // THUMBS UP SIGN (in UTF-16)
+
+var s = '';
+s += decoder.write(buffer.slice(0, 4)); // complete lead surrogate
+assert.equal(s, '');
+s += decoder.write(buffer.slice(4, 5));
+s += decoder.write(buffer.slice(5, 6)); // complete trail surrogate
+assert.equal(s, '\uD83D\uDC4D'); // THUMBS UP SIGN (in UTF-16)
+
+var s = '';
+s += decoder.write(buffer.slice(0, 5)); // complete lead surrogate
+assert.equal(s, '');
+s += decoder.write(buffer.slice(5, 6)); // complete trail surrogate
+assert.equal(s, '\uD83D\uDC4D'); // THUMBS UP SIGN (in UTF-16)
+
+var s = '';
+s += decoder.write(buffer.slice(0, 6));
+assert.equal(s, '\uD83D\uDC4D'); // THUMBS UP SIGN (in UTF-16)
+
+
+// UCS-2
+decoder = new StringDecoder('ucs2');
+buffer = new Buffer('ab', 'ucs2');
+assert.equal(decoder.write(buffer), 'ab'); // 2 complete chars
+buffer = new Buffer('abc', 'ucs2');
+assert.equal(decoder.write(buffer.slice(0, 3)), 'a'); // 'a' and first of 'b'
+assert.equal(decoder.write(buffer.slice(3, 6)), 'bc'); // second of 'b' and 'c'
+
+
+// UTF-16LE
+buffer = new Buffer('3DD84DDC', 'hex'); // THUMBS UP SIGN (in CESU-8)
+var s = '';
+s += decoder.write(buffer.slice(0, 1));
+s += decoder.write(buffer.slice(1, 2)); // complete lead surrogate
+assert.equal(s, '');
+s += decoder.write(buffer.slice(2, 3));
+s += decoder.write(buffer.slice(3, 4)); // complete trail surrogate
+assert.equal(s, '\uD83D\uDC4D'); // THUMBS UP SIGN (in UTF-16)
+
+var s = '';
+s += decoder.write(buffer.slice(0, 2)); // complete lead surrogate
+assert.equal(s, '');
+s += decoder.write(buffer.slice(2, 4)); // complete trail surrogate
+assert.equal(s, '\uD83D\uDC4D'); // THUMBS UP SIGN (in UTF-16)
+
+var s = '';
+s += decoder.write(buffer.slice(0, 3)); // complete lead surrogate
+assert.equal(s, '');
+s += decoder.write(buffer.slice(3, 4)); // complete trail surrogate
+assert.equal(s, '\uD83D\uDC4D'); // THUMBS UP SIGN (in UTF-16)
+
+var s = '';
+s += decoder.write(buffer.slice(0, 4));
+assert.equal(s, '\uD83D\uDC4D'); // THUMBS UP SIGN (in UTF-16)
+
+
+// A mixed ascii and non-ascii string
+// Test stolen from deps/v8/test/cctest/test-strings.cc
+// U+02E4 -> CB A4
+// U+0064 -> 64
+// U+12E4 -> E1 8B A4
+// U+0030 -> 30
+// U+3045 -> E3 81 85
+var expected = '\u02e4\u0064\u12e4\u0030\u3045';
+var buffer = new Buffer([0xCB, 0xA4, 0x64, 0xE1, 0x8B, 0xA4,
+ 0x30, 0xE3, 0x81, 0x85]);
+var charLengths = [0, 0, 1, 2, 2, 2, 3, 4, 4, 4, 5, 5];
+
+// Split the buffer into 3 segments
+// |----|------|-------|
+// 0 i j buffer.length
+// Scan through every possible 3 segment combination
+// and make sure that the string is always parsed.
+common.print('scanning ');
+for (var j = 2; j < buffer.length; j++) {
+ for (var i = 1; i < j; i++) {
+ var decoder = new StringDecoder('utf8');
+
+ var sum = decoder.write(buffer.slice(0, i));
+
+ // just check that we've received the right amount
+ // after the first write
+ assert.equal(charLengths[i], sum.length);
+
+ sum += decoder.write(buffer.slice(i, j));
+ sum += decoder.write(buffer.slice(j, buffer.length));
+ assert.equal(expected, sum);
+ common.print('.');
+ }
+}
+console.log(' crayon!');
+
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-javascript/node-string-decoder.git
More information about the Pkg-javascript-commits
mailing list