Clean up OatHeader::GetStoreValueKey*().

Replace helper function ParseString() with calls to memchr()
and make the OatHeader::GetStoreValueKey*() more readable.
This also avoids using a pointer to `end + 1` when we fail
to find the end of the value (this was benign as that `+1`
should not cause arithmetic overflow anyway).

Test: m test-art-host-gtest
Test: testrunner.py --host --optimizing
Change-Id: I2fa9043f42048689a64fba3ab1fc3845f4684544
diff --git a/runtime/oat.cc b/runtime/oat.cc
index 321425b..3698ddf 100644
--- a/runtime/oat.cc
+++ b/runtime/oat.cc
@@ -335,65 +335,66 @@
   return key_value_store_;
 }
 
-// Advance start until it is either end or \0.
-static const char* ParseString(const char* start, const char* end) {
-  while (start < end && *start != 0) {
-    start++;
-  }
-  return start;
-}
-
 const char* OatHeader::GetStoreValueByKey(const char* key) const {
+  std::string_view key_view(key);
   const char* ptr = reinterpret_cast<const char*>(&key_value_store_);
   const char* end = ptr + key_value_store_size_;
 
   while (ptr < end) {
     // Scan for a closing zero.
-    const char* str_end = ParseString(ptr, end);
-    if (str_end < end) {
-      if (strcmp(key, ptr) == 0) {
-        // Same as key. Check if value is OK.
-        if (ParseString(str_end + 1, end) < end) {
-          return str_end + 1;
-        }
-      } else {
-        // Different from key. Advance over the value.
-        ptr = ParseString(str_end + 1, end) + 1;
-      }
-    } else {
-      break;
+    const char* str_end = reinterpret_cast<const char*>(memchr(ptr, 0, end - ptr));
+    if (UNLIKELY(str_end == nullptr)) {
+      LOG(WARNING) << "OatHeader: Unterminated key in key value store.";
+      return nullptr;
     }
+    const char* value_start = str_end + 1;
+    const char* value_end =
+        reinterpret_cast<const char*>(memchr(value_start, 0, end - value_start));
+    if (UNLIKELY(value_end == nullptr)) {
+      LOG(WARNING) << "OatHeader: Unterminated value in key value store.";
+      return nullptr;
+    }
+    if (key_view == std::string_view(ptr, str_end - ptr)) {
+      // Same as key.
+      return value_start;
+    }
+    // Different from key. Advance over the value.
+    ptr = value_end + 1;
   }
   // Not found.
   return nullptr;
 }
 
-bool OatHeader::GetStoreKeyValuePairByIndex(size_t index, const char** key,
+bool OatHeader::GetStoreKeyValuePairByIndex(size_t index,
+                                            const char** key,
                                             const char** value) const {
   const char* ptr = reinterpret_cast<const char*>(&key_value_store_);
   const char* end = ptr + key_value_store_size_;
-  ssize_t counter = static_cast<ssize_t>(index);
+  size_t counter = index;
 
-  while (ptr < end && counter >= 0) {
+  while (ptr < end) {
     // Scan for a closing zero.
-    const char* str_end = ParseString(ptr, end);
-    if (str_end < end) {
-      const char* maybe_key = ptr;
-      ptr = ParseString(str_end + 1, end) + 1;
-      if (ptr <= end) {
-        if (counter == 0) {
-          *key = maybe_key;
-          *value = str_end + 1;
-          return true;
-        } else {
-          counter--;
-        }
-      } else {
-        return false;
-      }
-    } else {
-      break;
+    const char* str_end = reinterpret_cast<const char*>(memchr(ptr, 0, end - ptr));
+    if (UNLIKELY(str_end == nullptr)) {
+      LOG(WARNING) << "OatHeader: Unterminated key in key value store.";
+      return false;
     }
+    const char* value_start = str_end + 1;
+    const char* value_end =
+        reinterpret_cast<const char*>(memchr(value_start, 0, end - value_start));
+    if (UNLIKELY(value_end == nullptr)) {
+      LOG(WARNING) << "OatHeader: Unterminated value in key value store.";
+      return false;
+    }
+    if (counter == 0) {
+      *key = ptr;
+      *value = value_start;
+      return true;
+    } else {
+      --counter;
+    }
+    // Advance over the value.
+    ptr = value_end + 1;
   }
   // Not found.
   return false;