Home | History | Annotate | Download | only in base
      1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 // Copied from strings/stringpiece.h with modifications
      5 //
      6 // A string-like object that points to a sized piece of memory.
      7 //
      8 // Functions or methods may use const StringPiece& parameters to accept either
      9 // a "const char*" or a "string" value that will be implicitly converted to
     10 // a StringPiece.  The implicit conversion means that it is often appropriate
     11 // to include this .h file in other files rather than forward-declaring
     12 // StringPiece as would be appropriate for most other Google classes.
     13 //
     14 // Systematic usage of StringPiece is encouraged as it will reduce unnecessary
     15 // conversions from "const char*" to "string" and back again.
     16 //
     17 
     18 #ifndef BASE_STRING_PIECE_H_
     19 #define BASE_STRING_PIECE_H_
     20 #pragma once
     21 
     22 #include <string>
     23 
     24 #include "base/base_api.h"
     25 #include "base/basictypes.h"
     26 
     27 namespace base {
     28 
     29 class BASE_API StringPiece {
     30  public:
     31   // standard STL container boilerplate
     32   typedef size_t size_type;
     33   typedef char value_type;
     34   typedef const char* pointer;
     35   typedef const char& reference;
     36   typedef const char& const_reference;
     37   typedef ptrdiff_t difference_type;
     38   typedef const char* const_iterator;
     39   typedef const char* iterator;
     40   typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
     41   typedef std::reverse_iterator<iterator> reverse_iterator;
     42 
     43   static const size_type npos;
     44 
     45  public:
     46   // We provide non-explicit singleton constructors so users can pass
     47   // in a "const char*" or a "string" wherever a "StringPiece" is
     48   // expected.
     49   StringPiece() : ptr_(NULL), length_(0) { }
     50   StringPiece(const char* str)
     51     : ptr_(str), length_((str == NULL) ? 0 : strlen(str)) { }
     52   StringPiece(const std::string& str)
     53     : ptr_(str.data()), length_(str.size()) { }
     54   StringPiece(const char* offset, size_type len)
     55     : ptr_(offset), length_(len) { }
     56 
     57   // data() may return a pointer to a buffer with embedded NULs, and the
     58   // returned buffer may or may not be null terminated.  Therefore it is
     59   // typically a mistake to pass data() to a routine that expects a NUL
     60   // terminated string.
     61   const char* data() const { return ptr_; }
     62   size_type size() const { return length_; }
     63   size_type length() const { return length_; }
     64   bool empty() const { return length_ == 0; }
     65 
     66   void clear() {
     67     ptr_ = NULL;
     68     length_ = 0;
     69   }
     70   void set(const char* data, size_type len) {
     71     ptr_ = data;
     72     length_ = len;
     73   }
     74   void set(const char* str) {
     75     ptr_ = str;
     76     length_ = str ? strlen(str) : 0;
     77   }
     78   void set(const void* data, size_type len) {
     79     ptr_ = reinterpret_cast<const char*>(data);
     80     length_ = len;
     81   }
     82 
     83   char operator[](size_type i) const { return ptr_[i]; }
     84 
     85   void remove_prefix(size_type n) {
     86     ptr_ += n;
     87     length_ -= n;
     88   }
     89 
     90   void remove_suffix(size_type n) {
     91     length_ -= n;
     92   }
     93 
     94   int compare(const StringPiece& x) const {
     95     int r = wordmemcmp(
     96         ptr_, x.ptr_, (length_ < x.length_ ? length_ : x.length_));
     97     if (r == 0) {
     98       if (length_ < x.length_) r = -1;
     99       else if (length_ > x.length_) r = +1;
    100     }
    101     return r;
    102   }
    103 
    104   std::string as_string() const {
    105     // std::string doesn't like to take a NULL pointer even with a 0 size.
    106     return std::string(!empty() ? data() : "", size());
    107   }
    108 
    109   void CopyToString(std::string* target) const;
    110   void AppendToString(std::string* target) const;
    111 
    112   // Does "this" start with "x"
    113   bool starts_with(const StringPiece& x) const {
    114     return ((length_ >= x.length_) &&
    115             (wordmemcmp(ptr_, x.ptr_, x.length_) == 0));
    116   }
    117 
    118   // Does "this" end with "x"
    119   bool ends_with(const StringPiece& x) const {
    120     return ((length_ >= x.length_) &&
    121             (wordmemcmp(ptr_ + (length_-x.length_), x.ptr_, x.length_) == 0));
    122   }
    123 
    124   iterator begin() const { return ptr_; }
    125   iterator end() const { return ptr_ + length_; }
    126   const_reverse_iterator rbegin() const {
    127     return const_reverse_iterator(ptr_ + length_);
    128   }
    129   const_reverse_iterator rend() const {
    130     return const_reverse_iterator(ptr_);
    131   }
    132 
    133   size_type max_size() const { return length_; }
    134   size_type capacity() const { return length_; }
    135 
    136   size_type copy(char* buf, size_type n, size_type pos = 0) const;
    137 
    138   size_type find(const StringPiece& s, size_type pos = 0) const;
    139   size_type find(char c, size_type pos = 0) const;
    140   size_type rfind(const StringPiece& s, size_type pos = npos) const;
    141   size_type rfind(char c, size_type pos = npos) const;
    142 
    143   size_type find_first_of(const StringPiece& s, size_type pos = 0) const;
    144   size_type find_first_of(char c, size_type pos = 0) const {
    145     return find(c, pos);
    146   }
    147   size_type find_first_not_of(const StringPiece& s, size_type pos = 0) const;
    148   size_type find_first_not_of(char c, size_type pos = 0) const;
    149   size_type find_last_of(const StringPiece& s, size_type pos = npos) const;
    150   size_type find_last_of(char c, size_type pos = npos) const {
    151     return rfind(c, pos);
    152   }
    153   size_type find_last_not_of(const StringPiece& s, size_type pos = npos) const;
    154   size_type find_last_not_of(char c, size_type pos = npos) const;
    155 
    156   StringPiece substr(size_type pos, size_type n = npos) const;
    157 
    158   static int wordmemcmp(const char* p, const char* p2, size_type N) {
    159     return memcmp(p, p2, N);
    160   }
    161 
    162  private:
    163   const char*   ptr_;
    164   size_type     length_;
    165 };
    166 
    167 BASE_API bool operator==(const StringPiece& x, const StringPiece& y);
    168 
    169 inline bool operator!=(const StringPiece& x, const StringPiece& y) {
    170   return !(x == y);
    171 }
    172 
    173 inline bool operator<(const StringPiece& x, const StringPiece& y) {
    174   const int r = StringPiece::wordmemcmp(
    175       x.data(), y.data(), (x.size() < y.size() ? x.size() : y.size()));
    176   return ((r < 0) || ((r == 0) && (x.size() < y.size())));
    177 }
    178 
    179 inline bool operator>(const StringPiece& x, const StringPiece& y) {
    180   return y < x;
    181 }
    182 
    183 inline bool operator<=(const StringPiece& x, const StringPiece& y) {
    184   return !(x > y);
    185 }
    186 
    187 inline bool operator>=(const StringPiece& x, const StringPiece& y) {
    188   return !(x < y);
    189 }
    190 
    191 }  // namespace base
    192 
    193 #endif  // BASE_STRING_PIECE_H_
    194