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