Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(13)

Unified Diff: src/unicode.cc

Issue 2314663002: Rework scanner-character-streams. (Closed)
Patch Set: Marja's feedback. Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/unicode.h ('k') | test/cctest/cctest.gyp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/unicode.cc
diff --git a/src/unicode.cc b/src/unicode.cc
index db98be867579740b0e599c84c5b8fc164d834665..9fd39a75ebc6c506d6a42ebf99273d306f6221b6 100644
--- a/src/unicode.cc
+++ b/src/unicode.cc
@@ -190,8 +190,7 @@ static int LookupMapping(const int32_t* table,
}
}
-
-static inline size_t NonASCIISequenceLength(byte first) {
+static inline uint8_t NonASCIISequenceLength(byte first) {
// clang-format off
static const uint8_t lengths[256] = {
// The first 128 entries correspond to ASCII characters.
@@ -305,6 +304,57 @@ uchar Utf8::CalculateValue(const byte* str, size_t max_length, size_t* cursor) {
0x03C82080;
}
+uchar Utf8::ValueOfIncremental(byte next, Utf8IncrementalBuffer* buffer) {
+ DCHECK_NOT_NULL(buffer);
+
+ // The common case: 1-byte Utf8 (and no incomplete char in the buffer)
+ if (V8_LIKELY(next <= kMaxOneByteChar && *buffer == 0)) {
+ return static_cast<uchar>(next);
+ }
+
+ if (*buffer == 0) {
+ // We're at the start of a new character.
+ uint32_t kind = NonASCIISequenceLength(next);
+ if (kind >= 2 && kind <= 4) {
+ // Start of 2..4 byte character, and no buffer.
+
+ // The mask for the lower bits depends on the kind, and is
+ // 0x1F, 0x0F, 0x07 for kinds 2, 3, 4 respectively. We can get that
+ // with one shift.
+ uint8_t mask = 0x7f >> kind;
+
+ // Store the kind - 1 (i.e., remaining bytes) in the top byte, value
+ // in the bottom three.
+ *buffer = (kind - 1) << 24 | (next & mask);
+ return kIncomplete;
+ } else {
+ // No buffer, and not the start of a 1-byte char (handled at the
+ // beginning), and not the start of a 2..4 byte char? Bad char.
+ *buffer = 0;
+ return kBadChar;
+ }
+ } else {
+ // We're inside of a character, as described by buffer.
+ if (IsContinuationCharacter(next)) {
+ // How many bytes (excluding this one) do we still expect?
+ uint8_t count = (*buffer >> 24) - 1;
+ // Update the value.
+ uint32_t value = ((*buffer & 0xffffff) << 6) | (next & 0x3F);
+ if (count) {
+ *buffer = count << 24 | value;
+ return kIncomplete;
+ } else {
+ *buffer = 0;
+ return value;
+ }
+ } else {
+ // Within a character, but not a continuation character? Bad char.
+ *buffer = 0;
+ return kBadChar;
+ }
+ }
+}
+
bool Utf8::Validate(const byte* bytes, size_t length) {
size_t cursor = 0;
« no previous file with comments | « src/unicode.h ('k') | test/cctest/cctest.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698