OLD | NEW |
---|---|
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 4496 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4507 char* buffer, int capacity, bool skip_capacity_check) | 4507 char* buffer, int capacity, bool skip_capacity_check) |
4508 : early_termination_(false), | 4508 : early_termination_(false), |
4509 last_character_(unibrow::Utf16::kNoPreviousCharacter), | 4509 last_character_(unibrow::Utf16::kNoPreviousCharacter), |
4510 buffer_(buffer), | 4510 buffer_(buffer), |
4511 start_(buffer), | 4511 start_(buffer), |
4512 capacity_(capacity), | 4512 capacity_(capacity), |
4513 skip_capacity_check_(capacity == -1 || skip_capacity_check), | 4513 skip_capacity_check_(capacity == -1 || skip_capacity_check), |
4514 utf16_chars_read_(0) { | 4514 utf16_chars_read_(0) { |
4515 } | 4515 } |
4516 | 4516 |
4517 static int WriteEndCharacter(uint16_t character, | 4517 // WritePair writes the current UTF-16 code unit to the given buffer. The |
4518 int last_character, | 4518 // function will go back inside the buffer to combine surrogate pairs. |
4519 // @TODO use uint16_t for previous? | |
dcarney
2014/01/04 15:56:45
previous is an int because of some special values
haimuiba
2014/01/06 05:40:18
Makes sense. Thx.
| |
4520 static int WritePair(uint16_t current, int previous, char* buffer) { | |
4521 using namespace unibrow; | |
4522 int code_point = current; | |
4523 int written = 0; | |
4524 if (Utf16::IsSurrogatePair(previous, current)) { | |
4525 code_point = Utf16::CombineSurrogatePair(previous, current); | |
4526 buffer -= Utf8::kSizeOfUnmatchedSurrogate; | |
4527 written -= Utf8::kSizeOfUnmatchedSurrogate; | |
4528 } | |
4529 return written + Utf8::Encode(buffer, code_point, false); | |
dcarney
2014/01/04 15:56:45
having the length calculation here is too late. S
haimuiba
2014/01/06 05:40:18
Ok, I'll take a closer look.
| |
4530 } | |
4531 | |
4532 // @TODO use uint16_t for previous? | |
4533 static int WriteEndCharacter(uint16_t current, | |
4534 int previous, | |
4519 int remaining, | 4535 int remaining, |
4520 char* const buffer) { | 4536 char* const buffer) { |
4521 using namespace unibrow; | 4537 using namespace unibrow; |
4522 ASSERT(remaining > 0); | 4538 ASSERT(remaining > 0); |
4523 // We can't use a local buffer here because Encode needs to modify | 4539 // We can't use a local buffer here because WritePair needs to modify |
4524 // previous characters in the stream. We know, however, that | 4540 // previous characters in the stream. We know, however, that exactly one |
4525 // exactly one character will be advanced. | 4541 // character will be advanced. |
4526 if (Utf16::IsTrailSurrogate(character) && | 4542 if (Utf16::IsSurrogatePair(previous, current)) { |
4527 Utf16::IsLeadSurrogate(last_character)) { | 4543 int written = WritePair(current, previous, buffer); |
4528 int written = Utf8::Encode(buffer, character, last_character); | |
4529 ASSERT(written == 1); | 4544 ASSERT(written == 1); |
4530 return written; | 4545 return written; |
4531 } | 4546 } |
4532 // Use a scratch buffer to check the required characters. | 4547 // Use a scratch buffer to check the required characters. |
4533 char temp_buffer[Utf8::kMaxEncodedSize]; | 4548 char temp_buffer[Utf8::kMaxEncodedSize]; |
4534 // Can't encode using last_character as gcc has array bounds issues. | 4549 // Can't encode using last_character as gcc has array bounds issues. |
4535 int written = Utf8::Encode(temp_buffer, | 4550 int written = WritePair(current, Utf16::kNoPreviousCharacter, temp_buffer); |
4536 character, | |
4537 Utf16::kNoPreviousCharacter); | |
4538 // Won't fit. | 4551 // Won't fit. |
4539 if (written > remaining) return 0; | 4552 if (written > remaining) return 0; |
4540 // Copy over the character from temp_buffer. | 4553 // Copy over the character from temp_buffer. |
4541 for (int j = 0; j < written; j++) { | 4554 for (int j = 0; j < written; j++) { |
4542 buffer[j] = temp_buffer[j]; | 4555 buffer[j] = temp_buffer[j]; |
4543 } | 4556 } |
4544 return written; | 4557 return written; |
4545 } | 4558 } |
4546 | 4559 |
4547 template<typename Char> | 4560 template<typename Char> |
(...skipping 26 matching lines...) Expand all Loading... | |
4574 // Write the characters to the stream. | 4587 // Write the characters to the stream. |
4575 if (sizeof(Char) == 1) { | 4588 if (sizeof(Char) == 1) { |
4576 for (; i < fast_length; i++) { | 4589 for (; i < fast_length; i++) { |
4577 buffer += | 4590 buffer += |
4578 Utf8::EncodeOneByte(buffer, static_cast<uint8_t>(*chars++)); | 4591 Utf8::EncodeOneByte(buffer, static_cast<uint8_t>(*chars++)); |
4579 ASSERT(capacity_ == -1 || (buffer - start_) <= capacity_); | 4592 ASSERT(capacity_ == -1 || (buffer - start_) <= capacity_); |
4580 } | 4593 } |
4581 } else { | 4594 } else { |
4582 for (; i < fast_length; i++) { | 4595 for (; i < fast_length; i++) { |
4583 uint16_t character = *chars++; | 4596 uint16_t character = *chars++; |
4584 buffer += Utf8::Encode(buffer, character, last_character); | 4597 buffer += WritePair(character, last_character, buffer); |
4585 last_character = character; | 4598 last_character = character; |
4586 ASSERT(capacity_ == -1 || (buffer - start_) <= capacity_); | 4599 ASSERT(capacity_ == -1 || (buffer - start_) <= capacity_); |
4587 } | 4600 } |
4588 } | 4601 } |
4589 // Array is fully written. Exit. | 4602 // Array is fully written. Exit. |
4590 if (fast_length == length) { | 4603 if (fast_length == length) { |
4591 // Write state back out to object. | 4604 // Write state back out to object. |
4592 last_character_ = last_character; | 4605 last_character_ = last_character; |
4593 buffer_ = buffer; | 4606 buffer_ = buffer; |
4594 utf16_chars_read_ += length; | 4607 utf16_chars_read_ += length; |
(...skipping 2920 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
7515 Isolate* isolate = reinterpret_cast<Isolate*>(info.GetIsolate()); | 7528 Isolate* isolate = reinterpret_cast<Isolate*>(info.GetIsolate()); |
7516 Address callback_address = | 7529 Address callback_address = |
7517 reinterpret_cast<Address>(reinterpret_cast<intptr_t>(callback)); | 7530 reinterpret_cast<Address>(reinterpret_cast<intptr_t>(callback)); |
7518 VMState<EXTERNAL> state(isolate); | 7531 VMState<EXTERNAL> state(isolate); |
7519 ExternalCallbackScope call_scope(isolate, callback_address); | 7532 ExternalCallbackScope call_scope(isolate, callback_address); |
7520 callback(info); | 7533 callback(info); |
7521 } | 7534 } |
7522 | 7535 |
7523 | 7536 |
7524 } } // namespace v8::internal | 7537 } } // namespace v8::internal |
OLD | NEW |