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 2217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2228 const char* prefix, | 2228 const char* prefix, |
2229 intptr_t prefix_length, | 2229 intptr_t prefix_length, |
2230 const String& accessor_name) { | 2230 const String& accessor_name) { |
2231 intptr_t name_len = name.Length(); | 2231 intptr_t name_len = name.Length(); |
2232 intptr_t accessor_name_len = accessor_name.Length(); | 2232 intptr_t accessor_name_len = accessor_name.Length(); |
2233 | 2233 |
2234 if (name_len != (accessor_name_len + prefix_length)) { | 2234 if (name_len != (accessor_name_len + prefix_length)) { |
2235 return false; | 2235 return false; |
2236 } | 2236 } |
2237 for (intptr_t i = 0; i < prefix_length; i++) { | 2237 for (intptr_t i = 0; i < prefix_length; i++) { |
2238 if (name.CharAt(i) != prefix[i]) { | 2238 if (name.CharAt(i) != static_cast<int32_t>(prefix[i])) { |
2239 return false; | 2239 return false; |
2240 } | 2240 } |
2241 } | 2241 } |
2242 for (intptr_t i = 0, j = prefix_length; i < accessor_name_len; i++, j++) { | 2242 for (intptr_t i = 0, j = prefix_length; i < accessor_name_len; i++, j++) { |
2243 if (name.CharAt(j) != accessor_name.CharAt(i)) { | 2243 if (name.CharAt(j) != accessor_name.CharAt(i)) { |
2244 return false; | 2244 return false; |
2245 } | 2245 } |
2246 } | 2246 } |
2247 return true; | 2247 return true; |
2248 } | 2248 } |
(...skipping 6907 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9156 | 9156 |
9157 | 9157 |
9158 const char* Integer::ToCString() const { | 9158 const char* Integer::ToCString() const { |
9159 // Integer is an interface. No instances of Integer should exist. | 9159 // Integer is an interface. No instances of Integer should exist. |
9160 UNREACHABLE(); | 9160 UNREACHABLE(); |
9161 return "Integer"; | 9161 return "Integer"; |
9162 } | 9162 } |
9163 | 9163 |
9164 | 9164 |
9165 RawInteger* Integer::New(const String& str, Heap::Space space) { | 9165 RawInteger* Integer::New(const String& str, Heap::Space space) { |
9166 // We are not supposed to have integers represented as two byte or | 9166 // We are not supposed to have integers represented as two byte strings. |
9167 // four byte strings. | |
9168 ASSERT(str.IsOneByteString()); | 9167 ASSERT(str.IsOneByteString()); |
9169 int64_t value; | 9168 int64_t value; |
9170 if (!OS::StringToInt64(str.ToCString(), &value)) { | 9169 if (!OS::StringToInt64(str.ToCString(), &value)) { |
9171 const Bigint& big = Bigint::Handle(Bigint::New(str, space)); | 9170 const Bigint& big = Bigint::Handle(Bigint::New(str, space)); |
9172 ASSERT(!BigintOperations::FitsIntoSmi(big)); | 9171 ASSERT(!BigintOperations::FitsIntoSmi(big)); |
9173 ASSERT(!BigintOperations::FitsIntoMint(big)); | 9172 ASSERT(!BigintOperations::FitsIntoMint(big)); |
9174 return big.raw(); | 9173 return big.raw(); |
9175 } | 9174 } |
9176 return Integer::New(value, space); | 9175 return Integer::New(value, space); |
9177 } | 9176 } |
(...skipping 742 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9920 intptr_t String::Hash(const uint8_t* characters, intptr_t len) { | 9919 intptr_t String::Hash(const uint8_t* characters, intptr_t len) { |
9921 return HashImpl(characters, len); | 9920 return HashImpl(characters, len); |
9922 } | 9921 } |
9923 | 9922 |
9924 | 9923 |
9925 intptr_t String::Hash(const uint16_t* characters, intptr_t len) { | 9924 intptr_t String::Hash(const uint16_t* characters, intptr_t len) { |
9926 return HashImpl(characters, len); | 9925 return HashImpl(characters, len); |
9927 } | 9926 } |
9928 | 9927 |
9929 | 9928 |
9930 intptr_t String::Hash(const uint32_t* characters, intptr_t len) { | 9929 intptr_t String::Hash(const int32_t* characters, intptr_t len) { |
9931 return HashImpl(characters, len); | 9930 return HashImpl(characters, len); |
9932 } | 9931 } |
9933 | 9932 |
9934 | 9933 |
9935 int32_t String::CharAt(intptr_t index) const { | 9934 int32_t String::CharAt(intptr_t index) const { |
9936 intptr_t class_id = raw()->GetClassId(); | 9935 intptr_t class_id = raw()->GetClassId(); |
9937 ASSERT(RawObject::IsStringClassId(class_id)); | 9936 ASSERT(RawObject::IsStringClassId(class_id)); |
9938 NoGCScope no_gc; | 9937 NoGCScope no_gc; |
9939 if (class_id == kOneByteStringCid) { | 9938 if (class_id == kOneByteStringCid) { |
9940 return *OneByteString::CharAddr(*this, index); | 9939 return *OneByteString::CharAddr(*this, index); |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9995 intptr_t len = strlen(str); | 9994 intptr_t len = strlen(str); |
9996 for (intptr_t i = 0; i < this->Length(); ++i) { | 9995 for (intptr_t i = 0; i < this->Length(); ++i) { |
9997 if (*str == '\0') { | 9996 if (*str == '\0') { |
9998 // Lengths don't match. | 9997 // Lengths don't match. |
9999 return false; | 9998 return false; |
10000 } | 9999 } |
10001 int32_t ch; | 10000 int32_t ch; |
10002 intptr_t consumed = Utf8::Decode(reinterpret_cast<const uint8_t*>(str), | 10001 intptr_t consumed = Utf8::Decode(reinterpret_cast<const uint8_t*>(str), |
10003 len, | 10002 len, |
10004 &ch); | 10003 &ch); |
10005 if (consumed == 0 || this->CharAt(i) != ch) { | 10004 if (consumed == 0) return false; |
10006 return false; | 10005 |
| 10006 if (ch <= Utf16::kMaxCodeUnit) { |
| 10007 if (this->CharAt(i) != ch) return false; |
| 10008 } else { |
| 10009 if (Utf16::CodePointAt(*this, i) != ch) return false; |
| 10010 i++; |
10007 } | 10011 } |
10008 str += consumed; | 10012 str += consumed; |
10009 len -= consumed; | 10013 len -= consumed; |
10010 } | 10014 } |
10011 return *str == '\0'; | 10015 return *str == '\0'; |
10012 } | 10016 } |
10013 | 10017 |
10014 | 10018 |
10015 bool String::Equals(const uint8_t* characters, intptr_t len) const { | 10019 bool String::Equals(const uint8_t* characters, intptr_t len) const { |
10016 if (len != this->Length()) { | 10020 if (len != this->Length()) { |
(...skipping 18 matching lines...) Expand all Loading... |
10035 | 10039 |
10036 for (intptr_t i = 0; i < len; i++) { | 10040 for (intptr_t i = 0; i < len; i++) { |
10037 if (this->CharAt(i) != characters[i]) { | 10041 if (this->CharAt(i) != characters[i]) { |
10038 return false; | 10042 return false; |
10039 } | 10043 } |
10040 } | 10044 } |
10041 return true; | 10045 return true; |
10042 } | 10046 } |
10043 | 10047 |
10044 | 10048 |
10045 bool String::Equals(const uint32_t* characters, intptr_t len) const { | |
10046 if (len != this->Length()) { | |
10047 // Lengths don't match. | |
10048 return false; | |
10049 } | |
10050 | |
10051 for (intptr_t i = 0; i < len; i++) { | |
10052 if (this->CharAt(i) != static_cast<int32_t>(characters[i])) { | |
10053 return false; | |
10054 } | |
10055 } | |
10056 return true; | |
10057 } | |
10058 | |
10059 | |
10060 intptr_t String::CompareTo(const String& other) const { | 10049 intptr_t String::CompareTo(const String& other) const { |
10061 const intptr_t this_len = this->Length(); | 10050 const intptr_t this_len = this->Length(); |
10062 const intptr_t other_len = other.IsNull() ? 0 : other.Length(); | 10051 const intptr_t other_len = other.IsNull() ? 0 : other.Length(); |
10063 const intptr_t len = (this_len < other_len) ? this_len : other_len; | 10052 const intptr_t len = (this_len < other_len) ? this_len : other_len; |
| 10053 // UTF-16 has the high surrogate before the low surrogate so we can compare |
| 10054 // one code unit at a time for efficiency and still get the right ordering. |
10064 for (intptr_t i = 0; i < len; i++) { | 10055 for (intptr_t i = 0; i < len; i++) { |
10065 int32_t this_code_point = this->CharAt(i); | 10056 int32_t this_code_unit = this->CharAt(i); |
10066 int32_t other_code_point = other.CharAt(i); | 10057 int32_t other_code_unit = other.CharAt(i); |
10067 if (this_code_point < other_code_point) { | 10058 if (this_code_unit < other_code_unit) { |
10068 return -1; | 10059 return -1; |
10069 } | 10060 } |
10070 if (this_code_point > other_code_point) { | 10061 if (this_code_unit > other_code_unit) { |
10071 return 1; | 10062 return 1; |
10072 } | 10063 } |
10073 } | 10064 } |
10074 if (this_len < other_len) return -1; | 10065 if (this_len < other_len) return -1; |
10075 if (this_len > other_len) return 1; | 10066 if (this_len > other_len) return 1; |
10076 return 0; | 10067 return 0; |
10077 } | 10068 } |
10078 | 10069 |
10079 | 10070 |
10080 bool String::StartsWith(const String& other) const { | 10071 bool String::StartsWith(const String& other) const { |
(...skipping 23 matching lines...) Expand all Loading... |
10104 intptr_t array_len = strlen(str); | 10095 intptr_t array_len = strlen(str); |
10105 const uint8_t* utf8_array = reinterpret_cast<const uint8_t*>(str); | 10096 const uint8_t* utf8_array = reinterpret_cast<const uint8_t*>(str); |
10106 return String::New(utf8_array, array_len, space); | 10097 return String::New(utf8_array, array_len, space); |
10107 } | 10098 } |
10108 | 10099 |
10109 | 10100 |
10110 RawString* String::New(const uint8_t* utf8_array, | 10101 RawString* String::New(const uint8_t* utf8_array, |
10111 intptr_t array_len, | 10102 intptr_t array_len, |
10112 Heap::Space space) { | 10103 Heap::Space space) { |
10113 Utf8::Type type; | 10104 Utf8::Type type; |
10114 intptr_t len = Utf8::CodePointCount(utf8_array, array_len, &type); | 10105 intptr_t len = Utf8::CodeUnitCount(utf8_array, array_len, &type); |
10115 if (type == Utf8::kLatin1) { | 10106 if (type == Utf8::kLatin1) { |
10116 const String& strobj = String::Handle(OneByteString::New(len, space)); | 10107 const String& strobj = String::Handle(OneByteString::New(len, space)); |
10117 if (len > 0) { | 10108 if (len > 0) { |
10118 NoGCScope no_gc; | 10109 NoGCScope no_gc; |
10119 Utf8::DecodeToLatin1(utf8_array, array_len, | 10110 Utf8::DecodeToLatin1(utf8_array, array_len, |
10120 OneByteString::CharAddr(strobj, 0), len); | 10111 OneByteString::CharAddr(strobj, 0), len); |
10121 } | 10112 } |
10122 return strobj.raw(); | 10113 return strobj.raw(); |
10123 } | 10114 } |
10124 ASSERT((type == Utf8::kBMP) || (type == Utf8::kSMP)); | 10115 ASSERT((type == Utf8::kBMP) || (type == Utf8::kSMP)); |
(...skipping 15 matching lines...) Expand all Loading... |
10140 break; | 10131 break; |
10141 } | 10132 } |
10142 } | 10133 } |
10143 if (is_one_byte_string) { | 10134 if (is_one_byte_string) { |
10144 return OneByteString::New(utf16_array, array_len, space); | 10135 return OneByteString::New(utf16_array, array_len, space); |
10145 } | 10136 } |
10146 return TwoByteString::New(utf16_array, array_len, space); | 10137 return TwoByteString::New(utf16_array, array_len, space); |
10147 } | 10138 } |
10148 | 10139 |
10149 | 10140 |
10150 RawString* String::New(const uint32_t* utf32_array, | 10141 RawString* String::New(const int32_t* utf32_array, |
10151 intptr_t array_len, | 10142 intptr_t array_len, |
10152 Heap::Space space) { | 10143 Heap::Space space) { |
10153 bool is_one_byte_string = true; | 10144 bool is_one_byte_string = true; |
10154 intptr_t utf16_len = array_len; | 10145 intptr_t utf16_len = array_len; |
10155 for (intptr_t i = 0; i < array_len; ++i) { | 10146 for (intptr_t i = 0; i < array_len; ++i) { |
10156 if (utf32_array[i] > 0xFF) { | 10147 if (utf32_array[i] > 0xFF) { |
10157 is_one_byte_string = false; | 10148 is_one_byte_string = false; |
10158 } | 10149 } |
10159 if (utf32_array[i] > 0xFFFF) { | 10150 if (utf32_array[i] > 0xFFFF) { |
10160 utf16_len += 1; | 10151 utf16_len += 1; |
(...skipping 345 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10506 } | 10497 } |
10507 | 10498 |
10508 | 10499 |
10509 RawString* String::Transform(int32_t (*mapping)(int32_t ch), | 10500 RawString* String::Transform(int32_t (*mapping)(int32_t ch), |
10510 const String& str, | 10501 const String& str, |
10511 Heap::Space space) { | 10502 Heap::Space space) { |
10512 ASSERT(!str.IsNull()); | 10503 ASSERT(!str.IsNull()); |
10513 bool has_mapping = false; | 10504 bool has_mapping = false; |
10514 int32_t dst_max = 0; | 10505 int32_t dst_max = 0; |
10515 intptr_t len = str.Length(); | 10506 intptr_t len = str.Length(); |
| 10507 intptr_t out_len = 0; |
10516 // TODO(cshapiro): assume a transform is required, rollback if not. | 10508 // TODO(cshapiro): assume a transform is required, rollback if not. |
10517 for (intptr_t i = 0; i < len; ++i) { | 10509 intptr_t i = 0; |
| 10510 for (; i < len; ++i) { |
10518 int32_t src = str.CharAt(i); | 10511 int32_t src = str.CharAt(i); |
| 10512 if (Utf16::IsSurrogate(src)) break; |
10519 int32_t dst = mapping(src); | 10513 int32_t dst = mapping(src); |
10520 if (src != dst) { | 10514 if (src != dst) { |
10521 has_mapping = true; | 10515 has_mapping = true; |
10522 } | 10516 } |
10523 dst_max = Utils::Maximum(dst_max, dst); | 10517 dst_max = Utils::Maximum(dst_max, dst); |
| 10518 out_len += dst > Utf16::kMaxCodeUnit ? 2 : 1; |
| 10519 } |
| 10520 for (; i < len; ++i) { |
| 10521 int32_t src = Utf16::CodePointAt(str, i); |
| 10522 int32_t dst = mapping(src); |
| 10523 if (src != dst) { |
| 10524 has_mapping = true; |
| 10525 } |
| 10526 dst_max = Utils::Maximum(dst_max, dst); |
| 10527 out_len += dst > Utf16::kMaxCodeUnit ? 2 : 1; |
| 10528 if (src > Utf16::kMaxCodeUnit) ++i; |
10524 } | 10529 } |
10525 if (!has_mapping) { | 10530 if (!has_mapping) { |
10526 return str.raw(); | 10531 return str.raw(); |
10527 } | 10532 } |
10528 if (dst_max <= 0xFF) { | 10533 if (dst_max <= 0xFF) { |
10529 return OneByteString::Transform(mapping, str, space); | 10534 return OneByteString::Transform(mapping, str, out_len, space); |
10530 } | 10535 } |
10531 ASSERT(dst_max > 0xFF); | 10536 ASSERT(dst_max > 0xFF); |
10532 return TwoByteString::Transform(mapping, str, space); | 10537 return TwoByteString::Transform(mapping, str, out_len, space); |
10533 } | 10538 } |
10534 | 10539 |
10535 | 10540 |
10536 RawString* String::ToUpperCase(const String& str, Heap::Space space) { | 10541 RawString* String::ToUpperCase(const String& str, Heap::Space space) { |
10537 // TODO(cshapiro): create a fast-path for OneByteString instances. | 10542 // TODO(cshapiro): create a fast-path for OneByteString instances. |
10538 return Transform(CaseMapping::ToUpper, str, space); | 10543 return Transform(CaseMapping::ToUpper, str, space); |
10539 } | 10544 } |
10540 | 10545 |
10541 | 10546 |
10542 RawString* String::ToLowerCase(const String& str, Heap::Space space) { | 10547 RawString* String::ToLowerCase(const String& str, Heap::Space space) { |
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10676 Heap::Space space) { | 10681 Heap::Space space) { |
10677 const String& result =String::Handle(OneByteString::New(len, space)); | 10682 const String& result =String::Handle(OneByteString::New(len, space)); |
10678 for (intptr_t i = 0; i < len; ++i) { | 10683 for (intptr_t i = 0; i < len; ++i) { |
10679 ASSERT(characters[i] <= 0xFF); | 10684 ASSERT(characters[i] <= 0xFF); |
10680 *CharAddr(result, i) = characters[i]; | 10685 *CharAddr(result, i) = characters[i]; |
10681 } | 10686 } |
10682 return OneByteString::raw(result); | 10687 return OneByteString::raw(result); |
10683 } | 10688 } |
10684 | 10689 |
10685 | 10690 |
10686 RawOneByteString* OneByteString::New(const uint32_t* characters, | 10691 RawOneByteString* OneByteString::New(const int32_t* characters, |
10687 intptr_t len, | 10692 intptr_t len, |
10688 Heap::Space space) { | 10693 Heap::Space space) { |
10689 const String& result = String::Handle(OneByteString::New(len, space)); | 10694 const String& result = String::Handle(OneByteString::New(len, space)); |
10690 for (intptr_t i = 0; i < len; ++i) { | 10695 for (intptr_t i = 0; i < len; ++i) { |
10691 ASSERT(characters[i] <= 0xFF); | 10696 ASSERT(characters[i] <= 0xFF); |
10692 *CharAddr(result, i) = characters[i]; | 10697 *CharAddr(result, i) = characters[i]; |
10693 } | 10698 } |
10694 return OneByteString::raw(result); | 10699 return OneByteString::raw(result); |
10695 } | 10700 } |
10696 | 10701 |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10729 intptr_t str_len = str.Length(); | 10734 intptr_t str_len = str.Length(); |
10730 String::Copy(result, pos, str, 0, str_len); | 10735 String::Copy(result, pos, str, 0, str_len); |
10731 pos += str_len; | 10736 pos += str_len; |
10732 } | 10737 } |
10733 return OneByteString::raw(result); | 10738 return OneByteString::raw(result); |
10734 } | 10739 } |
10735 | 10740 |
10736 | 10741 |
10737 RawOneByteString* OneByteString::Transform(int32_t (*mapping)(int32_t ch), | 10742 RawOneByteString* OneByteString::Transform(int32_t (*mapping)(int32_t ch), |
10738 const String& str, | 10743 const String& str, |
| 10744 intptr_t out_length, |
10739 Heap::Space space) { | 10745 Heap::Space space) { |
10740 ASSERT(!str.IsNull()); | 10746 ASSERT(!str.IsNull()); |
10741 intptr_t len = str.Length(); | 10747 intptr_t len = str.Length(); |
10742 const String& result = String::Handle(OneByteString::New(len, space)); | 10748 const String& result = |
10743 for (intptr_t i = 0; i < len; ++i) { | 10749 String::Handle(OneByteString::New(out_length, space)); |
10744 int32_t ch = mapping(str.CharAt(i)); | 10750 for (intptr_t i = 0, j = 0; i < len; ++i, j++) { |
10745 ASSERT(ch >= 0 && ch <= 0xFF); | 10751 int32_t old_ch = str.CharAt(i); |
10746 *CharAddr(result, i) = ch; | 10752 if (old_ch > Utf16::kMaxCodeUnit) i++; |
| 10753 int32_t ch = mapping(old_ch); |
| 10754 ASSERT(ch <= 0xFF); |
| 10755 *CharAddr(result, j) = ch; |
10747 } | 10756 } |
10748 return OneByteString::raw(result); | 10757 return OneByteString::raw(result); |
10749 } | 10758 } |
10750 | 10759 |
10751 | 10760 |
10752 RawTwoByteString* TwoByteString::EscapeSpecialCharacters(const String& str, | 10761 RawTwoByteString* TwoByteString::EscapeSpecialCharacters(const String& str, |
10753 bool raw_str) { | 10762 bool raw_str) { |
10754 intptr_t len = str.Length(); | 10763 intptr_t len = str.Length(); |
10755 if (len > 0) { | 10764 if (len > 0) { |
10756 intptr_t num_escapes = 0; | 10765 intptr_t num_escapes = 0; |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10811 const String& result = String::Handle(TwoByteString::New(array_len, space)); | 10820 const String& result = String::Handle(TwoByteString::New(array_len, space)); |
10812 { | 10821 { |
10813 NoGCScope no_gc; | 10822 NoGCScope no_gc; |
10814 memmove(CharAddr(result, 0), utf16_array, (array_len * 2)); | 10823 memmove(CharAddr(result, 0), utf16_array, (array_len * 2)); |
10815 } | 10824 } |
10816 return TwoByteString::raw(result); | 10825 return TwoByteString::raw(result); |
10817 } | 10826 } |
10818 | 10827 |
10819 | 10828 |
10820 RawTwoByteString* TwoByteString::New(intptr_t utf16_len, | 10829 RawTwoByteString* TwoByteString::New(intptr_t utf16_len, |
10821 const uint32_t* utf32_array, | 10830 const int32_t* utf32_array, |
10822 intptr_t array_len, | 10831 intptr_t array_len, |
10823 Heap::Space space) { | 10832 Heap::Space space) { |
10824 ASSERT((array_len > 0) && (utf16_len >= array_len)); | 10833 ASSERT((array_len > 0) && (utf16_len >= array_len)); |
10825 const String& result = String::Handle(TwoByteString::New(utf16_len, space)); | 10834 const String& result = String::Handle(TwoByteString::New(utf16_len, space)); |
10826 { | 10835 { |
10827 NoGCScope no_gc; | 10836 NoGCScope no_gc; |
10828 intptr_t j = 0; | 10837 intptr_t j = 0; |
10829 for (intptr_t i = 0; i < array_len; ++i) { | 10838 for (intptr_t i = 0; i < array_len; ++i) { |
10830 if (utf32_array[i] > 0xffff) { | 10839 int32_t code_point = utf32_array[i]; |
| 10840 if (code_point > Utf16::kMaxCodeUnit) { |
10831 ASSERT(j < (utf16_len - 1)); | 10841 ASSERT(j < (utf16_len - 1)); |
10832 Utf8::ConvertUTF32ToUTF16(utf32_array[i], CharAddr(result, j)); | 10842 *CharAddr(result, j) = Utf16::LeadFromCodePoint(code_point); |
| 10843 *CharAddr(result, j + 1) = Utf16::TrailFromCodePoint(code_point); |
10833 j += 2; | 10844 j += 2; |
10834 } else { | 10845 } else { |
10835 ASSERT(j < utf16_len); | 10846 ASSERT(j < utf16_len); |
10836 *CharAddr(result, j) = utf32_array[i]; | 10847 *CharAddr(result, j) = utf32_array[i]; |
10837 j += 1; | 10848 j += 1; |
10838 } | 10849 } |
10839 } | 10850 } |
10840 } | 10851 } |
10841 return TwoByteString::raw(result); | 10852 return TwoByteString::raw(result); |
10842 } | 10853 } |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10876 intptr_t str_len = str.Length(); | 10887 intptr_t str_len = str.Length(); |
10877 String::Copy(result, pos, str, 0, str_len); | 10888 String::Copy(result, pos, str, 0, str_len); |
10878 pos += str_len; | 10889 pos += str_len; |
10879 } | 10890 } |
10880 return TwoByteString::raw(result); | 10891 return TwoByteString::raw(result); |
10881 } | 10892 } |
10882 | 10893 |
10883 | 10894 |
10884 RawTwoByteString* TwoByteString::Transform(int32_t (*mapping)(int32_t ch), | 10895 RawTwoByteString* TwoByteString::Transform(int32_t (*mapping)(int32_t ch), |
10885 const String& str, | 10896 const String& str, |
| 10897 intptr_t out_length, |
10886 Heap::Space space) { | 10898 Heap::Space space) { |
10887 ASSERT(!str.IsNull()); | 10899 ASSERT(!str.IsNull()); |
10888 intptr_t len = str.Length(); | 10900 intptr_t len = str.Length(); |
10889 const String& result = String::Handle(TwoByteString::New(len, space)); | 10901 const String& result = |
10890 for (intptr_t i = 0; i < len; ++i) { | 10902 String::Handle(TwoByteString::New(out_length, space)); |
10891 int32_t ch = mapping(str.CharAt(i)); | 10903 for (intptr_t i = 0, j = 0; i < len; ++i, j++) { |
10892 ASSERT(ch >= 0 && ch <= 0xFFFF); | 10904 int32_t old_ch = Utf16::CodePointAt(str, i); |
10893 *CharAddr(result, i) = ch; | 10905 if (old_ch > Utf16::kMaxCodeUnit) i++; |
| 10906 int32_t ch = mapping(old_ch); |
| 10907 ASSERT(ch <= Utf16::kMaxCodePoint); |
| 10908 if (ch <= Utf16::kMaxCodeUnit) { |
| 10909 *CharAddr(result, j) = ch; |
| 10910 } else { |
| 10911 *CharAddr(result, j) = Utf16::LeadFromCodePoint(ch); |
| 10912 *CharAddr(result, j + 1) = Utf16::TrailFromCodePoint(ch); |
| 10913 ++j; |
| 10914 } |
| 10915 ASSERT(j <= out_length); |
10894 } | 10916 } |
10895 return TwoByteString::raw(result); | 10917 return TwoByteString::raw(result); |
10896 } | 10918 } |
10897 | 10919 |
10898 | 10920 |
10899 RawExternalOneByteString* ExternalOneByteString::New( | 10921 RawExternalOneByteString* ExternalOneByteString::New( |
10900 const uint8_t* data, | 10922 const uint8_t* data, |
10901 intptr_t len, | 10923 intptr_t len, |
10902 void* peer, | 10924 void* peer, |
10903 Dart_PeerFinalizer callback, | 10925 Dart_PeerFinalizer callback, |
(...skipping 1182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12086 } | 12108 } |
12087 return result.raw(); | 12109 return result.raw(); |
12088 } | 12110 } |
12089 | 12111 |
12090 | 12112 |
12091 const char* WeakProperty::ToCString() const { | 12113 const char* WeakProperty::ToCString() const { |
12092 return "_WeakProperty"; | 12114 return "_WeakProperty"; |
12093 } | 12115 } |
12094 | 12116 |
12095 } // namespace dart | 12117 } // namespace dart |
OLD | NEW |