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

Unified Diff: runtime/vm/object.cc

Issue 11416054: Provide a code point iterator to the String class to simplify iteration. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: remove unintended code Created 8 years, 1 month 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
Index: runtime/vm/object.cc
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index 5dc09dd7e5c5e4afedd5e9abae89ad005309f24a..350347e3bf70a21791e7b4520aec22917d98ed96 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -9990,36 +9990,37 @@ bool String::Equals(const Instance& other) const {
}
-bool String::Equals(const char* str) const {
- ASSERT(str != NULL);
- intptr_t len = strlen(str);
+bool String::Equals(const char* utf8_array) const {
+ ASSERT(utf8_array != NULL);
+ intptr_t len = strlen(utf8_array);
for (intptr_t i = 0; i < this->Length(); ++i) {
- if (*str == '\0') {
+ if (*utf8_array == '\0') {
// Lengths don't match.
return false;
}
int32_t ch;
- intptr_t consumed = Utf8::Decode(reinterpret_cast<const uint8_t*>(str),
- len,
- &ch);
+ intptr_t consumed = Utf8::Decode(
+ reinterpret_cast<const uint8_t*>(utf8_array),
+ len,
+ &ch);
if (consumed == 0 || this->CharAt(i) != ch) {
return false;
}
- str += consumed;
+ utf8_array += consumed;
len -= consumed;
}
- return *str == '\0';
+ return *utf8_array == '\0';
}
-bool String::Equals(const uint8_t* characters, intptr_t len) const {
+bool String::Equals(const uint8_t* latin1_array, intptr_t len) const {
if (len != this->Length()) {
// Lengths don't match.
return false;
}
for (intptr_t i = 0; i < len; i++) {
- if (this->CharAt(i) != characters[i]) {
+ if (this->CharAt(i) != latin1_array[i]) {
return false;
}
}
@@ -10027,14 +10028,14 @@ bool String::Equals(const uint8_t* characters, intptr_t len) const {
}
-bool String::Equals(const uint16_t* characters, intptr_t len) const {
+bool String::Equals(const uint16_t* utf16_array, intptr_t len) const {
if (len != this->Length()) {
// Lengths don't match.
return false;
}
for (intptr_t i = 0; i < len; i++) {
- if (this->CharAt(i) != characters[i]) {
+ if (this->CharAt(i) != utf16_array[i]) {
return false;
}
}
@@ -10042,16 +10043,17 @@ bool String::Equals(const uint16_t* characters, intptr_t len) const {
}
-bool String::Equals(const uint32_t* characters, intptr_t len) const {
- if (len != this->Length()) {
- // Lengths don't match.
- return false;
- }
-
- for (intptr_t i = 0; i < len; i++) {
- if (this->CharAt(i) != static_cast<int32_t>(characters[i])) {
+bool String::Equals(const uint32_t* utf32_array, intptr_t len) const {
+ CodePointIterator it(*this);
+ intptr_t i = 0;
+ while (it.Next()) {
+ if (it.Current() != static_cast<int32_t>(utf32_array[i])) {
return false;
}
+ ++i;
+ }
+ if (i != len) {
+ return false;
}
return true;
}
@@ -10512,10 +10514,9 @@ RawString* String::Transform(int32_t (*mapping)(int32_t ch),
ASSERT(!str.IsNull());
bool has_mapping = false;
int32_t dst_max = 0;
- intptr_t len = str.Length();
- // TODO(cshapiro): assume a transform is required, rollback if not.
- for (intptr_t i = 0; i < len; ++i) {
- int32_t src = str.CharAt(i);
+ CodePointIterator it(str);
+ while (it.Next()) {
+ int32_t src = it.Current();
int32_t dst = mapping(src);
if (src != dst) {
has_mapping = true;
@@ -10545,6 +10546,46 @@ RawString* String::ToLowerCase(const String& str, Heap::Space space) {
}
+int32_t String::CodePointIterator::Current() {
+ ASSERT(index_ >= 0);
+ ASSERT(index_ < str_.Length());
+ int32_t ch = str_.CharAt(index_);
+ if (Utf16::IsLeadSurrogate(ch) && (index_ != (str_.Length() - 1))) {
siva 2012/11/19 18:25:29 Shouldn't this be (index_ < (str_.Length() - 1))
cshapiro 2012/11/19 18:55:11 Removed in the re-upload.
+ ASSERT(str_.IsTwoByteString());
+ int32_t ch2 = str_.CharAt(index_ + 1);
+ if (Utf16::IsTrailSurrogate(ch2)) {
+ ch = Utf16::Decode(ch, ch2);
+ }
+ }
+ return ch;
+}
+
+
+bool String::CodePointIterator::Next() {
+ ASSERT(index_ >= -1);
+ ASSERT(index_ < str_.Length());
+ if (index_ == (str_.Length() - 1)) {
siva 2012/11/19 18:25:29 Why not just make this if (index_ >= (str_.Length(
cshapiro 2012/11/19 18:55:11 I am not sure what this simplifies. Having the in
+ return false;
+ }
+ ++index_;
+ int32_t ch2 = str_.CharAt(index_);
+ if (Utf16::IsTrailSurrogate(ch2)) {
+ ASSERT(str_.IsTwoByteString());
+ if (index_ != 0) {
+ int32_t ch = str_.CharAt(index_ - 1);
+ if (Utf16::IsLeadSurrogate(ch)) {
+ if (index_ == (str_.Length() - 1)) {
+ --index_;
+ return false;
+ }
+ ++index_;
+ }
siva 2012/11/19 18:25:29 If you structure the code as discussed offline it
+ }
+ }
+ return true;
+}
+
+
RawOneByteString* OneByteString::EscapeSpecialCharacters(const String& str,
bool raw_str) {
intptr_t len = str.Length();
@@ -10829,7 +10870,7 @@ RawTwoByteString* TwoByteString::New(intptr_t utf16_len,
for (intptr_t i = 0; i < array_len; ++i) {
if (utf32_array[i] > 0xffff) {
ASSERT(j < (utf16_len - 1));
- Utf8::ConvertUTF32ToUTF16(utf32_array[i], CharAddr(result, j));
+ Utf16::Encode(utf32_array[i], CharAddr(result, j));
j += 2;
} else {
ASSERT(j < utf16_len);
@@ -10887,10 +10928,19 @@ RawTwoByteString* TwoByteString::Transform(int32_t (*mapping)(int32_t ch),
ASSERT(!str.IsNull());
intptr_t len = str.Length();
const String& result = String::Handle(TwoByteString::New(len, space));
- for (intptr_t i = 0; i < len; ++i) {
- int32_t ch = mapping(str.CharAt(i));
- ASSERT(ch >= 0 && ch <= 0xFFFF);
- *CharAddr(result, i) = ch;
+ String::CodePointIterator it(str);
+ intptr_t i = 0;
+ while (it.Next()) {
+ int32_t src = it.Current();
+ int32_t dst = mapping(src);
+ ASSERT(dst >= 0 && dst <= 0x10FFFF);
+ if (dst <= 0xFFFF) {
+ *CharAddr(result, i) = dst;
+ i += 1;
+ } else {
+ Utf16::Encode(dst, CharAddr(result, i));
+ i += 2;
+ }
}
return TwoByteString::raw(result);
}
« no previous file with comments | « runtime/vm/object.h ('k') | runtime/vm/object_test.cc » ('j') | runtime/vm/unicode.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698