tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

string_piece.cc (5947B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
      3 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
      4 // Use of this source code is governed by a BSD-style license that can be
      5 // found in the LICENSE file.
      6 // Copied from strings/stringpiece.cc with modifications
      7 
      8 #include <algorithm>
      9 #include <ostream>
     10 
     11 #include "base/string_piece.h"
     12 
     13 typedef StringPiece::size_type size_type;
     14 
     15 std::ostream& operator<<(std::ostream& o, const StringPiece& piece) {
     16  o.write(piece.data(), static_cast<std::streamsize>(piece.size()));
     17  return o;
     18 }
     19 
     20 bool operator==(const StringPiece& x, const StringPiece& y) {
     21  if (x.size() != y.size()) return false;
     22 
     23  return StringPiece::wordmemcmp(x.data(), y.data(), x.size()) == 0;
     24 }
     25 
     26 void StringPiece::CopyToString(std::string* target) const {
     27  target->assign(!empty() ? data() : "", size());
     28 }
     29 
     30 void StringPiece::AppendToString(std::string* target) const {
     31  if (!empty()) target->append(data(), size());
     32 }
     33 
     34 size_type StringPiece::copy(char* buf, size_type n, size_type pos) const {
     35  size_type ret = std::min(length_ - pos, n);
     36  memcpy(buf, ptr_ + pos, ret);
     37  return ret;
     38 }
     39 
     40 size_type StringPiece::find(const StringPiece& s, size_type pos) const {
     41  if (pos > length_) return npos;
     42 
     43  const char* result =
     44      std::search(ptr_ + pos, ptr_ + length_, s.ptr_, s.ptr_ + s.length_);
     45  const size_type xpos = result - ptr_;
     46  return xpos + s.length_ <= length_ ? xpos : npos;
     47 }
     48 
     49 size_type StringPiece::find(char c, size_type pos) const {
     50  if (pos >= length_) return npos;
     51 
     52  const char* result = std::find(ptr_ + pos, ptr_ + length_, c);
     53  return result != ptr_ + length_ ? result - ptr_ : npos;
     54 }
     55 
     56 size_type StringPiece::rfind(const StringPiece& s, size_type pos) const {
     57  if (length_ < s.length_) return npos;
     58 
     59  if (s.empty()) return std::min(length_, pos);
     60 
     61  const char* last = ptr_ + std::min(length_ - s.length_, pos) + s.length_;
     62  const char* result = std::find_end(ptr_, last, s.ptr_, s.ptr_ + s.length_);
     63  return result != last ? result - ptr_ : npos;
     64 }
     65 
     66 size_type StringPiece::rfind(char c, size_type pos) const {
     67  if (length_ == 0) return npos;
     68 
     69  for (size_type i = std::min(pos, length_ - 1);; --i) {
     70    if (ptr_[i] == c) return i;
     71    if (i == 0) break;
     72  }
     73  return npos;
     74 }
     75 
     76 // For each character in characters_wanted, sets the index corresponding
     77 // to the ASCII code of that character to 1 in table.  This is used by
     78 // the find_.*_of methods below to tell whether or not a character is in
     79 // the lookup table in constant time.
     80 // The argument `table' must be an array that is large enough to hold all
     81 // the possible values of an unsigned char.  Thus it should be be declared
     82 // as follows:
     83 //   bool table[UCHAR_MAX + 1]
     84 static inline void BuildLookupTable(const StringPiece& characters_wanted,
     85                                    bool* table) {
     86  const size_type length = characters_wanted.length();
     87  const char* const data = characters_wanted.data();
     88  for (size_type i = 0; i < length; ++i) {
     89    table[static_cast<unsigned char>(data[i])] = true;
     90  }
     91 }
     92 
     93 size_type StringPiece::find_first_of(const StringPiece& s,
     94                                     size_type pos) const {
     95  if (length_ == 0 || s.length_ == 0) return npos;
     96 
     97  // Avoid the cost of BuildLookupTable() for a single-character search.
     98  if (s.length_ == 1) return find_first_of(s.ptr_[0], pos);
     99 
    100  bool lookup[UCHAR_MAX + 1] = {false};
    101  BuildLookupTable(s, lookup);
    102  for (size_type i = pos; i < length_; ++i) {
    103    if (lookup[static_cast<unsigned char>(ptr_[i])]) {
    104      return i;
    105    }
    106  }
    107  return npos;
    108 }
    109 
    110 size_type StringPiece::find_first_not_of(const StringPiece& s,
    111                                         size_type pos) const {
    112  if (length_ == 0) return npos;
    113 
    114  if (s.length_ == 0) return 0;
    115 
    116  // Avoid the cost of BuildLookupTable() for a single-character search.
    117  if (s.length_ == 1) return find_first_not_of(s.ptr_[0], pos);
    118 
    119  bool lookup[UCHAR_MAX + 1] = {false};
    120  BuildLookupTable(s, lookup);
    121  for (size_type i = pos; i < length_; ++i) {
    122    if (!lookup[static_cast<unsigned char>(ptr_[i])]) {
    123      return i;
    124    }
    125  }
    126  return npos;
    127 }
    128 
    129 size_type StringPiece::find_first_not_of(char c, size_type pos) const {
    130  if (length_ == 0) return npos;
    131 
    132  for (; pos < length_; ++pos) {
    133    if (ptr_[pos] != c) {
    134      return pos;
    135    }
    136  }
    137  return npos;
    138 }
    139 
    140 size_type StringPiece::find_last_of(const StringPiece& s, size_type pos) const {
    141  if (length_ == 0 || s.length_ == 0) return npos;
    142 
    143  // Avoid the cost of BuildLookupTable() for a single-character search.
    144  if (s.length_ == 1) return find_last_of(s.ptr_[0], pos);
    145 
    146  bool lookup[UCHAR_MAX + 1] = {false};
    147  BuildLookupTable(s, lookup);
    148  for (size_type i = std::min(pos, length_ - 1);; --i) {
    149    if (lookup[static_cast<unsigned char>(ptr_[i])]) return i;
    150    if (i == 0) break;
    151  }
    152  return npos;
    153 }
    154 
    155 size_type StringPiece::find_last_not_of(const StringPiece& s,
    156                                        size_type pos) const {
    157  if (length_ == 0) return npos;
    158 
    159  size_type i = std::min(pos, length_ - 1);
    160  if (s.length_ == 0) return i;
    161 
    162  // Avoid the cost of BuildLookupTable() for a single-character search.
    163  if (s.length_ == 1) return find_last_not_of(s.ptr_[0], pos);
    164 
    165  bool lookup[UCHAR_MAX + 1] = {false};
    166  BuildLookupTable(s, lookup);
    167  for (;; --i) {
    168    if (!lookup[static_cast<unsigned char>(ptr_[i])]) return i;
    169    if (i == 0) break;
    170  }
    171  return npos;
    172 }
    173 
    174 size_type StringPiece::find_last_not_of(char c, size_type pos) const {
    175  if (length_ == 0) return npos;
    176 
    177  for (size_type i = std::min(pos, length_ - 1);; --i) {
    178    if (ptr_[i] != c) return i;
    179    if (i == 0) break;
    180  }
    181  return npos;
    182 }
    183 
    184 StringPiece StringPiece::substr(size_type pos, size_type n) const {
    185  if (pos > length_) pos = length_;
    186  if (n > length_ - pos) n = length_ - pos;
    187  return StringPiece(ptr_ + pos, n);
    188 }
    189 
    190 const StringPiece::size_type StringPiece::npos = size_type(-1);