00001
00002
00003
00004
00005 #include "util/string_piece.hh"
00006
00007 #include <algorithm>
00008 #include <climits>
00009
00010 #ifndef HAVE_ICU
00011
00012 typedef StringPiece::size_type size_type;
00013
00014 void StringPiece::CopyToString(std::string* target) const {
00015 target->assign(ptr_, length_);
00016 }
00017
00018 size_type StringPiece::find(const StringPiece& s, size_type pos) const {
00019
00020 if (pos > static_cast<size_type>(length_))
00021 return npos;
00022
00023 const char* result = std::search(ptr_ + pos, ptr_ + length_,
00024 s.ptr_, s.ptr_ + s.length_);
00025 const size_type xpos = result - ptr_;
00026 return xpos + s.length_ <= length_ ? xpos : npos;
00027 }
00028
00029 size_type StringPiece::find(char c, size_type pos) const {
00030 if (length_ <= 0 || pos >= static_cast<size_type>(length_)) {
00031 return npos;
00032 }
00033 const char* result = std::find(ptr_ + pos, ptr_ + length_, c);
00034 return result != ptr_ + length_ ? result - ptr_ : npos;
00035 }
00036
00037 size_type StringPiece::rfind(const StringPiece& s, size_type pos) const {
00038 if (length_ < s.length_) return npos;
00039 const size_t ulen = length_;
00040 if (s.length_ == 0) return std::min(ulen, pos);
00041
00042 const char* last = ptr_ + std::min(ulen - s.length_, pos) + s.length_;
00043 const char* result = std::find_end(ptr_, last, s.ptr_, s.ptr_ + s.length_);
00044 return result != last ? result - ptr_ : npos;
00045 }
00046
00047 size_type StringPiece::rfind(char c, size_type pos) const {
00048 if (length_ <= 0) return npos;
00049 for (int i = std::min(pos, static_cast<size_type>(length_ - 1));
00050 i >= 0; --i) {
00051 if (ptr_[i] == c) {
00052 return i;
00053 }
00054 }
00055 return npos;
00056 }
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066 static inline void BuildLookupTable(const StringPiece& characters_wanted,
00067 bool* table) {
00068 const size_type length = characters_wanted.length();
00069 const char* const data = characters_wanted.data();
00070 for (size_type i = 0; i < length; ++i) {
00071 table[static_cast<unsigned char>(data[i])] = true;
00072 }
00073 }
00074
00075 size_type StringPiece::find_first_of(const StringPiece& s,
00076 size_type pos) const {
00077 if (length_ == 0 || s.length_ == 0)
00078 return npos;
00079
00080
00081 if (s.length_ == 1)
00082 return find_first_of(s.ptr_[0], pos);
00083
00084 bool lookup[UCHAR_MAX + 1] = { false };
00085 BuildLookupTable(s, lookup);
00086 for (size_type i = pos; i < length_; ++i) {
00087 if (lookup[static_cast<unsigned char>(ptr_[i])]) {
00088 return i;
00089 }
00090 }
00091 return npos;
00092 }
00093
00094 size_type StringPiece::find_first_not_of(const StringPiece& s,
00095 size_type pos) const {
00096 if (length_ == 0)
00097 return npos;
00098
00099 if (s.length_ == 0)
00100 return 0;
00101
00102
00103 if (s.length_ == 1)
00104 return find_first_not_of(s.ptr_[0], pos);
00105
00106 bool lookup[UCHAR_MAX + 1] = { false };
00107 BuildLookupTable(s, lookup);
00108 for (size_type i = pos; i < length_; ++i) {
00109 if (!lookup[static_cast<unsigned char>(ptr_[i])]) {
00110 return i;
00111 }
00112 }
00113 return npos;
00114 }
00115
00116 size_type StringPiece::find_first_not_of(char c, size_type pos) const {
00117 if (length_ == 0)
00118 return npos;
00119
00120 for (; pos < length_; ++pos) {
00121 if (ptr_[pos] != c) {
00122 return pos;
00123 }
00124 }
00125 return npos;
00126 }
00127
00128 size_type StringPiece::find_last_of(const StringPiece& s, size_type pos) const {
00129 if (length_ == 0 || s.length_ == 0)
00130 return npos;
00131
00132
00133 if (s.length_ == 1)
00134 return find_last_of(s.ptr_[0], pos);
00135
00136 bool lookup[UCHAR_MAX + 1] = { false };
00137 BuildLookupTable(s, lookup);
00138 for (size_type i = std::min(pos, length_ - 1); ; --i) {
00139 if (lookup[static_cast<unsigned char>(ptr_[i])])
00140 return i;
00141 if (i == 0)
00142 break;
00143 }
00144 return npos;
00145 }
00146
00147 size_type StringPiece::find_last_not_of(const StringPiece& s,
00148 size_type pos) const {
00149 if (length_ == 0)
00150 return npos;
00151
00152 size_type i = std::min(pos, length_ - 1);
00153 if (s.length_ == 0)
00154 return i;
00155
00156
00157 if (s.length_ == 1)
00158 return find_last_not_of(s.ptr_[0], pos);
00159
00160 bool lookup[UCHAR_MAX + 1] = { false };
00161 BuildLookupTable(s, lookup);
00162 for (; ; --i) {
00163 if (!lookup[static_cast<unsigned char>(ptr_[i])])
00164 return i;
00165 if (i == 0)
00166 break;
00167 }
00168 return npos;
00169 }
00170
00171 size_type StringPiece::find_last_not_of(char c, size_type pos) const {
00172 if (length_ == 0)
00173 return npos;
00174
00175 for (size_type i = std::min(pos, length_ - 1); ; --i) {
00176 if (ptr_[i] != c)
00177 return i;
00178 if (i == 0)
00179 break;
00180 }
00181 return npos;
00182 }
00183
00184 StringPiece StringPiece::substr(size_type pos, size_type n) const {
00185 if (pos > length_) pos = length_;
00186 if (n > length_ - pos) n = length_ - pos;
00187 return StringPiece(ptr_ + pos, n);
00188 }
00189
00190 const size_type StringPiece::npos = size_type(-1);
00191
00192 #endif // !HAVE_ICU