1 /* 2 * Copyright (C) 2017 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 MINIKIN_STRING_PIECE_H 18 #define MINIKIN_STRING_PIECE_H 19 20 #include <cstdint> 21 #include <string> 22 #include <vector> 23 24 namespace minikin { 25 26 class StringPiece { 27 public: StringPiece()28 StringPiece() : mData(nullptr), mLength(0) {} StringPiece(const char * data)29 StringPiece(const char* data) : mData(data), mLength(data == nullptr ? 0 : strlen(data)) {} StringPiece(const char * data,size_t length)30 StringPiece(const char* data, size_t length) : mData(data), mLength(length) {} StringPiece(const std::string & str)31 StringPiece(const std::string& str) : mData(str.data()), mLength(str.size()) {} StringPiece(std::string_view str)32 StringPiece(std::string_view str) : mData(str.data()), mLength(str.size()) {} 33 data()34 inline const char* data() const { return mData; } length()35 inline size_t length() const { return mLength; } size()36 inline size_t size() const { return mLength; } empty()37 inline bool empty() const { return mLength == 0; } 38 39 inline char operator[](size_t i) const { return mData[i]; } 40 substr(size_t from,size_t length)41 inline StringPiece substr(size_t from, size_t length) const { 42 return StringPiece(mData + from, length); 43 } 44 find(size_t from,char c)45 inline size_t find(size_t from, char c) const { 46 if (from >= mLength) { 47 return mLength; 48 } 49 const char* p = static_cast<const char*>(memchr(mData + from, c, mLength - from)); 50 return p == nullptr ? mLength : p - mData; 51 } 52 toString()53 std::string toString() const { return std::string(mData, mData + mLength); } 54 55 private: 56 const char* mData; 57 size_t mLength; 58 }; 59 60 inline bool operator==(const StringPiece& l, const StringPiece& r) { 61 const size_t len = l.size(); 62 if (len != r.size()) { 63 return false; 64 } 65 const char* lData = l.data(); 66 const char* rData = r.data(); 67 if (lData == rData) { 68 return true; 69 } 70 return memcmp(lData, rData, len) == 0; 71 } 72 73 inline bool operator==(const StringPiece& l, const char* s) { 74 const size_t len = l.size(); 75 if (len != strlen(s)) { 76 return false; 77 } 78 return memcmp(l.data(), s, len) == 0; 79 } 80 81 inline bool operator!=(const StringPiece& l, const StringPiece& r) { 82 return !(l == r); 83 } 84 85 inline bool operator!=(const StringPiece& l, const char* s) { 86 return !(l == s); 87 } 88 89 class SplitIterator { 90 public: SplitIterator(const StringPiece & string,char delimiter)91 SplitIterator(const StringPiece& string, char delimiter) 92 : mStarted(false), mCurrent(0), mString(string), mDelimiter(delimiter) {} 93 next()94 inline StringPiece next() { 95 if (!hasNext()) { 96 return StringPiece(); 97 } 98 const size_t searchFrom = mStarted ? mCurrent + 1 : 0; 99 mStarted = true; 100 mCurrent = mString.find(searchFrom, mDelimiter); 101 return mString.substr(searchFrom, mCurrent - searchFrom); 102 } hasNext()103 inline bool hasNext() const { return mCurrent < mString.size(); } 104 105 private: 106 bool mStarted; 107 size_t mCurrent; 108 StringPiece mString; 109 char mDelimiter; 110 }; 111 112 } // namespace minikin 113 114 #endif // MINIKIN_STRING_PIECE_H 115