summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFelix Geisendörfer <felix@debuggable.com>2014-05-13 17:36:40 +0200
committerTimothy J Fontaine <tjfontaine@gmail.com>2014-06-06 15:04:39 -0700
commitf59ec645cb84070a78c96c7144b0fac055d4d1c6 (patch)
tree4ffd7e2c083d25cc4d8d43ab7e93bc3976d5824b
parentd55702e73d20ca661f6ba4d06e95fbec431e2558 (diff)
downloadnode-f59ec645cb84070a78c96c7144b0fac055d4d1c6.tar.gz
string_decoder: Fix failures from new test cases
This patch simplifies the implementation of StringDecoder, fixes the failures from the new test cases, and also no longer relies on v8's WriteUtf8 function to encode individual surrogates.
-rw-r--r--lib/string_decoder.js40
1 files changed, 19 insertions, 21 deletions
diff --git a/lib/string_decoder.js b/lib/string_decoder.js
index 879e59064..56ae79d42 100644
--- a/lib/string_decoder.js
+++ b/lib/string_decoder.js
@@ -45,29 +45,29 @@ var StringDecoder = exports.StringDecoder = function(encoding) {
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) ?
+ var available = (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;
+ buffer.copy(this.charBuffer, this.charReceived, 0, available);
+ this.charReceived += available;
if (this.charReceived < this.charLength) {
// still not enough chars in this buffer? wait for more ...
return '';
}
+ // remove bytes belonging to the current character from the buffer
+ buffer = buffer.slice(available, buffer.length);
+
// 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
+ // CESU-8: 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;
@@ -77,34 +77,33 @@ StringDecoder.prototype.write = function(buffer) {
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);
+ if (buffer.length === 0) {
+ return charStr;
+ }
break;
}
- var lenIncomplete = this.detectIncompleteChar(buffer);
+ // determine and set charLength / charReceived
+ 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;
+ buffer.copy(this.charBuffer, 0, buffer.length - this.charReceived, end);
+ end -= this.charReceived;
}
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
+ // CESU-8: 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);
+ buffer.copy(this.charBuffer, 0, 0, size);
return charStr.substring(0, end);
}
@@ -142,7 +141,7 @@ StringDecoder.prototype.detectIncompleteChar = function(buffer) {
}
}
- return i;
+ this.charReceived = i;
};
function passThroughWrite(buffer) {
@@ -150,7 +149,6 @@ function passThroughWrite(buffer) {
}
function utf16DetectIncompleteChar(buffer) {
- var incomplete = this.charReceived = buffer.length % 2;
- this.charLength = incomplete ? 2 : 0;
- return incomplete;
+ this.charReceived = buffer.length % 2;
+ this.charLength = this.charReceived ? 2 : 0;
}