mirror of https://github.com/svaarala/duktape.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
340 lines
7.3 KiB
340 lines
7.3 KiB
10 years ago
|
/*
|
||
|
* Node.js Buffer toString()
|
||
|
*/
|
||
|
|
||
|
/*@include util-nodejs-buffer.js@*/
|
||
|
|
||
|
/*===
|
||
|
node.js Buffer toString() test
|
||
|
function
|
||
|
false
|
||
|
true
|
||
|
"ABC"
|
||
|
"ABC"
|
||
|
"ABC"
|
||
|
"DEFG"
|
||
|
"EFG"
|
||
|
"E"
|
||
|
"<U+CAFE>A"
|
||
|
"<U+D800><U+DFFF>"
|
||
|
"<Error>ABC"
|
||
|
"ABB<Error>"
|
||
|
"DEFG"
|
||
|
NONE NONE "DEFG"
|
||
|
NONE undefined "DEFG"
|
||
|
NONE null "DEFG"
|
||
|
NONE true "DEFG"
|
||
|
NONE false "DEFG"
|
||
|
NONE [object Object] "DEFG"
|
||
|
NONE [object Object] "DEFG"
|
||
|
NONE -1 "DEFG"
|
||
|
NONE 0 "DEFG"
|
||
|
NONE 1 "DEFG"
|
||
|
NONE 2 "DEFG"
|
||
|
NONE 3 "DEFG"
|
||
|
NONE 4 "DEFG"
|
||
|
NONE 5 "DEFG"
|
||
|
undefined NONE "DEFG"
|
||
|
undefined undefined "DEFG"
|
||
|
undefined null ""
|
||
|
undefined true "D"
|
||
|
undefined false ""
|
||
|
undefined [object Object] "D"
|
||
|
undefined [object Object] "DEF"
|
||
|
undefined -1 ""
|
||
|
undefined 0 ""
|
||
|
undefined 1 "D"
|
||
|
undefined 2 "DE"
|
||
|
undefined 3 "DEF"
|
||
|
undefined 4 "DEFG"
|
||
|
undefined 5 "DEFG"
|
||
|
null NONE "DEFG"
|
||
|
null undefined "DEFG"
|
||
|
null null ""
|
||
|
null true "D"
|
||
|
null false ""
|
||
|
null [object Object] "D"
|
||
|
null [object Object] "DEF"
|
||
|
null -1 ""
|
||
|
null 0 ""
|
||
|
null 1 "D"
|
||
|
null 2 "DE"
|
||
|
null 3 "DEF"
|
||
|
null 4 "DEFG"
|
||
|
null 5 "DEFG"
|
||
|
true NONE "EFG"
|
||
|
true undefined "EFG"
|
||
|
true null ""
|
||
|
true true ""
|
||
|
true false ""
|
||
|
true [object Object] ""
|
||
|
true [object Object] "EF"
|
||
|
true -1 ""
|
||
|
true 0 ""
|
||
|
true 1 ""
|
||
|
true 2 "E"
|
||
|
true 3 "EF"
|
||
|
true 4 "EFG"
|
||
|
true 5 "EFG"
|
||
|
false NONE "DEFG"
|
||
|
false undefined "DEFG"
|
||
|
false null ""
|
||
|
false true "D"
|
||
|
false false ""
|
||
|
false [object Object] "D"
|
||
|
false [object Object] "DEF"
|
||
|
false -1 ""
|
||
|
false 0 ""
|
||
|
false 1 "D"
|
||
|
false 2 "DE"
|
||
|
false 3 "DEF"
|
||
|
false 4 "DEFG"
|
||
|
false 5 "DEFG"
|
||
|
[object Object] NONE "EFG"
|
||
|
[object Object] undefined "EFG"
|
||
|
[object Object] null ""
|
||
|
[object Object] true ""
|
||
|
[object Object] false ""
|
||
|
[object Object] [object Object] ""
|
||
|
[object Object] [object Object] "EF"
|
||
|
[object Object] -1 ""
|
||
|
[object Object] 0 ""
|
||
|
[object Object] 1 ""
|
||
|
[object Object] 2 "E"
|
||
|
[object Object] 3 "EF"
|
||
|
[object Object] 4 "EFG"
|
||
|
[object Object] 5 "EFG"
|
||
|
[object Object] NONE "G"
|
||
|
[object Object] undefined "G"
|
||
|
[object Object] null ""
|
||
|
[object Object] true ""
|
||
|
[object Object] false ""
|
||
|
[object Object] [object Object] ""
|
||
|
[object Object] [object Object] ""
|
||
|
[object Object] -1 ""
|
||
|
[object Object] 0 ""
|
||
|
[object Object] 1 ""
|
||
|
[object Object] 2 ""
|
||
|
[object Object] 3 ""
|
||
|
[object Object] 4 "G"
|
||
|
[object Object] 5 "G"
|
||
|
-1 NONE "DEFG"
|
||
|
-1 undefined "DEFG"
|
||
|
-1 null ""
|
||
|
-1 true "D"
|
||
|
-1 false ""
|
||
|
-1 [object Object] "D"
|
||
|
-1 [object Object] "DEF"
|
||
|
-1 -1 ""
|
||
|
-1 0 ""
|
||
|
-1 1 "D"
|
||
|
-1 2 "DE"
|
||
|
-1 3 "DEF"
|
||
|
-1 4 "DEFG"
|
||
|
-1 5 "DEFG"
|
||
|
0 NONE "DEFG"
|
||
|
0 undefined "DEFG"
|
||
|
0 null ""
|
||
|
0 true "D"
|
||
|
0 false ""
|
||
|
0 [object Object] "D"
|
||
|
0 [object Object] "DEF"
|
||
|
0 -1 ""
|
||
|
0 0 ""
|
||
|
0 1 "D"
|
||
|
0 2 "DE"
|
||
|
0 3 "DEF"
|
||
|
0 4 "DEFG"
|
||
|
0 5 "DEFG"
|
||
|
1 NONE "EFG"
|
||
|
1 undefined "EFG"
|
||
|
1 null ""
|
||
|
1 true ""
|
||
|
1 false ""
|
||
|
1 [object Object] ""
|
||
|
1 [object Object] "EF"
|
||
|
1 -1 ""
|
||
|
1 0 ""
|
||
|
1 1 ""
|
||
|
1 2 "E"
|
||
|
1 3 "EF"
|
||
|
1 4 "EFG"
|
||
|
1 5 "EFG"
|
||
|
2 NONE "FG"
|
||
|
2 undefined "FG"
|
||
|
2 null ""
|
||
|
2 true ""
|
||
|
2 false ""
|
||
|
2 [object Object] ""
|
||
|
2 [object Object] "F"
|
||
|
2 -1 ""
|
||
|
2 0 ""
|
||
|
2 1 ""
|
||
|
2 2 ""
|
||
|
2 3 "F"
|
||
|
2 4 "FG"
|
||
|
2 5 "FG"
|
||
|
3 NONE "G"
|
||
|
3 undefined "G"
|
||
|
3 null ""
|
||
|
3 true ""
|
||
|
3 false ""
|
||
|
3 [object Object] ""
|
||
|
3 [object Object] ""
|
||
|
3 -1 ""
|
||
|
3 0 ""
|
||
|
3 1 ""
|
||
|
3 2 ""
|
||
|
3 3 ""
|
||
|
3 4 "G"
|
||
|
3 5 "G"
|
||
|
4 NONE ""
|
||
|
4 undefined ""
|
||
|
4 null ""
|
||
|
4 true ""
|
||
|
4 false ""
|
||
|
4 [object Object] ""
|
||
|
4 [object Object] ""
|
||
|
4 -1 ""
|
||
|
4 0 ""
|
||
|
4 1 ""
|
||
|
4 2 ""
|
||
|
4 3 ""
|
||
|
4 4 ""
|
||
|
4 5 ""
|
||
|
5 NONE ""
|
||
|
5 undefined ""
|
||
|
5 null ""
|
||
|
5 true ""
|
||
|
5 false ""
|
||
|
5 [object Object] ""
|
||
|
5 [object Object] ""
|
||
|
5 -1 ""
|
||
|
5 0 ""
|
||
|
5 1 ""
|
||
|
5 2 ""
|
||
|
5 3 ""
|
||
|
5 4 ""
|
||
|
5 5 ""
|
||
|
===*/
|
||
|
|
||
|
function nodejsBufferToStringTest() {
|
||
|
var b, s;
|
||
|
|
||
|
// Check inheritance; not inherited from Object.prototype
|
||
|
print(typeof Buffer.prototype.toString);
|
||
|
print(Buffer.prototype.toString === Object.prototype.valueOf);
|
||
|
print(Buffer.prototype.hasOwnProperty('toString'));
|
||
|
|
||
|
// buf.toString([encoding], [start], [end])
|
||
|
|
||
|
// Without arguments encoding defaults to UTF-8 and the entire
|
||
|
// buffer is converted to string. At least undefined and null
|
||
|
// are accepted as "not defined" for encoding.
|
||
|
b = new Buffer('ABC');
|
||
|
safePrint(b.toString());
|
||
|
safePrint(b.toString(undefined));
|
||
|
safePrint(b.toString(null));
|
||
|
|
||
|
// If the buffer is a slice of an underlying buffer, only that slice
|
||
|
// is string converted. Offsets are relative to the slice.
|
||
|
b = new Buffer('ABCDEFGH');
|
||
|
b = b.slice(3, 7); // DEFG
|
||
|
safePrint(b.toString());
|
||
|
safePrint(b.toString(null, 1));
|
||
|
safePrint(b.toString(null, 1, 2));
|
||
|
|
||
|
// When the buffer data is legal UTF-8 and the chosen encoding
|
||
|
// is UTF-8 (default), Duktape internal representation is correct
|
||
|
// as is. Here the 4-byte data is U+CAFE U+0041.
|
||
|
b = new Buffer(4);
|
||
|
b[0] = 0xec; b[1] = 0xab; b[2] = 0xbe; b[3] = 0x41;
|
||
|
safePrint(b.toString());
|
||
|
|
||
|
// When the buffer data is not legal UTF-8 Node.js behavior is
|
||
|
// interesting and a bit inconsistent with other API calls:
|
||
|
// CESU-8 encoded strings are accepted as is. Here U+D800 U+DFFF
|
||
|
// encoded as CESU-8 is ED A0 80 ED BF BF and the string that comes
|
||
|
// back is U+D800 U+DFFF with both Node.js and Duktape.
|
||
|
b = new Buffer(6);
|
||
|
b[0] = 0xed; b[1] = 0xa0; b[2] = 0x80;
|
||
|
b[3] = 0xed; b[4] = 0xbf; b[5] = 0xbf;
|
||
|
safePrint(b.toString());
|
||
|
|
||
|
// Here the buffer data is invalid UTF-8 and invalid CESU-8.
|
||
|
// Node.js replaces the offending character (0xff) with U+FFFD
|
||
|
// (replacement character). Duktape currently allows as is.
|
||
|
|
||
|
// XXX: current output is odd because charCodeAt() doesn't
|
||
|
// work well now for invalid strings.
|
||
|
|
||
|
b = new Buffer(4);
|
||
|
b[0] = 0xff; b[1] = 0x41; b[2] = 0x42; b[3] = 0x43;
|
||
|
safePrint(b.toString());
|
||
|
|
||
|
// Invalid continuation characters. Node.js seems to scan for
|
||
|
// the next valid starting byte and each offending byte causes
|
||
|
// a new U+FFFD to be emitted (here U+FFFD U+FFFD U+0042 U+FFFD).
|
||
|
// Duktape currently allows the bytes as is.
|
||
|
|
||
|
// XXX: current output is odd because charCodeAt() doesn't
|
||
|
// work well now for invalid strings.
|
||
|
|
||
|
b = new Buffer(4);
|
||
|
b[0] = 0xc1; b[1] = 0xc1; b[2] = 0x42; b[3] = 0xc1;
|
||
|
safePrint(b.toString());
|
||
|
|
||
|
// XXX: encoding test?
|
||
|
|
||
|
// Offsets, very lenient, something like:
|
||
|
// - Non-numbers coerce to 0 (no valueOf() etc consulted)
|
||
|
// - Negative starting point => empty result, regardless of 'end'
|
||
|
// - Valid starting point but 'end' out of bounds => clamp to end
|
||
|
// - Crossed indices => empty result
|
||
|
//
|
||
|
// Duktape behavior is a bit more lenient: everything is ToInteger()
|
||
|
// coerced, clamped to valid range, and crossed indices are allowed.
|
||
|
// Testcase expect string has been corrected for this.
|
||
|
//
|
||
|
// Offsets are relative to a slice (if buffer is a slice).
|
||
|
|
||
|
b = new Buffer('ABCDEFGH');
|
||
|
b = b.slice(3, 7); // DEFG
|
||
|
safePrint(b.toString());
|
||
|
|
||
|
var offsetList = [
|
||
|
'NONE',
|
||
|
undefined,
|
||
|
null,
|
||
|
true,
|
||
|
false,
|
||
|
{ valueOf: function () { return 1; } },
|
||
|
{ valueOf: function () { return 3; } },
|
||
|
-1, 0, 1, 2, 3, 4, 5
|
||
|
]
|
||
|
|
||
|
offsetList.forEach(function (start) {
|
||
|
offsetList.forEach(function (end) {
|
||
|
try {
|
||
|
if (start === 'NONE') {
|
||
|
s = b.toString('utf8');
|
||
|
} else if (end === 'NONE') {
|
||
|
s = b.toString('utf8', start);
|
||
|
} else {
|
||
|
s = b.toString('utf8', start, end);
|
||
|
}
|
||
|
print(start, end, safeEscape(s));
|
||
|
} catch (e) {
|
||
|
print(start, end, e.name);
|
||
|
}
|
||
|
});
|
||
|
});
|
||
|
}
|
||
|
|
||
|
try {
|
||
|
print('node.js Buffer toString() test');
|
||
|
nodejsBufferToStringTest();
|
||
|
} catch (e) {
|
||
|
print(e.stack || e);
|
||
|
}
|