StringPiece.h revision 1ab598f46c3ff520a67f9d80194847741f3467ab
1/* 2 * Copyright (C) 2015 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#ifndef AAPT_STRING_PIECE_H 18#define AAPT_STRING_PIECE_H 19 20#include <ostream> 21#include <string> 22#include <utils/String8.h> 23#include <utils/Unicode.h> 24 25namespace aapt { 26 27/** 28 * Read only wrapper around basic C strings. 29 * Prevents excessive copying. 30 * 31 * WARNING: When creating from std::basic_string<>, moving the original 32 * std::basic_string<> will invalidate the data held in a BasicStringPiece<>. 33 * BasicStringPiece<> should only be used transitively. 34 */ 35template <typename TChar> 36class BasicStringPiece { 37public: 38 using const_iterator = const TChar*; 39 40 BasicStringPiece(); 41 BasicStringPiece(const BasicStringPiece<TChar>& str); 42 BasicStringPiece(const std::basic_string<TChar>& str); 43 BasicStringPiece(const TChar* str); 44 BasicStringPiece(const TChar* str, size_t len); 45 46 BasicStringPiece<TChar>& operator=(const BasicStringPiece<TChar>& rhs); 47 BasicStringPiece<TChar>& assign(const TChar* str, size_t len); 48 49 BasicStringPiece<TChar> substr(size_t start, size_t len) const; 50 BasicStringPiece<TChar> substr(BasicStringPiece<TChar>::const_iterator begin, 51 BasicStringPiece<TChar>::const_iterator end) const; 52 53 const TChar* data() const; 54 size_t length() const; 55 size_t size() const; 56 bool empty() const; 57 std::basic_string<TChar> toString() const; 58 59 int compare(const BasicStringPiece<TChar>& rhs) const; 60 bool operator<(const BasicStringPiece<TChar>& rhs) const; 61 bool operator>(const BasicStringPiece<TChar>& rhs) const; 62 bool operator==(const BasicStringPiece<TChar>& rhs) const; 63 bool operator!=(const BasicStringPiece<TChar>& rhs) const; 64 65 const_iterator begin() const; 66 const_iterator end() const; 67 68private: 69 const TChar* mData; 70 size_t mLength; 71}; 72 73using StringPiece = BasicStringPiece<char>; 74using StringPiece16 = BasicStringPiece<char16_t>; 75 76// 77// BasicStringPiece implementation. 78// 79 80template <typename TChar> 81inline BasicStringPiece<TChar>::BasicStringPiece() : mData(nullptr) , mLength(0) { 82} 83 84template <typename TChar> 85inline BasicStringPiece<TChar>::BasicStringPiece(const BasicStringPiece<TChar>& str) : 86 mData(str.mData), mLength(str.mLength) { 87} 88 89template <typename TChar> 90inline BasicStringPiece<TChar>::BasicStringPiece(const std::basic_string<TChar>& str) : 91 mData(str.data()), mLength(str.length()) { 92} 93 94template <> 95inline BasicStringPiece<char>::BasicStringPiece(const char* str) : 96 mData(str), mLength(str != nullptr ? strlen(str) : 0) { 97} 98 99template <> 100inline BasicStringPiece<char16_t>::BasicStringPiece(const char16_t* str) : 101 mData(str), mLength(str != nullptr ? strlen16(str) : 0) { 102} 103 104template <typename TChar> 105inline BasicStringPiece<TChar>::BasicStringPiece(const TChar* str, size_t len) : 106 mData(str), mLength(len) { 107} 108 109template <typename TChar> 110inline BasicStringPiece<TChar>& BasicStringPiece<TChar>::operator=( 111 const BasicStringPiece<TChar>& rhs) { 112 mData = rhs.mData; 113 mLength = rhs.mLength; 114 return *this; 115} 116 117template <typename TChar> 118inline BasicStringPiece<TChar>& BasicStringPiece<TChar>::assign(const TChar* str, size_t len) { 119 mData = str; 120 mLength = len; 121 return *this; 122} 123 124 125template <typename TChar> 126inline BasicStringPiece<TChar> BasicStringPiece<TChar>::substr(size_t start, size_t len) const { 127 if (start + len > mLength) { 128 return BasicStringPiece<TChar>(); 129 } 130 return BasicStringPiece<TChar>(mData + start, len); 131} 132 133template <typename TChar> 134inline BasicStringPiece<TChar> BasicStringPiece<TChar>::substr( 135 BasicStringPiece<TChar>::const_iterator begin, 136 BasicStringPiece<TChar>::const_iterator end) const { 137 return BasicStringPiece<TChar>(begin, end - begin); 138} 139 140template <typename TChar> 141inline const TChar* BasicStringPiece<TChar>::data() const { 142 return mData; 143} 144 145template <typename TChar> 146inline size_t BasicStringPiece<TChar>::length() const { 147 return mLength; 148} 149 150template <typename TChar> 151inline size_t BasicStringPiece<TChar>::size() const { 152 return mLength; 153} 154 155template <typename TChar> 156inline bool BasicStringPiece<TChar>::empty() const { 157 return mLength == 0; 158} 159 160template <typename TChar> 161inline std::basic_string<TChar> BasicStringPiece<TChar>::toString() const { 162 return std::basic_string<TChar>(mData, mLength); 163} 164 165template <> 166inline int BasicStringPiece<char>::compare(const BasicStringPiece<char>& rhs) const { 167 const char nullStr = '\0'; 168 const char* b1 = mData != nullptr ? mData : &nullStr; 169 const char* e1 = b1 + mLength; 170 const char* b2 = rhs.mData != nullptr ? rhs.mData : &nullStr; 171 const char* e2 = b2 + rhs.mLength; 172 173 while (b1 < e1 && b2 < e2) { 174 const int d = static_cast<int>(*b1++) - static_cast<int>(*b2++); 175 if (d) { 176 return d; 177 } 178 } 179 return static_cast<int>(mLength - rhs.mLength); 180} 181 182inline ::std::ostream& operator<<(::std::ostream& out, const BasicStringPiece<char16_t>& str) { 183 android::String8 utf8(str.data(), str.size()); 184 return out.write(utf8.string(), utf8.size()); 185} 186 187 188template <> 189inline int BasicStringPiece<char16_t>::compare(const BasicStringPiece<char16_t>& rhs) const { 190 const char16_t nullStr = u'\0'; 191 const char16_t* b1 = mData != nullptr ? mData : &nullStr; 192 const char16_t* b2 = rhs.mData != nullptr ? rhs.mData : &nullStr; 193 return strzcmp16(b1, mLength, b2, rhs.mLength); 194} 195 196template <typename TChar> 197inline bool BasicStringPiece<TChar>::operator<(const BasicStringPiece<TChar>& rhs) const { 198 return compare(rhs) < 0; 199} 200 201template <typename TChar> 202inline bool BasicStringPiece<TChar>::operator>(const BasicStringPiece<TChar>& rhs) const { 203 return compare(rhs) > 0; 204} 205 206template <typename TChar> 207inline bool BasicStringPiece<TChar>::operator==(const BasicStringPiece<TChar>& rhs) const { 208 return compare(rhs) == 0; 209} 210 211template <typename TChar> 212inline bool BasicStringPiece<TChar>::operator!=(const BasicStringPiece<TChar>& rhs) const { 213 return compare(rhs) != 0; 214} 215 216template <typename TChar> 217inline typename BasicStringPiece<TChar>::const_iterator BasicStringPiece<TChar>::begin() const { 218 return mData; 219} 220 221template <typename TChar> 222inline typename BasicStringPiece<TChar>::const_iterator BasicStringPiece<TChar>::end() const { 223 return mData + mLength; 224} 225 226inline ::std::ostream& operator<<(::std::ostream& out, const BasicStringPiece<char>& str) { 227 return out.write(str.data(), str.size()); 228} 229 230} // namespace aapt 231 232inline ::std::ostream& operator<<(::std::ostream& out, const std::u16string& str) { 233 android::String8 utf8(str.data(), str.size()); 234 return out.write(utf8.string(), utf8.size()); 235} 236 237#endif // AAPT_STRING_PIECE_H 238