16f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski/* 26f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * Copyright (C) 2015 The Android Open Source Project 36f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * 46f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * Licensed under the Apache License, Version 2.0 (the "License"); 56f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * you may not use this file except in compliance with the License. 66f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * You may obtain a copy of the License at 76f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * 86f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * http://www.apache.org/licenses/LICENSE-2.0 96f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * 106f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * Unless required by applicable law or agreed to in writing, software 116f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * distributed under the License is distributed on an "AS IS" BASIS, 126f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 136f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * See the License for the specific language governing permissions and 146f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski * limitations under the License. 156f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski */ 166f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 17d5083f6f6b9bc76bbe64052bcec639eee752a321Adam Lesinski#ifndef ANDROIDFW_STRING_PIECE_H 18d5083f6f6b9bc76bbe64052bcec639eee752a321Adam Lesinski#define ANDROIDFW_STRING_PIECE_H 196f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 20cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski#include <ostream> 21cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski#include <string> 226f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 23ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski#include "utils/JenkinsHash.h" 24ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski#include "utils/Unicode.h" 25ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski 26d5083f6f6b9bc76bbe64052bcec639eee752a321Adam Lesinskinamespace android { 276f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 28d5083f6f6b9bc76bbe64052bcec639eee752a321Adam Lesinski// Read only wrapper around basic C strings. Prevents excessive copying. 29d5083f6f6b9bc76bbe64052bcec639eee752a321Adam Lesinski// StringPiece does not own the data it is wrapping. The lifetime of the underlying 30d5083f6f6b9bc76bbe64052bcec639eee752a321Adam Lesinski// data must outlive this StringPiece. 31d5083f6f6b9bc76bbe64052bcec639eee752a321Adam Lesinski// 32d5083f6f6b9bc76bbe64052bcec639eee752a321Adam Lesinski// WARNING: When creating from std::basic_string<>, moving the original 33d5083f6f6b9bc76bbe64052bcec639eee752a321Adam Lesinski// std::basic_string<> will invalidate the data held in a BasicStringPiece<>. 34d5083f6f6b9bc76bbe64052bcec639eee752a321Adam Lesinski// BasicStringPiece<> should only be used transitively. 356f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskitemplate <typename TChar> 366f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskiclass BasicStringPiece { 37cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski public: 38cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski using const_iterator = const TChar*; 39cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski using difference_type = size_t; 40cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski 41cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski // End of string marker. 42cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski constexpr static const size_t npos = static_cast<size_t>(-1); 43cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski 44cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski BasicStringPiece(); 45cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski BasicStringPiece(const BasicStringPiece<TChar>& str); 46cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski BasicStringPiece(const std::basic_string<TChar>& str); // NOLINT(implicit) 47cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski BasicStringPiece(const TChar* str); // NOLINT(implicit) 48cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski BasicStringPiece(const TChar* str, size_t len); 49cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski 50cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski BasicStringPiece<TChar>& operator=(const BasicStringPiece<TChar>& rhs); 51cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski BasicStringPiece<TChar>& assign(const TChar* str, size_t len); 52cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski 53cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski BasicStringPiece<TChar> substr(size_t start, size_t len = npos) const; 54d5083f6f6b9bc76bbe64052bcec639eee752a321Adam Lesinski BasicStringPiece<TChar> substr(BasicStringPiece<TChar>::const_iterator begin, 55d5083f6f6b9bc76bbe64052bcec639eee752a321Adam Lesinski BasicStringPiece<TChar>::const_iterator end) const; 56cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski 57cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski const TChar* data() const; 58cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski size_t length() const; 59cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski size_t size() const; 60cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski bool empty() const; 61d5083f6f6b9bc76bbe64052bcec639eee752a321Adam Lesinski std::basic_string<TChar> to_string() const; 62cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski 63cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski bool contains(const BasicStringPiece<TChar>& rhs) const; 64cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski int compare(const BasicStringPiece<TChar>& rhs) const; 65cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski bool operator<(const BasicStringPiece<TChar>& rhs) const; 66cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski bool operator>(const BasicStringPiece<TChar>& rhs) const; 67cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski bool operator==(const BasicStringPiece<TChar>& rhs) const; 68cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski bool operator!=(const BasicStringPiece<TChar>& rhs) const; 69cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski 70cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski const_iterator begin() const; 71cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski const_iterator end() const; 72cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski 73cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski private: 74ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski const TChar* data_; 75ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski size_t length_; 766f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski}; 776f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 786f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskiusing StringPiece = BasicStringPiece<char>; 796f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskiusing StringPiece16 = BasicStringPiece<char16_t>; 806f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 816f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski// 826f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski// BasicStringPiece implementation. 836f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski// 846f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 856f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskitemplate <typename TChar> 8621efb6827cede06c2ab708de6cdb64d052dddcceAdam Lesinskiconstexpr const size_t BasicStringPiece<TChar>::npos; 8721efb6827cede06c2ab708de6cdb64d052dddcceAdam Lesinski 8821efb6827cede06c2ab708de6cdb64d052dddcceAdam Lesinskitemplate <typename TChar> 89d5083f6f6b9bc76bbe64052bcec639eee752a321Adam Lesinskiinline BasicStringPiece<TChar>::BasicStringPiece() : data_(nullptr), length_(0) {} 906f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 916f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskitemplate <typename TChar> 92d5083f6f6b9bc76bbe64052bcec639eee752a321Adam Lesinskiinline BasicStringPiece<TChar>::BasicStringPiece(const BasicStringPiece<TChar>& str) 93ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski : data_(str.data_), length_(str.length_) {} 946f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 956f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskitemplate <typename TChar> 96d5083f6f6b9bc76bbe64052bcec639eee752a321Adam Lesinskiinline BasicStringPiece<TChar>::BasicStringPiece(const std::basic_string<TChar>& str) 97ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski : data_(str.data()), length_(str.length()) {} 986f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 996f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskitemplate <> 100cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinskiinline BasicStringPiece<char>::BasicStringPiece(const char* str) 101ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski : data_(str), length_(str != nullptr ? strlen(str) : 0) {} 1026f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 1036f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskitemplate <> 104cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinskiinline BasicStringPiece<char16_t>::BasicStringPiece(const char16_t* str) 105ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski : data_(str), length_(str != nullptr ? strlen16(str) : 0) {} 1066f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 1076f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskitemplate <typename TChar> 108cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinskiinline BasicStringPiece<TChar>::BasicStringPiece(const TChar* str, size_t len) 109ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski : data_(str), length_(len) {} 1106f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 1116f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskitemplate <typename TChar> 1126f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskiinline BasicStringPiece<TChar>& BasicStringPiece<TChar>::operator=( 113cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski const BasicStringPiece<TChar>& rhs) { 114ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski data_ = rhs.data_; 115ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski length_ = rhs.length_; 116cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski return *this; 1176f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski} 1186f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 1196f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskitemplate <typename TChar> 120d5083f6f6b9bc76bbe64052bcec639eee752a321Adam Lesinskiinline BasicStringPiece<TChar>& BasicStringPiece<TChar>::assign(const TChar* str, size_t len) { 121ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski data_ = str; 122ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski length_ = len; 123cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski return *this; 1246f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski} 1256f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 1266f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskitemplate <typename TChar> 127d5083f6f6b9bc76bbe64052bcec639eee752a321Adam Lesinskiinline BasicStringPiece<TChar> BasicStringPiece<TChar>::substr(size_t start, size_t len) const { 128cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski if (len == npos) { 129ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski len = length_ - start; 130cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski } 131cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski 132ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski if (start > length_ || start + len > length_) { 133cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski return BasicStringPiece<TChar>(); 134cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski } 135ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski return BasicStringPiece<TChar>(data_ + start, len); 1366f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski} 1376f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 1386f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskitemplate <typename TChar> 1396f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskiinline BasicStringPiece<TChar> BasicStringPiece<TChar>::substr( 140cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski BasicStringPiece<TChar>::const_iterator begin, 141cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski BasicStringPiece<TChar>::const_iterator end) const { 142cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski return BasicStringPiece<TChar>(begin, end - begin); 1436f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski} 1446f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 1456f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskitemplate <typename TChar> 1466f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskiinline const TChar* BasicStringPiece<TChar>::data() const { 147ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski return data_; 1486f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski} 1496f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 1506f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskitemplate <typename TChar> 1516f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskiinline size_t BasicStringPiece<TChar>::length() const { 152ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski return length_; 1536f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski} 1546f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 1556f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskitemplate <typename TChar> 1566f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskiinline size_t BasicStringPiece<TChar>::size() const { 157ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski return length_; 1586f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski} 1596f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 1606f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskitemplate <typename TChar> 1616f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskiinline bool BasicStringPiece<TChar>::empty() const { 162ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski return length_ == 0; 1636f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski} 1646f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 1656f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskitemplate <typename TChar> 166d5083f6f6b9bc76bbe64052bcec639eee752a321Adam Lesinskiinline std::basic_string<TChar> BasicStringPiece<TChar>::to_string() const { 167ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski return std::basic_string<TChar>(data_, length_); 1686f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski} 1696f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 1706f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskitemplate <> 171d5083f6f6b9bc76bbe64052bcec639eee752a321Adam Lesinskiinline bool BasicStringPiece<char>::contains(const BasicStringPiece<char>& rhs) const { 172ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski if (!data_ || !rhs.data_) { 173cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski return false; 174cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski } 175ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski if (rhs.length_ > length_) { 176cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski return false; 177cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski } 178ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski return strstr(data_, rhs.data_) != nullptr; 179feaf99fa1b7563f15dbd4211718a6cfb7a3cc3c8Michael Wright} 180feaf99fa1b7563f15dbd4211718a6cfb7a3cc3c8Michael Wright 181feaf99fa1b7563f15dbd4211718a6cfb7a3cc3c8Michael Wrighttemplate <> 182d5083f6f6b9bc76bbe64052bcec639eee752a321Adam Lesinskiinline int BasicStringPiece<char>::compare(const BasicStringPiece<char>& rhs) const { 183cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski const char nullStr = '\0'; 184ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski const char* b1 = data_ != nullptr ? data_ : &nullStr; 185ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski const char* e1 = b1 + length_; 186ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski const char* b2 = rhs.data_ != nullptr ? rhs.data_ : &nullStr; 187ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski const char* e2 = b2 + rhs.length_; 188cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski 189cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski while (b1 < e1 && b2 < e2) { 190cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski const int d = static_cast<int>(*b1++) - static_cast<int>(*b2++); 191cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski if (d) { 192cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski return d; 1936f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski } 194cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski } 195ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski return static_cast<int>(length_ - rhs.length_); 1966f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski} 1976f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 198d5083f6f6b9bc76bbe64052bcec639eee752a321Adam Lesinskiinline ::std::ostream& operator<<(::std::ostream& out, const BasicStringPiece<char16_t>& str) { 199d5083f6f6b9bc76bbe64052bcec639eee752a321Adam Lesinski const ssize_t result_len = utf16_to_utf8_length(str.data(), str.size()); 200d5083f6f6b9bc76bbe64052bcec639eee752a321Adam Lesinski if (result_len < 0) { 201d5083f6f6b9bc76bbe64052bcec639eee752a321Adam Lesinski // Empty string. 202d5083f6f6b9bc76bbe64052bcec639eee752a321Adam Lesinski return out; 203d5083f6f6b9bc76bbe64052bcec639eee752a321Adam Lesinski } 204d5083f6f6b9bc76bbe64052bcec639eee752a321Adam Lesinski 205d5083f6f6b9bc76bbe64052bcec639eee752a321Adam Lesinski std::string result; 206d5083f6f6b9bc76bbe64052bcec639eee752a321Adam Lesinski result.resize(static_cast<size_t>(result_len)); 207d5083f6f6b9bc76bbe64052bcec639eee752a321Adam Lesinski utf16_to_utf8(str.data(), str.length(), &*result.begin(), static_cast<size_t>(result_len) + 1); 208d5083f6f6b9bc76bbe64052bcec639eee752a321Adam Lesinski return out << result; 2096f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski} 2106f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 211feaf99fa1b7563f15dbd4211718a6cfb7a3cc3c8Michael Wrighttemplate <> 212d5083f6f6b9bc76bbe64052bcec639eee752a321Adam Lesinskiinline bool BasicStringPiece<char16_t>::contains(const BasicStringPiece<char16_t>& rhs) const { 213ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski if (!data_ || !rhs.data_) { 214cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski return false; 215cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski } 216ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski if (rhs.length_ > length_) { 217cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski return false; 218cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski } 219ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski return strstr16(data_, rhs.data_) != nullptr; 220feaf99fa1b7563f15dbd4211718a6cfb7a3cc3c8Michael Wright} 2216f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 2226f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskitemplate <> 223d5083f6f6b9bc76bbe64052bcec639eee752a321Adam Lesinskiinline int BasicStringPiece<char16_t>::compare(const BasicStringPiece<char16_t>& rhs) const { 224cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski const char16_t nullStr = u'\0'; 225ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski const char16_t* b1 = data_ != nullptr ? data_ : &nullStr; 226ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski const char16_t* b2 = rhs.data_ != nullptr ? rhs.data_ : &nullStr; 227ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski return strzcmp16(b1, length_, b2, rhs.length_); 2286f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski} 2296f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 2306f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskitemplate <typename TChar> 231d5083f6f6b9bc76bbe64052bcec639eee752a321Adam Lesinskiinline bool BasicStringPiece<TChar>::operator<(const BasicStringPiece<TChar>& rhs) const { 232cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski return compare(rhs) < 0; 2336f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski} 2346f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 2356f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskitemplate <typename TChar> 236d5083f6f6b9bc76bbe64052bcec639eee752a321Adam Lesinskiinline bool BasicStringPiece<TChar>::operator>(const BasicStringPiece<TChar>& rhs) const { 237cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski return compare(rhs) > 0; 2386f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski} 2396f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 2406f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskitemplate <typename TChar> 241d5083f6f6b9bc76bbe64052bcec639eee752a321Adam Lesinskiinline bool BasicStringPiece<TChar>::operator==(const BasicStringPiece<TChar>& rhs) const { 242cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski return compare(rhs) == 0; 2436f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski} 2446f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 2456f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskitemplate <typename TChar> 246d5083f6f6b9bc76bbe64052bcec639eee752a321Adam Lesinskiinline bool BasicStringPiece<TChar>::operator!=(const BasicStringPiece<TChar>& rhs) const { 247cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski return compare(rhs) != 0; 2486f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski} 2496f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 2506f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskitemplate <typename TChar> 251d5083f6f6b9bc76bbe64052bcec639eee752a321Adam Lesinskiinline typename BasicStringPiece<TChar>::const_iterator BasicStringPiece<TChar>::begin() const { 252ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski return data_; 2536f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski} 2546f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 2556f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskitemplate <typename TChar> 256d5083f6f6b9bc76bbe64052bcec639eee752a321Adam Lesinskiinline typename BasicStringPiece<TChar>::const_iterator BasicStringPiece<TChar>::end() const { 257ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski return data_ + length_; 2586f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski} 2596f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 260929d6517dfd338f0d481dbe6587643d5aef27ec6Adam Lesinskitemplate <typename TChar> 261929d6517dfd338f0d481dbe6587643d5aef27ec6Adam Lesinskiinline bool operator==(const TChar* lhs, const BasicStringPiece<TChar>& rhs) { 262929d6517dfd338f0d481dbe6587643d5aef27ec6Adam Lesinski return BasicStringPiece<TChar>(lhs) == rhs; 263929d6517dfd338f0d481dbe6587643d5aef27ec6Adam Lesinski} 264929d6517dfd338f0d481dbe6587643d5aef27ec6Adam Lesinski 265929d6517dfd338f0d481dbe6587643d5aef27ec6Adam Lesinskitemplate <typename TChar> 266929d6517dfd338f0d481dbe6587643d5aef27ec6Adam Lesinskiinline bool operator!=(const TChar* lhs, const BasicStringPiece<TChar>& rhs) { 267929d6517dfd338f0d481dbe6587643d5aef27ec6Adam Lesinski return BasicStringPiece<TChar>(lhs) != rhs; 268929d6517dfd338f0d481dbe6587643d5aef27ec6Adam Lesinski} 269929d6517dfd338f0d481dbe6587643d5aef27ec6Adam Lesinski 270d5083f6f6b9bc76bbe64052bcec639eee752a321Adam Lesinskiinline ::std::ostream& operator<<(::std::ostream& out, const BasicStringPiece<char>& str) { 271cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski return out.write(str.data(), str.size()); 2726f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski} 2736f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski 2747542162cb1b1fd2ce8a26dd7f3fedc8de8160d38Adam Lesinskitemplate <typename TChar> 2757542162cb1b1fd2ce8a26dd7f3fedc8de8160d38Adam Lesinskiinline ::std::basic_string<TChar>& operator+=(::std::basic_string<TChar>& lhs, 2767542162cb1b1fd2ce8a26dd7f3fedc8de8160d38Adam Lesinski const BasicStringPiece<TChar>& rhs) { 2777542162cb1b1fd2ce8a26dd7f3fedc8de8160d38Adam Lesinski return lhs.append(rhs.data(), rhs.size()); 2787542162cb1b1fd2ce8a26dd7f3fedc8de8160d38Adam Lesinski} 2797542162cb1b1fd2ce8a26dd7f3fedc8de8160d38Adam Lesinski 2807542162cb1b1fd2ce8a26dd7f3fedc8de8160d38Adam Lesinskitemplate <typename TChar> 2817542162cb1b1fd2ce8a26dd7f3fedc8de8160d38Adam Lesinskiinline bool operator==(const ::std::basic_string<TChar>& lhs, const BasicStringPiece<TChar>& rhs) { 2827542162cb1b1fd2ce8a26dd7f3fedc8de8160d38Adam Lesinski return rhs == lhs; 2837542162cb1b1fd2ce8a26dd7f3fedc8de8160d38Adam Lesinski} 2847542162cb1b1fd2ce8a26dd7f3fedc8de8160d38Adam Lesinski 2857542162cb1b1fd2ce8a26dd7f3fedc8de8160d38Adam Lesinskitemplate <typename TChar> 2867542162cb1b1fd2ce8a26dd7f3fedc8de8160d38Adam Lesinskiinline bool operator!=(const ::std::basic_string<TChar>& lhs, const BasicStringPiece<TChar>& rhs) { 2877542162cb1b1fd2ce8a26dd7f3fedc8de8160d38Adam Lesinski return rhs != lhs; 2887542162cb1b1fd2ce8a26dd7f3fedc8de8160d38Adam Lesinski} 2897542162cb1b1fd2ce8a26dd7f3fedc8de8160d38Adam Lesinski 290d5083f6f6b9bc76bbe64052bcec639eee752a321Adam Lesinski} // namespace android 29190959887e9a61ff83097b2789f8b3243ad817decAdam Lesinski 2927542162cb1b1fd2ce8a26dd7f3fedc8de8160d38Adam Lesinskiinline ::std::ostream& operator<<(::std::ostream& out, const std::u16string& str) { 2937542162cb1b1fd2ce8a26dd7f3fedc8de8160d38Adam Lesinski ssize_t utf8_len = utf16_to_utf8_length(str.data(), str.size()); 2947542162cb1b1fd2ce8a26dd7f3fedc8de8160d38Adam Lesinski if (utf8_len < 0) { 2957542162cb1b1fd2ce8a26dd7f3fedc8de8160d38Adam Lesinski return out << "???"; 2967542162cb1b1fd2ce8a26dd7f3fedc8de8160d38Adam Lesinski } 2977542162cb1b1fd2ce8a26dd7f3fedc8de8160d38Adam Lesinski 2987542162cb1b1fd2ce8a26dd7f3fedc8de8160d38Adam Lesinski std::string utf8; 2997542162cb1b1fd2ce8a26dd7f3fedc8de8160d38Adam Lesinski utf8.resize(static_cast<size_t>(utf8_len)); 3007542162cb1b1fd2ce8a26dd7f3fedc8de8160d38Adam Lesinski utf16_to_utf8(str.data(), str.size(), &*utf8.begin(), utf8_len + 1); 3017542162cb1b1fd2ce8a26dd7f3fedc8de8160d38Adam Lesinski return out << utf8; 3027542162cb1b1fd2ce8a26dd7f3fedc8de8160d38Adam Lesinski} 3037542162cb1b1fd2ce8a26dd7f3fedc8de8160d38Adam Lesinski 30432852a575bbd79caaabb701cf5b76571516bb6c5Adam Lesinskinamespace std { 30532852a575bbd79caaabb701cf5b76571516bb6c5Adam Lesinski 30632852a575bbd79caaabb701cf5b76571516bb6c5Adam Lesinskitemplate <typename TChar> 307d5083f6f6b9bc76bbe64052bcec639eee752a321Adam Lesinskistruct hash<android::BasicStringPiece<TChar>> { 308d5083f6f6b9bc76bbe64052bcec639eee752a321Adam Lesinski size_t operator()(const android::BasicStringPiece<TChar>& str) const { 309cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski uint32_t hashCode = android::JenkinsHashMixBytes( 310d5083f6f6b9bc76bbe64052bcec639eee752a321Adam Lesinski 0, reinterpret_cast<const uint8_t*>(str.data()), sizeof(TChar) * str.size()); 311cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski return static_cast<size_t>(hashCode); 312cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski } 31332852a575bbd79caaabb701cf5b76571516bb6c5Adam Lesinski}; 31432852a575bbd79caaabb701cf5b76571516bb6c5Adam Lesinski 315cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski} // namespace std 31632852a575bbd79caaabb701cf5b76571516bb6c5Adam Lesinski 317d5083f6f6b9bc76bbe64052bcec639eee752a321Adam Lesinski#endif // ANDROIDFW_STRING_PIECE_H 318