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

Unified Diff: src/unicode.cc

Issue 2314663002: Rework scanner-character-streams. (Closed)
Patch Set: Marja's feedback, round 1. 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
« src/unicode.h ('K') | « 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..9b2b0a460c43c07f74529fc2667878a29a02aeba 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,55 @@ uchar Utf8::CalculateValue(const byte* str, size_t max_length, size_t* cursor) {
0x03C82080;
}
+uchar Utf8::ValueOfIncremental(byte next, Utf8IncrementalBuffer& buffer) {
marja 2016/09/08 09:46:23 Much better now!
+ // 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;
« src/unicode.h ('K') | « src/unicode.h ('k') | test/cctest/cctest.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698