Line data Source code
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 0 : MOZ_IMPLICIT StringPiece(const char* str)
43 0 : : ptr_(str), length_((str == NULL) ? 0 : strlen(str)) { }
44 13 : MOZ_IMPLICIT StringPiece(const std::string& str)
45 13 : : ptr_(str.data()), length_(str.size()) { }
46 0 : StringPiece(const char* offset, size_type len)
47 0 : : ptr_(offset), length_(len) { }
48 :
49 : // data() may return a pointer to a buffer with embedded NULs, and the
50 : // returned buffer may or may not be null terminated. Therefore it is
51 : // typically a mistake to pass data() to a routine that expects a NUL
52 : // terminated string.
53 0 : const char* data() const { return ptr_; }
54 0 : size_type size() const { return length_; }
55 26 : size_type length() const { return length_; }
56 0 : bool empty() const { return length_ == 0; }
57 :
58 : void clear() { ptr_ = NULL; length_ = 0; }
59 : void set(const char* aData, size_type aLen) { ptr_ = aData; length_ = aLen; }
60 : void set(const char* str) {
61 : ptr_ = str;
62 : length_ = str ? strlen(str) : 0;
63 : }
64 : void set(const void* aData, size_type aLen) {
65 : ptr_ = reinterpret_cast<const char*>(aData);
66 : length_ = aLen;
67 : }
68 :
69 0 : char operator[](size_type i) const { return ptr_[i]; }
70 :
71 : void remove_prefix(size_type n) {
72 : ptr_ += n;
73 : length_ -= n;
74 : }
75 :
76 : void remove_suffix(size_type n) {
77 : length_ -= n;
78 : }
79 :
80 : int compare(const StringPiece& x) const {
81 : int r = wordmemcmp(ptr_, x.ptr_, std::min(length_, x.length_));
82 : if (r == 0) {
83 : if (length_ < x.length_) r = -1;
84 : else if (length_ > x.length_) r = +1;
85 : }
86 : return r;
87 : }
88 :
89 : std::string as_string() const {
90 : // std::string doesn't like to take a NULL pointer even with a 0 size.
91 : return std::string(!empty() ? data() : "", size());
92 : }
93 :
94 : void CopyToString(std::string* target) const;
95 : void AppendToString(std::string* target) const;
96 :
97 : // Does "this" start with "x"
98 : bool starts_with(const StringPiece& x) const {
99 : return ((length_ >= x.length_) &&
100 : (wordmemcmp(ptr_, x.ptr_, x.length_) == 0));
101 : }
102 :
103 : // Does "this" end with "x"
104 : bool ends_with(const StringPiece& x) const {
105 : return ((length_ >= x.length_) &&
106 : (wordmemcmp(ptr_ + (length_-x.length_), x.ptr_, x.length_) == 0));
107 : }
108 :
109 : // standard STL container boilerplate
110 : typedef char value_type;
111 : typedef const char* pointer;
112 : typedef const char& reference;
113 : typedef const char& const_reference;
114 : typedef ptrdiff_t difference_type;
115 : static const size_type npos;
116 : typedef const char* const_iterator;
117 : typedef const char* iterator;
118 : typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
119 : typedef std::reverse_iterator<iterator> reverse_iterator;
120 : iterator begin() const { return ptr_; }
121 : iterator end() const { return ptr_ + length_; }
122 : const_reverse_iterator rbegin() const {
123 : return const_reverse_iterator(ptr_ + length_);
124 : }
125 : const_reverse_iterator rend() const {
126 : return const_reverse_iterator(ptr_);
127 : }
128 :
129 : size_type max_size() const { return length_; }
130 : size_type capacity() const { return length_; }
131 :
132 : size_type copy(char* buf, size_type n, size_type pos = 0) const;
133 :
134 : size_type find(const StringPiece& s, size_type pos = 0) const;
135 : size_type find(char c, size_type pos = 0) const;
136 : size_type rfind(const StringPiece& s, size_type pos = npos) const;
137 : size_type rfind(char c, size_type pos = npos) const;
138 :
139 : size_type find_first_of(const StringPiece& s, size_type pos = 0) const;
140 0 : size_type find_first_of(char c, size_type pos = 0) const {
141 0 : return find(c, pos);
142 : }
143 : size_type find_first_not_of(const StringPiece& s, size_type pos = 0) const;
144 : size_type find_first_not_of(char c, size_type pos = 0) const;
145 : size_type find_last_of(const StringPiece& s, size_type pos = npos) const;
146 0 : size_type find_last_of(char c, size_type pos = npos) const {
147 0 : return rfind(c, pos);
148 : }
149 : size_type find_last_not_of(const StringPiece& s, size_type pos = npos) const;
150 : size_type find_last_not_of(char c, size_type pos = npos) const;
151 :
152 : StringPiece substr(size_type pos, size_type n = npos) const;
153 :
154 0 : static int wordmemcmp(const char* p, const char* p2, size_type N) {
155 0 : return memcmp(p, p2, N);
156 : }
157 : };
158 :
159 : bool operator==(const ::StringPiece& x, const ::StringPiece& y);
160 :
161 : inline bool operator!=(const ::StringPiece& x, const ::StringPiece& y) {
162 : return !(x == y);
163 : }
164 :
165 : inline bool operator<(const ::StringPiece& x, const ::StringPiece& y) {
166 : const int r = ::StringPiece::wordmemcmp(x.data(), y.data(),
167 : std::min(x.size(), y.size()));
168 : return ((r < 0) || ((r == 0) && (x.size() < y.size())));
169 : }
170 :
171 : inline bool operator>(const ::StringPiece& x, const ::StringPiece& y) {
172 : return y < x;
173 : }
174 :
175 : inline bool operator<=(const ::StringPiece& x, const ::StringPiece& y) {
176 : return !(x > y);
177 : }
178 :
179 : inline bool operator>=(const ::StringPiece& x, const ::StringPiece& y) {
180 : return !(x < y);
181 : }
182 :
183 : // allow StringPiece to be logged (needed for unit testing).
184 : extern std::ostream& operator<<(std::ostream& o, const ::StringPiece& piece);
185 :
186 : #endif // BASE_STRING_PIECE_H_
|