Add equals to C++ String
This is a baby step towards using String instead of StringPiece.
Change-Id: I34baa1c91e99f78151ec1fa9175eb5df30fa0292
diff --git a/src/class_linker.h b/src/class_linker.h
index d6c2f0c..b504095 100644
--- a/src/class_linker.h
+++ b/src/class_linker.h
@@ -206,6 +206,7 @@
FRIEND_TEST(DexCacheTest, Open);
friend class ObjectTest;
FRIEND_TEST(ObjectTest, AllocObjectArray);
+ FRIEND_TEST(ObjectTest, StringEquals);
DISALLOW_COPY_AND_ASSIGN(ClassLinker);
};
diff --git a/src/object.h b/src/object.h
index 4d68d30..a9bf40f 100644
--- a/src/object.h
+++ b/src/object.h
@@ -1057,11 +1057,11 @@
// Field order required by test "ValidateFieldOrderOfJavaCppUnionClasses".
CharArray* array_;
- uint32_t hash_code_;
+ int32_t hash_code_;
- uint32_t offset_;
+ int32_t offset_;
- uint32_t count_;
+ int32_t count_;
static String* Alloc(Class* java_lang_String,
Class* char_array,
@@ -1114,14 +1114,25 @@
}
// The java/lang/String.computeHashCode() algorithm
- static uint32_t ComputeUtf16Hash(const uint16_t* string_data, size_t string_length) {
- uint32_t hash = 0;
+ static int32_t ComputeUtf16Hash(const uint16_t* string_data, size_t string_length) {
+ int32_t hash = 0;
while (string_length--) {
hash = hash * 31 + *string_data++;
}
return hash;
}
+ static bool Equals(const String* string, const char* other) {
+ uint16_t* chars = string->array_->GetChars();
+ for (int32_t i = 0; i < string->count_; i++) {
+ uint16_t c = GetUtf16FromUtf8(&other);
+ if (c == '\0' || c != chars[string->offset_ + i]) {
+ return false;
+ }
+ }
+ return *other == '\0';
+ }
+
private:
String();
};
diff --git a/src/object_test.cc b/src/object_test.cc
index 969378c..7800855 100644
--- a/src/object_test.cc
+++ b/src/object_test.cc
@@ -19,7 +19,7 @@
void AssertString(size_t length,
const char* utf8_in,
const char* utf16_expected_le,
- uint32_t hash_expected) {
+ int32_t hash_expected) {
uint16_t utf16_expected[length];
for (size_t i = 0; i < length; i++) {
uint16_t ch = (((utf16_expected_le[i*2 + 0] & 0xff) << 8) |
@@ -28,9 +28,11 @@
}
String* string = class_linker_->AllocStringFromModifiedUtf8(length, utf8_in);
- ASSERT_EQ(length, string->count_);
+ ASSERT_EQ(length, static_cast<size_t>(string->count_));
ASSERT_TRUE(string->array_ != NULL);
ASSERT_TRUE(string->array_->GetChars() != NULL);
+ // strlen is necessary because the 1-character string "\0" is interpreted as ""
+ ASSERT_TRUE(String::Equals(string, utf8_in) || length != strlen(utf8_in));
for (size_t i = 0; i < length; i++) {
EXPECT_EQ(utf16_expected[i], string->array_->GetChar(i));
}
@@ -87,4 +89,23 @@
AssertString(1, "\xef\xbf\xbf", "\xff\xff", 0xffff);
AssertString(3, "h\xe1\x88\xb4i", "\x00\x68\x12\x34\x00\x69", (31 * ((31 * 0x68) + 0x1234)) + 0x69);
}
+
+static bool StringNotEquals(const String* a, const char* b) {
+ return !String::Equals(a, b);
+}
+
+TEST_F(ObjectTest, StringEquals) {
+ String* string = class_linker_->AllocStringFromModifiedUtf8(7, "android");
+ EXPECT_PRED2(String::Equals, string, "android");
+ EXPECT_PRED2(StringNotEquals, string, "Android");
+ EXPECT_PRED2(StringNotEquals, string, "ANDROID");
+ EXPECT_PRED2(StringNotEquals, string, "");
+ EXPECT_PRED2(StringNotEquals, string, "and");
+ EXPECT_PRED2(StringNotEquals, string, "androids");
+
+ String* empty = class_linker_->AllocStringFromModifiedUtf8(0, "");
+ EXPECT_PRED2(String::Equals, empty, "");
+ EXPECT_PRED2(StringNotEquals, empty, "a");
+}
+
} // namespace art