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