Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/object.h" | 5 #include "vm/object.h" |
| 6 | 6 |
| 7 #include "include/dart_api.h" | 7 #include "include/dart_api.h" |
| 8 #include "platform/assert.h" | 8 #include "platform/assert.h" |
| 9 #include "vm/assembler.h" | 9 #include "vm/assembler.h" |
| 10 #include "vm/bigint_operations.h" | 10 #include "vm/bigint_operations.h" |
| (...skipping 9972 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 9983 | 9983 |
| 9984 const String& other_string = String::Cast(other); | 9984 const String& other_string = String::Cast(other); |
| 9985 if (this->HasHash() && other_string.HasHash() && | 9985 if (this->HasHash() && other_string.HasHash() && |
| 9986 (this->Hash() != other_string.Hash())) { | 9986 (this->Hash() != other_string.Hash())) { |
| 9987 return false; // Both sides have a hash code and it does not match. | 9987 return false; // Both sides have a hash code and it does not match. |
| 9988 } | 9988 } |
| 9989 return Equals(other_string, 0, other_string.Length()); | 9989 return Equals(other_string, 0, other_string.Length()); |
| 9990 } | 9990 } |
| 9991 | 9991 |
| 9992 | 9992 |
| 9993 bool String::Equals(const char* str) const { | 9993 bool String::Equals(const char* utf8_array) const { |
| 9994 ASSERT(str != NULL); | 9994 ASSERT(utf8_array != NULL); |
| 9995 intptr_t len = strlen(str); | 9995 intptr_t len = strlen(utf8_array); |
| 9996 for (intptr_t i = 0; i < this->Length(); ++i) { | 9996 for (intptr_t i = 0; i < this->Length(); ++i) { |
| 9997 if (*str == '\0') { | 9997 if (*utf8_array == '\0') { |
| 9998 // Lengths don't match. | 9998 // Lengths don't match. |
| 9999 return false; | 9999 return false; |
| 10000 } | 10000 } |
| 10001 int32_t ch; | 10001 int32_t ch; |
| 10002 intptr_t consumed = Utf8::Decode(reinterpret_cast<const uint8_t*>(str), | 10002 intptr_t consumed = Utf8::Decode( |
| 10003 len, | 10003 reinterpret_cast<const uint8_t*>(utf8_array), |
| 10004 &ch); | 10004 len, |
| 10005 &ch); | |
| 10005 if (consumed == 0 || this->CharAt(i) != ch) { | 10006 if (consumed == 0 || this->CharAt(i) != ch) { |
| 10006 return false; | 10007 return false; |
| 10007 } | 10008 } |
| 10008 str += consumed; | 10009 utf8_array += consumed; |
| 10009 len -= consumed; | 10010 len -= consumed; |
| 10010 } | 10011 } |
| 10011 return *str == '\0'; | 10012 return *utf8_array == '\0'; |
| 10012 } | 10013 } |
| 10013 | 10014 |
| 10014 | 10015 |
| 10015 bool String::Equals(const uint8_t* characters, intptr_t len) const { | 10016 bool String::Equals(const uint8_t* latin1_array, intptr_t len) const { |
| 10016 if (len != this->Length()) { | 10017 if (len != this->Length()) { |
| 10017 // Lengths don't match. | 10018 // Lengths don't match. |
| 10018 return false; | 10019 return false; |
| 10019 } | 10020 } |
| 10020 | 10021 |
| 10021 for (intptr_t i = 0; i < len; i++) { | 10022 for (intptr_t i = 0; i < len; i++) { |
| 10022 if (this->CharAt(i) != characters[i]) { | 10023 if (this->CharAt(i) != latin1_array[i]) { |
| 10023 return false; | 10024 return false; |
| 10024 } | 10025 } |
| 10025 } | 10026 } |
| 10026 return true; | 10027 return true; |
| 10027 } | 10028 } |
| 10028 | 10029 |
| 10029 | 10030 |
| 10030 bool String::Equals(const uint16_t* characters, intptr_t len) const { | 10031 bool String::Equals(const uint16_t* utf16_array, intptr_t len) const { |
| 10031 if (len != this->Length()) { | 10032 if (len != this->Length()) { |
| 10032 // Lengths don't match. | 10033 // Lengths don't match. |
| 10033 return false; | 10034 return false; |
| 10034 } | 10035 } |
| 10035 | 10036 |
| 10036 for (intptr_t i = 0; i < len; i++) { | 10037 for (intptr_t i = 0; i < len; i++) { |
| 10037 if (this->CharAt(i) != characters[i]) { | 10038 if (this->CharAt(i) != utf16_array[i]) { |
| 10038 return false; | 10039 return false; |
| 10039 } | 10040 } |
| 10040 } | 10041 } |
| 10041 return true; | 10042 return true; |
| 10042 } | 10043 } |
| 10043 | 10044 |
| 10044 | 10045 |
| 10045 bool String::Equals(const uint32_t* characters, intptr_t len) const { | 10046 bool String::Equals(const uint32_t* utf32_array, intptr_t len) const { |
| 10046 if (len != this->Length()) { | 10047 CodePointIterator it(*this); |
| 10047 // Lengths don't match. | 10048 intptr_t i = 0; |
| 10048 return false; | 10049 while (it.Next()) { |
| 10049 } | 10050 if (it.Current() != static_cast<int32_t>(utf32_array[i])) { |
| 10050 | |
| 10051 for (intptr_t i = 0; i < len; i++) { | |
| 10052 if (this->CharAt(i) != static_cast<int32_t>(characters[i])) { | |
| 10053 return false; | 10051 return false; |
| 10054 } | 10052 } |
| 10053 ++i; | |
| 10054 } | |
| 10055 if (i != len) { | |
| 10056 return false; | |
| 10055 } | 10057 } |
| 10056 return true; | 10058 return true; |
| 10057 } | 10059 } |
| 10058 | 10060 |
| 10059 | 10061 |
| 10060 intptr_t String::CompareTo(const String& other) const { | 10062 intptr_t String::CompareTo(const String& other) const { |
| 10061 const intptr_t this_len = this->Length(); | 10063 const intptr_t this_len = this->Length(); |
| 10062 const intptr_t other_len = other.IsNull() ? 0 : other.Length(); | 10064 const intptr_t other_len = other.IsNull() ? 0 : other.Length(); |
| 10063 const intptr_t len = (this_len < other_len) ? this_len : other_len; | 10065 const intptr_t len = (this_len < other_len) ? this_len : other_len; |
| 10064 for (intptr_t i = 0; i < len; i++) { | 10066 for (intptr_t i = 0; i < len; i++) { |
| (...skipping 440 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 10505 return this->raw(); | 10507 return this->raw(); |
| 10506 } | 10508 } |
| 10507 | 10509 |
| 10508 | 10510 |
| 10509 RawString* String::Transform(int32_t (*mapping)(int32_t ch), | 10511 RawString* String::Transform(int32_t (*mapping)(int32_t ch), |
| 10510 const String& str, | 10512 const String& str, |
| 10511 Heap::Space space) { | 10513 Heap::Space space) { |
| 10512 ASSERT(!str.IsNull()); | 10514 ASSERT(!str.IsNull()); |
| 10513 bool has_mapping = false; | 10515 bool has_mapping = false; |
| 10514 int32_t dst_max = 0; | 10516 int32_t dst_max = 0; |
| 10515 intptr_t len = str.Length(); | 10517 CodePointIterator it(str); |
| 10516 // TODO(cshapiro): assume a transform is required, rollback if not. | 10518 while (it.Next()) { |
| 10517 for (intptr_t i = 0; i < len; ++i) { | 10519 int32_t src = it.Current(); |
| 10518 int32_t src = str.CharAt(i); | |
| 10519 int32_t dst = mapping(src); | 10520 int32_t dst = mapping(src); |
| 10520 if (src != dst) { | 10521 if (src != dst) { |
| 10521 has_mapping = true; | 10522 has_mapping = true; |
| 10522 } | 10523 } |
| 10523 dst_max = Utils::Maximum(dst_max, dst); | 10524 dst_max = Utils::Maximum(dst_max, dst); |
| 10524 } | 10525 } |
| 10525 if (!has_mapping) { | 10526 if (!has_mapping) { |
| 10526 return str.raw(); | 10527 return str.raw(); |
| 10527 } | 10528 } |
| 10528 if (dst_max <= 0xFF) { | 10529 if (dst_max <= 0xFF) { |
| 10529 return OneByteString::Transform(mapping, str, space); | 10530 return OneByteString::Transform(mapping, str, space); |
| 10530 } | 10531 } |
| 10531 ASSERT(dst_max > 0xFF); | 10532 ASSERT(dst_max > 0xFF); |
| 10532 return TwoByteString::Transform(mapping, str, space); | 10533 return TwoByteString::Transform(mapping, str, space); |
| 10533 } | 10534 } |
| 10534 | 10535 |
| 10535 | 10536 |
| 10536 RawString* String::ToUpperCase(const String& str, Heap::Space space) { | 10537 RawString* String::ToUpperCase(const String& str, Heap::Space space) { |
| 10537 // TODO(cshapiro): create a fast-path for OneByteString instances. | 10538 // TODO(cshapiro): create a fast-path for OneByteString instances. |
| 10538 return Transform(CaseMapping::ToUpper, str, space); | 10539 return Transform(CaseMapping::ToUpper, str, space); |
| 10539 } | 10540 } |
| 10540 | 10541 |
| 10541 | 10542 |
| 10542 RawString* String::ToLowerCase(const String& str, Heap::Space space) { | 10543 RawString* String::ToLowerCase(const String& str, Heap::Space space) { |
| 10543 // TODO(cshapiro): create a fast-path for OneByteString instances. | 10544 // TODO(cshapiro): create a fast-path for OneByteString instances. |
| 10544 return Transform(CaseMapping::ToLower, str, space); | 10545 return Transform(CaseMapping::ToLower, str, space); |
| 10545 } | 10546 } |
| 10546 | 10547 |
| 10547 | 10548 |
| 10549 bool String::CodePointIterator::Next() { | |
| 10550 ASSERT(index_ >= -1); | |
| 10551 ASSERT(index_ < str_.Length()); | |
| 10552 int d = (ch_ <= 0xFFFF) ? 1 : 2; | |
|
siva
2012/11/19 19:29:54
(ch_ <= Utf16::kMaxBmpCodePoint)
cshapiro
2012/11/19 19:47:59
I'll fix that before submitting.
I think we shoul
| |
| 10553 if (index_ == (str_.Length() - d)) { | |
| 10554 return false; | |
| 10555 } | |
| 10556 index_ += d; | |
| 10557 ch_ = str_.CharAt(index_); | |
| 10558 if (Utf16::IsLeadSurrogate(ch_) && (index_ != (str_.Length() - 1))) { | |
| 10559 int32_t ch2 = str_.CharAt(index_ + 1); | |
| 10560 if (Utf16::IsTrailSurrogate(ch2)) { | |
| 10561 ch_ = Utf16::Decode(ch_, ch2); | |
| 10562 } | |
| 10563 } | |
| 10564 return true; | |
| 10565 } | |
| 10566 | |
| 10567 | |
| 10548 RawOneByteString* OneByteString::EscapeSpecialCharacters(const String& str, | 10568 RawOneByteString* OneByteString::EscapeSpecialCharacters(const String& str, |
| 10549 bool raw_str) { | 10569 bool raw_str) { |
| 10550 intptr_t len = str.Length(); | 10570 intptr_t len = str.Length(); |
| 10551 if (len > 0) { | 10571 if (len > 0) { |
| 10552 intptr_t num_escapes = 0; | 10572 intptr_t num_escapes = 0; |
| 10553 intptr_t index = 0; | 10573 intptr_t index = 0; |
| 10554 for (intptr_t i = 0; i < len; i++) { | 10574 for (intptr_t i = 0; i < len; i++) { |
| 10555 if (IsSpecialCharacter(*CharAddr(str, i)) || | 10575 if (IsSpecialCharacter(*CharAddr(str, i)) || |
| 10556 (!raw_str && (*CharAddr(str, i) == '\\'))) { | 10576 (!raw_str && (*CharAddr(str, i) == '\\'))) { |
| 10557 num_escapes += 1; | 10577 num_escapes += 1; |
| (...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 10822 intptr_t array_len, | 10842 intptr_t array_len, |
| 10823 Heap::Space space) { | 10843 Heap::Space space) { |
| 10824 ASSERT((array_len > 0) && (utf16_len >= array_len)); | 10844 ASSERT((array_len > 0) && (utf16_len >= array_len)); |
| 10825 const String& result = String::Handle(TwoByteString::New(utf16_len, space)); | 10845 const String& result = String::Handle(TwoByteString::New(utf16_len, space)); |
| 10826 { | 10846 { |
| 10827 NoGCScope no_gc; | 10847 NoGCScope no_gc; |
| 10828 intptr_t j = 0; | 10848 intptr_t j = 0; |
| 10829 for (intptr_t i = 0; i < array_len; ++i) { | 10849 for (intptr_t i = 0; i < array_len; ++i) { |
| 10830 if (utf32_array[i] > 0xffff) { | 10850 if (utf32_array[i] > 0xffff) { |
| 10831 ASSERT(j < (utf16_len - 1)); | 10851 ASSERT(j < (utf16_len - 1)); |
| 10832 Utf8::ConvertUTF32ToUTF16(utf32_array[i], CharAddr(result, j)); | 10852 Utf16::Encode(utf32_array[i], CharAddr(result, j)); |
| 10833 j += 2; | 10853 j += 2; |
| 10834 } else { | 10854 } else { |
| 10835 ASSERT(j < utf16_len); | 10855 ASSERT(j < utf16_len); |
| 10836 *CharAddr(result, j) = utf32_array[i]; | 10856 *CharAddr(result, j) = utf32_array[i]; |
| 10837 j += 1; | 10857 j += 1; |
| 10838 } | 10858 } |
| 10839 } | 10859 } |
| 10840 } | 10860 } |
| 10841 return TwoByteString::raw(result); | 10861 return TwoByteString::raw(result); |
| 10842 } | 10862 } |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 10880 return TwoByteString::raw(result); | 10900 return TwoByteString::raw(result); |
| 10881 } | 10901 } |
| 10882 | 10902 |
| 10883 | 10903 |
| 10884 RawTwoByteString* TwoByteString::Transform(int32_t (*mapping)(int32_t ch), | 10904 RawTwoByteString* TwoByteString::Transform(int32_t (*mapping)(int32_t ch), |
| 10885 const String& str, | 10905 const String& str, |
| 10886 Heap::Space space) { | 10906 Heap::Space space) { |
| 10887 ASSERT(!str.IsNull()); | 10907 ASSERT(!str.IsNull()); |
| 10888 intptr_t len = str.Length(); | 10908 intptr_t len = str.Length(); |
| 10889 const String& result = String::Handle(TwoByteString::New(len, space)); | 10909 const String& result = String::Handle(TwoByteString::New(len, space)); |
| 10890 for (intptr_t i = 0; i < len; ++i) { | 10910 String::CodePointIterator it(str); |
| 10891 int32_t ch = mapping(str.CharAt(i)); | 10911 intptr_t i = 0; |
| 10892 ASSERT(ch >= 0 && ch <= 0xFFFF); | 10912 while (it.Next()) { |
| 10893 *CharAddr(result, i) = ch; | 10913 int32_t src = it.Current(); |
| 10914 int32_t dst = mapping(src); | |
| 10915 ASSERT(dst >= 0 && dst <= 0x10FFFF); | |
| 10916 if (dst <= 0xFFFF) { | |
| 10917 *CharAddr(result, i) = dst; | |
| 10918 i += 1; | |
| 10919 } else { | |
| 10920 Utf16::Encode(dst, CharAddr(result, i)); | |
| 10921 i += 2; | |
| 10922 } | |
| 10894 } | 10923 } |
| 10895 return TwoByteString::raw(result); | 10924 return TwoByteString::raw(result); |
| 10896 } | 10925 } |
| 10897 | 10926 |
| 10898 | 10927 |
| 10899 RawExternalOneByteString* ExternalOneByteString::New( | 10928 RawExternalOneByteString* ExternalOneByteString::New( |
| 10900 const uint8_t* data, | 10929 const uint8_t* data, |
| 10901 intptr_t len, | 10930 intptr_t len, |
| 10902 void* peer, | 10931 void* peer, |
| 10903 Dart_PeerFinalizer callback, | 10932 Dart_PeerFinalizer callback, |
| (...skipping 1182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 12086 } | 12115 } |
| 12087 return result.raw(); | 12116 return result.raw(); |
| 12088 } | 12117 } |
| 12089 | 12118 |
| 12090 | 12119 |
| 12091 const char* WeakProperty::ToCString() const { | 12120 const char* WeakProperty::ToCString() const { |
| 12092 return "_WeakProperty"; | 12121 return "_WeakProperty"; |
| 12093 } | 12122 } |
| 12094 | 12123 |
| 12095 } // namespace dart | 12124 } // namespace dart |
| OLD | NEW |