From 86c9ea8f861ec80399305f6f5aff422e45e0ac70 Mon Sep 17 00:00:00 2001 From: Tomasz Wasilczyk Date: Tue, 12 Sep 2023 16:23:13 +0000 Subject: [PATCH] Implement android::String access methods that avoid C string cast Bug: 295394788 Test: m checkbuild Change-Id: If25fd69319171e8c549fc8fcfd95a0819291d8e6 --- libutils/include/utils/String16.h | 24 +++++++++++++++++ libutils/include/utils/String8.h | 43 ++++++++++++++++++++++++++++++- 2 files changed, 66 insertions(+), 1 deletion(-) diff --git a/libutils/include/utils/String16.h b/libutils/include/utils/String16.h index b48b90765..fb94174da 100644 --- a/libutils/include/utils/String16.h +++ b/libutils/include/utils/String16.h @@ -24,6 +24,11 @@ #include #include +#if __has_include() +#include +#define HAS_STRING_VIEW +#endif + // --------------------------------------------------------------------------- namespace android { @@ -91,6 +96,7 @@ public: bool startsWith(const char16_t* prefix) const; bool contains(const char16_t* chrs) const; + inline bool contains(const String16& other) const; status_t replaceAll(char16_t replaceThis, char16_t withThis); @@ -113,6 +119,12 @@ public: inline operator const char16_t*() const; +#ifdef HAS_STRING_VIEW + // Implicit cast to std::u16string is not implemented on purpose - u16string_view is much + // lighter and if one needs, they can still create u16string from u16string_view. + inline operator std::u16string_view() const; +#endif + // Static and non-static String16 behave the same for the users, so // this method isn't of much use for the users. It is public for testing. bool isStaticString() const; @@ -264,6 +276,11 @@ inline size_t String16::length() const return size(); } +inline bool String16::contains(const String16& other) const +{ + return contains(other.c_str()); +} + inline String16& String16::operator=(const String16& other) { setTo(other); @@ -353,8 +370,15 @@ inline String16::operator const char16_t*() const return mString; } +inline String16::operator std::u16string_view() const +{ + return {mString, length()}; +} + } // namespace android // --------------------------------------------------------------------------- +#undef HAS_STRING_VIEW + #endif // ANDROID_STRING16_H diff --git a/libutils/include/utils/String8.h b/libutils/include/utils/String8.h index ea25c6aa3..389301865 100644 --- a/libutils/include/utils/String8.h +++ b/libutils/include/utils/String8.h @@ -18,7 +18,6 @@ #define ANDROID_STRING8_H #include -#include #include #include @@ -27,6 +26,16 @@ #include // for strcmp #include +#if __has_include() +#include +#define HAS_STRING +#endif + +#if __has_include() +#include +#define HAS_STRING_VIEW +#endif + // --------------------------------------------------------------------------- namespace android { @@ -113,6 +122,10 @@ public: inline operator const char*() const; +#ifdef HAS_STRING_VIEW + inline explicit operator std::string_view() const; +#endif + char* lockBuffer(size_t size); void unlockBuffer(); status_t unlockBuffer(size_t size); @@ -120,13 +133,16 @@ public: // return the index of the first byte of other in this at or after // start, or -1 if not found ssize_t find(const char* other, size_t start = 0) const; + inline ssize_t find(const String8& other, size_t start = 0) const; // return true if this string contains the specified substring inline bool contains(const char* other) const; + inline bool contains(const String8& other) const; // removes all occurrence of the specified substring // returns true if any were found and removed bool removeAll(const char* other); + inline bool removeAll(const String8& other); void toLower(); @@ -264,11 +280,26 @@ inline size_t String8::bytes() const return length(); } +inline ssize_t String8::find(const String8& other, size_t start) const +{ + return find(other.c_str(), start); +} + inline bool String8::contains(const char* other) const { return find(other) >= 0; } +inline bool String8::contains(const String8& other) const +{ + return contains(other.c_str()); +} + +inline bool String8::removeAll(const String8& other) +{ + return removeAll(other.c_str()); +} + inline String8& String8::operator=(const String8& other) { setTo(other); @@ -377,8 +408,18 @@ inline String8::operator const char*() const return mString; } +#ifdef HAS_STRING_VIEW +inline String8::operator std::string_view() const +{ + return {mString, length()}; +} +#endif + } // namespace android // --------------------------------------------------------------------------- +#undef HAS_STRING +#undef HAS_STRING_VIEW + #endif // ANDROID_STRING8_H