| 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 |