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