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