1
1
'use strict' ;
2
2
3
+ const isEncoding = Buffer . isEncoding ;
4
+
3
5
function assertEncoding ( encoding ) {
4
- if ( encoding && ! Buffer . isEncoding ( encoding ) ) {
6
+ if ( encoding && ! isEncoding ( encoding ) ) {
5
7
throw new Error ( 'Unknown encoding: ' + encoding ) ;
6
8
}
7
9
}
@@ -59,65 +61,83 @@ const StringDecoder = exports.StringDecoder = function(encoding) {
59
61
// replacement character. See https://codereview.chromium.org/121173009/ .
60
62
StringDecoder . prototype . write = function ( buffer ) {
61
63
var charStr = '' ;
64
+ var buflen = buffer . length ;
65
+ var charBuffer = this . charBuffer ;
66
+ var charLength = this . charLength ;
67
+ var charReceived = this . charReceived ;
68
+ var surrogateSize = this . surrogateSize ;
69
+ var encoding = this . encoding ;
62
70
// if our last write ended with an incomplete multibyte character
63
- while ( this . charLength ) {
71
+ while ( charLength ) {
64
72
// determine how many remaining bytes this buffer has to offer for this char
65
- var available = ( buffer . length >= this . charLength - this . charReceived ) ?
66
- this . charLength - this . charReceived :
67
- buffer . length ;
73
+ var diff = charLength - charReceived ;
74
+ var available = ( buflen >= diff ) ? diff : buflen ;
68
75
69
76
// add the new bytes to the char buffer
70
- buffer . copy ( this . charBuffer , this . charReceived , 0 , available ) ;
71
- this . charReceived += available ;
77
+ buffer . copy ( charBuffer , charReceived , 0 , available ) ;
78
+ charReceived += available ;
72
79
73
- if ( this . charReceived < this . charLength ) {
80
+ if ( charReceived < charLength ) {
74
81
// still not enough chars in this buffer? wait for more ...
82
+
83
+ this . charLength = charLength ;
84
+ this . charReceived = charReceived ;
85
+
75
86
return '' ;
76
87
}
77
88
78
89
// remove bytes belonging to the current character from the buffer
79
- buffer = buffer . slice ( available , buffer . length ) ;
90
+ buffer = buffer . slice ( available , buflen ) ;
91
+ buflen = buffer . length ;
80
92
81
93
// get the character that was split
82
- charStr = this . charBuffer . slice ( 0 , this . charLength ) . toString ( this . encoding ) ;
94
+ charStr = charBuffer . toString ( encoding , 0 , charLength ) ;
83
95
84
96
// CESU-8: lead surrogate (D800-DBFF) is also the incomplete character
85
97
var charCode = charStr . charCodeAt ( charStr . length - 1 ) ;
86
98
if ( charCode >= 0xD800 && charCode <= 0xDBFF ) {
87
- this . charLength += this . surrogateSize ;
99
+ charLength += surrogateSize ;
88
100
charStr = '' ;
89
101
continue ;
90
102
}
91
- this . charReceived = this . charLength = 0 ;
103
+ charReceived = charLength = 0 ;
92
104
93
105
// if there are no more bytes in this buffer, just emit our char
94
- if ( buffer . length === 0 ) {
106
+ if ( buflen === 0 ) {
107
+ this . charLength = charLength ;
108
+ this . charReceived = charReceived ;
109
+
95
110
return charStr ;
96
111
}
97
- break ;
98
112
}
99
113
100
114
// determine and set charLength / charReceived
101
- this . detectIncompleteChar ( buffer ) ;
115
+ if ( this . detectIncompleteChar ( buffer ) )
116
+ charLength = this . charLength ;
117
+ charReceived = this . charReceived ;
102
118
103
- var end = buffer . length ;
104
- if ( this . charLength ) {
119
+ var end = buflen ;
120
+ if ( charLength ) {
105
121
// buffer the incomplete character bytes we got
106
- buffer . copy ( this . charBuffer , 0 , buffer . length - this . charReceived , end ) ;
107
- end -= this . charReceived ;
122
+ buffer . copy ( charBuffer , 0 , buflen - charReceived , end ) ;
123
+ end -= charReceived ;
108
124
}
109
125
110
- charStr += buffer . toString ( this . encoding , 0 , end ) ;
126
+ this . charLength = charLength ;
127
+ charStr += buffer . toString ( encoding , 0 , end ) ;
111
128
112
129
var end = charStr . length - 1 ;
113
130
var charCode = charStr . charCodeAt ( end ) ;
114
131
// CESU-8: lead surrogate (D800-DBFF) is also the incomplete character
115
132
if ( charCode >= 0xD800 && charCode <= 0xDBFF ) {
116
- var size = this . surrogateSize ;
117
- this . charLength += size ;
118
- this . charReceived += size ;
119
- this . charBuffer . copy ( this . charBuffer , size , 0 , size ) ;
120
- buffer . copy ( this . charBuffer , 0 , 0 , size ) ;
133
+ charLength += surrogateSize ;
134
+ charReceived += surrogateSize ;
135
+ charBuffer . copy ( charBuffer , surrogateSize , 0 , surrogateSize ) ;
136
+ buffer . copy ( charBuffer , 0 , 0 , surrogateSize ) ;
137
+
138
+ this . charLength = charLength ;
139
+ this . charReceived = charReceived ;
140
+
121
141
return charStr . substring ( 0 , end ) ;
122
142
}
123
143
@@ -130,47 +150,56 @@ StringDecoder.prototype.write = function(buffer) {
130
150
// length that character, and sets this.charReceived to the number of bytes
131
151
// that are available for this character.
132
152
StringDecoder . prototype . detectIncompleteChar = function ( buffer ) {
153
+ var buflen = buffer . length ;
133
154
// determine how many bytes we have to check at the end of this buffer
134
- var i = ( buffer . length >= 3 ) ? 3 : buffer . length ;
155
+ var i = ( buflen >= 3 ) ? 3 : buflen ;
156
+ var newlen = false ;
135
157
136
158
// Figure out if one of the last i bytes of our buffer announces an
137
159
// incomplete char.
138
160
for ( ; i > 0 ; i -- ) {
139
- var c = buffer [ buffer . length - i ] ;
161
+ var c = buffer [ buflen - i ] ;
140
162
141
163
// See http://en.wikipedia.org/wiki/UTF-8#Description
142
164
143
165
// 110XXXXX
144
- if ( i == 1 && c >> 5 == 0x06 ) {
166
+ if ( i === 1 && c >> 5 = == 0x06 ) {
145
167
this . charLength = 2 ;
168
+ newlen = true ;
146
169
break ;
147
170
}
148
171
149
172
// 1110XXXX
150
- if ( i <= 2 && c >> 4 == 0x0E ) {
173
+ if ( i <= 2 && c >> 4 === 0x0E ) {
151
174
this . charLength = 3 ;
175
+ newlen = true ;
152
176
break ;
153
177
}
154
178
155
179
// 11110XXX
156
- if ( i <= 3 && c >> 3 == 0x1E ) {
180
+ if ( i <= 3 && c >> 3 === 0x1E ) {
157
181
this . charLength = 4 ;
182
+ newlen = true ;
158
183
break ;
159
184
}
160
185
}
186
+
161
187
this . charReceived = i ;
188
+
189
+ return newlen ;
162
190
} ;
163
191
164
192
StringDecoder . prototype . end = function ( buffer ) {
165
193
var res = '' ;
166
194
if ( buffer && buffer . length )
167
195
res = this . write ( buffer ) ;
168
196
169
- if ( this . charReceived ) {
170
- var cr = this . charReceived ;
197
+ var charReceived = this . charReceived ;
198
+ if ( charReceived ) {
199
+ var cr = charReceived ;
171
200
var buf = this . charBuffer ;
172
201
var enc = this . encoding ;
173
- res += buf . slice ( 0 , cr ) . toString ( enc ) ;
202
+ res += buf . toString ( enc , 0 , cr ) ;
174
203
}
175
204
176
205
return res ;
@@ -181,11 +210,13 @@ function passThroughWrite(buffer) {
181
210
}
182
211
183
212
function utf16DetectIncompleteChar ( buffer ) {
184
- this . charReceived = buffer . length % 2 ;
185
- this . charLength = this . charReceived ? 2 : 0 ;
213
+ var charReceived = this . charReceived = buffer . length % 2 ;
214
+ this . charLength = charReceived ? 2 : 0 ;
215
+ return true ;
186
216
}
187
217
188
218
function base64DetectIncompleteChar ( buffer ) {
189
- this . charReceived = buffer . length % 3 ;
190
- this . charLength = this . charReceived ? 3 : 0 ;
219
+ var charReceived = this . charReceived = buffer . length % 3 ;
220
+ this . charLength = charReceived ? 3 : 0 ;
221
+ return true ;
191
222
}
0 commit comments