@@ -203,40 +203,34 @@ static size_t keep_buflen_in_range(size_t len) { |
203 | 203 | return len; |
204 | 204 | } |
205 | 205 |
|
206 | | -size_t StringBytes::WriteUCS2( |
207 | | - Isolate* isolate, char* buf, size_t buflen, Local<String> str, int flags) { |
| 206 | +size_t StringBytes::WriteUCS2(Isolate* isolate, |
| 207 | + char* buf, |
| 208 | + size_t buflen, |
| 209 | + Local<String> str) { |
208 | 210 | uint16_t* const dst = reinterpret_cast<uint16_t*>(buf); |
209 | 211 |
|
210 | | - size_t max_chars = buflen / sizeof(*dst); |
211 | | - if (max_chars == 0) { |
| 212 | + const size_t max_chars = buflen / sizeof(*dst); |
| 213 | + const size_t nchars = std::min(max_chars, static_cast<size_t>(str->Length())); |
| 214 | + if (nchars == 0) { |
212 | 215 | return 0; |
213 | 216 | } |
214 | 217 |
|
215 | 218 | uint16_t* const aligned_dst = nbytes::AlignUp(dst, sizeof(*dst)); |
216 | | - size_t nchars; |
| 219 | + CHECK_EQ(reinterpret_cast<uintptr_t>(aligned_dst) % sizeof(*dst), 0); |
217 | 220 | if (aligned_dst == dst) { |
218 | | - nchars = str->Write(isolate, dst, 0, max_chars, flags); |
219 | | - return nchars * sizeof(*dst); |
220 | | - } |
| 221 | + str->WriteV2(isolate, 0, nchars, dst); |
| 222 | + } else { |
| 223 | + // Write all but the last char. |
| 224 | + str->WriteV2(isolate, 0, nchars - 1, aligned_dst); |
221 | 225 |
|
222 | | - CHECK_EQ(reinterpret_cast<uintptr_t>(aligned_dst) % sizeof(*dst), 0); |
| 226 | + // Shift everything to unaligned-left. |
| 227 | + memmove(dst, aligned_dst, (nchars - 1) * sizeof(*dst)); |
223 | 228 |
|
224 | | - // Write all but the last char |
225 | | - max_chars = std::min(max_chars, static_cast<size_t>(str->Length())); |
226 | | - if (max_chars == 0) { |
227 | | - return 0; |
| 229 | + // One more char to be written. |
| 230 | + uint16_t last; |
| 231 | + str->WriteV2(isolate, nchars - 1, 1, &last); |
| 232 | + memcpy(dst + nchars - 1, &last, sizeof(last)); |
228 | 233 | } |
229 | | - nchars = str->Write(isolate, aligned_dst, 0, max_chars - 1, flags); |
230 | | - CHECK_EQ(nchars, max_chars - 1); |
231 | | - |
232 | | - // Shift everything to unaligned-left |
233 | | - memmove(dst, aligned_dst, nchars * sizeof(*dst)); |
234 | | - |
235 | | - // One more char to be written |
236 | | - uint16_t last; |
237 | | - CHECK_EQ(str->Write(isolate, &last, nchars, 1, flags), 1); |
238 | | - memcpy(buf + nchars * sizeof(*dst), &last, sizeof(last)); |
239 | | - nchars++; |
240 | 234 |
|
241 | 235 | return nchars * sizeof(*dst); |
242 | 236 | } |
@@ -253,10 +247,6 @@ size_t StringBytes::Write(Isolate* isolate, |
253 | 247 | Local<String> str = val.As<String>(); |
254 | 248 | String::ValueView input_view(isolate, str); |
255 | 249 |
|
256 | | - int flags = String::HINT_MANY_WRITES_EXPECTED | |
257 | | - String::NO_NULL_TERMINATION | |
258 | | - String::REPLACE_INVALID_UTF8; |
259 | | - |
260 | 250 | switch (encoding) { |
261 | 251 | case ASCII: |
262 | 252 | case LATIN1: |
@@ -265,6 +255,9 @@ size_t StringBytes::Write(Isolate* isolate, |
265 | 255 | memcpy(buf, input_view.data8(), nbytes); |
266 | 256 | } else { |
267 | 257 | uint8_t* const dst = reinterpret_cast<uint8_t*>(buf); |
| 258 | + const int flags = String::HINT_MANY_WRITES_EXPECTED | |
| 259 | + String::NO_NULL_TERMINATION | |
| 260 | + String::REPLACE_INVALID_UTF8; |
268 | 261 | nbytes = str->WriteOneByte(isolate, dst, 0, buflen, flags); |
269 | 262 | } |
270 | 263 | break; |
@@ -276,7 +269,7 @@ size_t StringBytes::Write(Isolate* isolate, |
276 | 269 | break; |
277 | 270 |
|
278 | 271 | case UCS2: { |
279 | | - nbytes = WriteUCS2(isolate, buf, buflen, str, flags); |
| 272 | + nbytes = WriteUCS2(isolate, buf, buflen, str); |
280 | 273 |
|
281 | 274 | // Node's "ucs2" encoding wants LE character data stored in |
282 | 275 | // the Buffer, so we need to reorder on BE platforms. See |
|