Home | History | Annotate | Download | only in kati
      1 // Copyright 2015 Google Inc. All rights reserved
      2 //
      3 // Licensed under the Apache License, Version 2.0 (the "License");
      4 // you may not use this file except in compliance with the License.
      5 // You may obtain a copy of the License at
      6 //
      7 //      http://www.apache.org/licenses/LICENSE-2.0
      8 //
      9 // Unless required by applicable law or agreed to in writing, software
     10 // distributed under the License is distributed on an "AS IS" BASIS,
     11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     12 // See the License for the specific language governing permissions and
     13 // limitations under the License.
     14 
     15 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
     16 // Use of this source code is governed by a BSD-style license that can be
     17 // found in the LICENSE file.
     18 // Copied from strings/stringpiece.cc with modifications
     19 
     20 // +build ignore
     21 
     22 #include <ctype.h>
     23 #include <limits.h>
     24 #include <stdint.h>
     25 
     26 #include <algorithm>
     27 #include <ostream>
     28 
     29 #include "string_piece.h"
     30 
     31 typedef StringPiece::size_type size_type;
     32 
     33 bool operator==(const StringPiece& x, const StringPiece& y) {
     34   if (x.size() != y.size())
     35     return false;
     36   size_t len = x.size();
     37   if (len >= sizeof(uint64_t)) {
     38     len -= sizeof(uint64_t);
     39     uint64_t xt = *reinterpret_cast<const uint64_t*>(x.data() + len);
     40     uint64_t yt = *reinterpret_cast<const uint64_t*>(y.data() + len);
     41     if (xt != yt)
     42       return false;
     43   }
     44   return StringPiece::wordmemcmp(x.data(), y.data(), len) == 0;
     45 }
     46 
     47 void StringPiece::CopyToString(std::string* target) const {
     48   target->assign(!empty() ? data() : "", size());
     49 }
     50 
     51 void StringPiece::AppendToString(std::string* target) const {
     52   if (!empty())
     53     target->append(data(), size());
     54 }
     55 
     56 size_type StringPiece::copy(char* buf, size_type n, size_type pos) const {
     57   size_type ret = std::min(length_ - pos, n);
     58   memcpy(buf, ptr_ + pos, ret);
     59   return ret;
     60 }
     61 
     62 size_type StringPiece::find(const StringPiece& s, size_type pos) const {
     63   if (pos > length_)
     64     return npos;
     65 
     66   const char* result = std::search(ptr_ + pos, ptr_ + length_,
     67                                    s.ptr_, s.ptr_ + s.length_);
     68   const size_type xpos = result - ptr_;
     69   return xpos + s.length_ <= length_ ? xpos : npos;
     70 }
     71 
     72 size_type StringPiece::find(char c, size_type pos) const {
     73   if (pos >= length_)
     74     return npos;
     75 
     76   const char* result = std::find(ptr_ + pos, ptr_ + length_, c);
     77   return result != ptr_ + length_ ? static_cast<size_t>(result - ptr_) : npos;
     78 }
     79 
     80 size_type StringPiece::rfind(const StringPiece& s, size_type pos) const {
     81   if (length_ < s.length_)
     82     return npos;
     83 
     84   if (s.empty())
     85     return std::min(length_, pos);
     86 
     87   const char* last = ptr_ + std::min(length_ - s.length_, pos) + s.length_;
     88   const char* result = std::find_end(ptr_, last, s.ptr_, s.ptr_ + s.length_);
     89   return result != last ? static_cast<size_t>(result - ptr_) : npos;
     90 }
     91 
     92 size_type StringPiece::rfind(char c, size_type pos) const {
     93   if (length_ == 0)
     94     return npos;
     95 
     96   for (size_type i = std::min(pos, length_ - 1); ; --i) {
     97     if (ptr_[i] == c)
     98       return i;
     99     if (i == 0)
    100       break;
    101   }
    102   return npos;
    103 }
    104 
    105 // For each character in characters_wanted, sets the index corresponding
    106 // to the ASCII code of that character to 1 in table.  This is used by
    107 // the find_.*_of methods below to tell whether or not a character is in
    108 // the lookup table in constant time.
    109 // The argument `table' must be an array that is large enough to hold all
    110 // the possible values of an unsigned char.  Thus it should be be declared
    111 // as follows:
    112 //   bool table[UCHAR_MAX + 1]
    113 static inline void BuildLookupTable(const StringPiece& characters_wanted,
    114                                     bool* table) {
    115   const size_type length = characters_wanted.length();
    116   const char* const data = characters_wanted.data();
    117   for (size_type i = 0; i < length; ++i) {
    118     table[static_cast<unsigned char>(data[i])] = true;
    119   }
    120 }
    121 
    122 size_type StringPiece::find_first_of(const StringPiece& s,
    123                                      size_type pos) const {
    124   if (length_ == 0 || s.length_ == 0)
    125     return npos;
    126 
    127   // Avoid the cost of BuildLookupTable() for a single-character search.
    128   if (s.length_ == 1)
    129     return find_first_of(s.ptr_[0], pos);
    130 
    131   bool lookup[UCHAR_MAX + 1] = { false };
    132   BuildLookupTable(s, lookup);
    133   for (size_type i = pos; i < length_; ++i) {
    134     if (lookup[static_cast<unsigned char>(ptr_[i])]) {
    135       return i;
    136     }
    137   }
    138   return npos;
    139 }
    140 
    141 size_type StringPiece::find_first_not_of(const StringPiece& s,
    142                                          size_type pos) const {
    143   if (length_ == 0)
    144     return npos;
    145 
    146   if (s.length_ == 0)
    147     return 0;
    148 
    149   // Avoid the cost of BuildLookupTable() for a single-character search.
    150   if (s.length_ == 1)
    151     return find_first_not_of(s.ptr_[0], pos);
    152 
    153   bool lookup[UCHAR_MAX + 1] = { false };
    154   BuildLookupTable(s, lookup);
    155   for (size_type i = pos; i < length_; ++i) {
    156     if (!lookup[static_cast<unsigned char>(ptr_[i])]) {
    157       return i;
    158     }
    159   }
    160   return npos;
    161 }
    162 
    163 size_type StringPiece::find_first_not_of(char c, size_type pos) const {
    164   if (length_ == 0)
    165     return npos;
    166 
    167   for (; pos < length_; ++pos) {
    168     if (ptr_[pos] != c) {
    169       return pos;
    170     }
    171   }
    172   return npos;
    173 }
    174 
    175 size_type StringPiece::find_last_of(const StringPiece& s, size_type pos) const {
    176   if (length_ == 0 || s.length_ == 0)
    177     return npos;
    178 
    179   // Avoid the cost of BuildLookupTable() for a single-character search.
    180   if (s.length_ == 1)
    181     return find_last_of(s.ptr_[0], pos);
    182 
    183   bool lookup[UCHAR_MAX + 1] = { false };
    184   BuildLookupTable(s, lookup);
    185   for (size_type i = std::min(pos, length_ - 1); ; --i) {
    186     if (lookup[static_cast<unsigned char>(ptr_[i])])
    187       return i;
    188     if (i == 0)
    189       break;
    190   }
    191   return npos;
    192 }
    193 
    194 size_type StringPiece::find_last_not_of(const StringPiece& s,
    195                                         size_type pos) const {
    196   if (length_ == 0)
    197     return npos;
    198 
    199   size_type i = std::min(pos, length_ - 1);
    200   if (s.length_ == 0)
    201     return i;
    202 
    203   // Avoid the cost of BuildLookupTable() for a single-character search.
    204   if (s.length_ == 1)
    205     return find_last_not_of(s.ptr_[0], pos);
    206 
    207   bool lookup[UCHAR_MAX + 1] = { false };
    208   BuildLookupTable(s, lookup);
    209   for (; ; --i) {
    210     if (!lookup[static_cast<unsigned char>(ptr_[i])])
    211       return i;
    212     if (i == 0)
    213       break;
    214   }
    215   return npos;
    216 }
    217 
    218 size_type StringPiece::find_last_not_of(char c, size_type pos) const {
    219   if (length_ == 0)
    220     return npos;
    221 
    222   for (size_type i = std::min(pos, length_ - 1); ; --i) {
    223     if (ptr_[i] != c)
    224       return i;
    225     if (i == 0)
    226       break;
    227   }
    228   return npos;
    229 }
    230 
    231 StringPiece StringPiece::substr(size_type pos, size_type n) const {
    232   if (pos > length_) pos = length_;
    233   if (n > length_ - pos) n = length_ - pos;
    234   return StringPiece(ptr_ + pos, n);
    235 }
    236 
    237 const StringPiece::size_type StringPiece::npos = size_type(-1);
    238