You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
224 lines
7.0 KiB
224 lines
7.0 KiB
// Copyright 2015 Google Inc. All rights reserved |
|
// |
|
// Licensed under the Apache License, Version 2.0 (the "License"); |
|
// you may not use this file except in compliance with the License. |
|
// You may obtain a copy of the License at |
|
// |
|
// http://www.apache.org/licenses/LICENSE-2.0 |
|
// |
|
// Unless required by applicable law or agreed to in writing, software |
|
// distributed under the License is distributed on an "AS IS" BASIS, |
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
// See the License for the specific language governing permissions and |
|
// limitations under the License. |
|
|
|
// Copyright (c) 2011 The Chromium Authors. All rights reserved. |
|
// Use of this source code is governed by a BSD-style license that can be |
|
// found in the LICENSE file. |
|
// Copied from strings/stringpiece.h with modifications |
|
// |
|
// A string-like object that points to a sized piece of memory. |
|
// |
|
// Functions or methods may use const StringPiece& parameters to accept either |
|
// a "const char*" or a "string" value that will be implicitly converted to |
|
// a StringPiece. The implicit conversion means that it is often appropriate |
|
// to include this .h file in other files rather than forward-declaring |
|
// StringPiece as would be appropriate for most other Google classes. |
|
// |
|
// Systematic usage of StringPiece is encouraged as it will reduce unnecessary |
|
// conversions from "const char*" to "string" and back again. |
|
// |
|
|
|
#ifndef BASE_STRING_PIECE_H_ |
|
#define BASE_STRING_PIECE_H_ |
|
#pragma once |
|
|
|
#include <stddef.h> |
|
#include <string.h> |
|
|
|
#include <string> |
|
|
|
//#include "base/base_api.h" |
|
//#include "base/basictypes.h" |
|
|
|
class StringPiece { |
|
public: |
|
// standard STL container boilerplate |
|
typedef size_t size_type; |
|
typedef char value_type; |
|
typedef const char* pointer; |
|
typedef const char& reference; |
|
typedef const char& const_reference; |
|
typedef ptrdiff_t difference_type; |
|
typedef const char* const_iterator; |
|
typedef const char* iterator; |
|
typedef std::reverse_iterator<const_iterator> const_reverse_iterator; |
|
typedef std::reverse_iterator<iterator> reverse_iterator; |
|
|
|
static const size_type npos; |
|
|
|
public: |
|
// We provide non-explicit singleton constructors so users can pass |
|
// in a "const char*" or a "string" wherever a "StringPiece" is |
|
// expected. |
|
StringPiece() : ptr_(NULL), length_(0) {} |
|
StringPiece(const char* str) |
|
: ptr_(str), length_((str == NULL) ? 0 : strlen(str)) {} |
|
StringPiece(const std::string& str) : ptr_(str.data()), length_(str.size()) {} |
|
StringPiece(const std::string&& str) |
|
: ptr_(str.data()), length_(str.size()) {} |
|
StringPiece(const char* offset, size_type len) : ptr_(offset), length_(len) {} |
|
|
|
// data() may return a pointer to a buffer with embedded NULs, and the |
|
// returned buffer may or may not be null terminated. Therefore it is |
|
// typically a mistake to pass data() to a routine that expects a NUL |
|
// terminated string. |
|
const char* data() const { return ptr_; } |
|
size_type size() const { return length_; } |
|
size_type length() const { return length_; } |
|
bool empty() const { return length_ == 0; } |
|
|
|
void clear() { |
|
ptr_ = NULL; |
|
length_ = 0; |
|
} |
|
void set(const char* data, size_type len) { |
|
ptr_ = data; |
|
length_ = len; |
|
} |
|
void set(const char* str) { |
|
ptr_ = str; |
|
length_ = str ? strlen(str) : 0; |
|
} |
|
void set(const void* data, size_type len) { |
|
ptr_ = reinterpret_cast<const char*>(data); |
|
length_ = len; |
|
} |
|
|
|
char operator[](size_type i) const { return ptr_[i]; } |
|
|
|
void remove_prefix(size_type n) { |
|
ptr_ += n; |
|
length_ -= n; |
|
} |
|
|
|
void remove_suffix(size_type n) { length_ -= n; } |
|
|
|
int compare(const StringPiece& x) const { |
|
int r = |
|
wordmemcmp(ptr_, x.ptr_, (length_ < x.length_ ? length_ : x.length_)); |
|
if (r == 0) { |
|
if (length_ < x.length_) |
|
r = -1; |
|
else if (length_ > x.length_) |
|
r = +1; |
|
} |
|
return r; |
|
} |
|
|
|
std::string as_string() const { |
|
// std::string doesn't like to take a NULL pointer even with a 0 size. |
|
return std::string(!empty() ? data() : "", size()); |
|
} |
|
|
|
void CopyToString(std::string* target) const; |
|
void AppendToString(std::string* target) const; |
|
|
|
// Does "this" start with "x" |
|
bool starts_with(const StringPiece& x) const { |
|
return ((length_ >= x.length_) && |
|
(wordmemcmp(ptr_, x.ptr_, x.length_) == 0)); |
|
} |
|
|
|
// Does "this" end with "x" |
|
bool ends_with(const StringPiece& x) const { |
|
return ((length_ >= x.length_) && |
|
(wordmemcmp(ptr_ + (length_ - x.length_), x.ptr_, x.length_) == 0)); |
|
} |
|
|
|
iterator begin() const { return ptr_; } |
|
iterator end() const { return ptr_ + length_; } |
|
const_reverse_iterator rbegin() const { |
|
return const_reverse_iterator(ptr_ + length_); |
|
} |
|
const_reverse_iterator rend() const { return const_reverse_iterator(ptr_); } |
|
|
|
size_type max_size() const { return length_; } |
|
size_type capacity() const { return length_; } |
|
|
|
size_type copy(char* buf, size_type n, size_type pos = 0) const; |
|
|
|
size_type find(const StringPiece& s, size_type pos = 0) const; |
|
size_type find(char c, size_type pos = 0) const; |
|
size_type rfind(const StringPiece& s, size_type pos = npos) const; |
|
size_type rfind(char c, size_type pos = npos) const; |
|
|
|
size_type find_first_of(const StringPiece& s, size_type pos = 0) const; |
|
size_type find_first_of(char c, size_type pos = 0) const { |
|
return find(c, pos); |
|
} |
|
size_type find_first_not_of(const StringPiece& s, size_type pos = 0) const; |
|
size_type find_first_not_of(char c, size_type pos = 0) const; |
|
size_type find_last_of(const StringPiece& s, size_type pos = npos) const; |
|
size_type find_last_of(char c, size_type pos = npos) const { |
|
return rfind(c, pos); |
|
} |
|
size_type find_last_not_of(const StringPiece& s, size_type pos = npos) const; |
|
size_type find_last_not_of(char c, size_type pos = npos) const; |
|
|
|
StringPiece substr(size_type pos, size_type n = npos) const; |
|
|
|
static int wordmemcmp(const char* p, const char* p2, size_type N) { |
|
return memcmp(p, p2, N); |
|
} |
|
|
|
// kati specific functions will follow. |
|
|
|
char get(size_type i) const { return i < length_ ? ptr_[i] : 0; } |
|
|
|
private: |
|
const char* ptr_; |
|
size_type length_; |
|
}; |
|
|
|
bool operator==(const StringPiece& x, const StringPiece& y); |
|
|
|
inline bool operator!=(const StringPiece& x, const StringPiece& y) { |
|
return !(x == y); |
|
} |
|
|
|
inline bool operator<(const StringPiece& x, const StringPiece& y) { |
|
const int r = StringPiece::wordmemcmp( |
|
x.data(), y.data(), (x.size() < y.size() ? x.size() : y.size())); |
|
return ((r < 0) || ((r == 0) && (x.size() < y.size()))); |
|
} |
|
|
|
inline bool operator>(const StringPiece& x, const StringPiece& y) { |
|
return y < x; |
|
} |
|
|
|
inline bool operator<=(const StringPiece& x, const StringPiece& y) { |
|
return !(x > y); |
|
} |
|
|
|
inline bool operator>=(const StringPiece& x, const StringPiece& y) { |
|
return !(x < y); |
|
} |
|
|
|
namespace std { |
|
template <> |
|
struct hash<StringPiece> { |
|
size_t operator()(const StringPiece& s) const { |
|
size_t result = 0; |
|
for (char c : s) { |
|
result = (result * 131) + c; |
|
} |
|
return result; |
|
} |
|
}; |
|
|
|
} // namespace std |
|
|
|
#define SPF(s) static_cast<int>((s).size()), (s).data() |
|
|
|
#endif // BASE_STRING_PIECE_H_
|
|
|