11767c5feSopenharmony_ci// Copyright (c) 2011 The Chromium Authors. All rights reserved. 21767c5feSopenharmony_ci// Use of this source code is governed by a BSD-style license that can be 31767c5feSopenharmony_ci// found in the LICENSE file. 41767c5feSopenharmony_ci// Copied from strings/stringpiece.h with modifications 51767c5feSopenharmony_ci// 61767c5feSopenharmony_ci// A string-like object that points to a sized piece of memory. 71767c5feSopenharmony_ci// 81767c5feSopenharmony_ci// Functions or methods may use const StringPiece& parameters to accept either 91767c5feSopenharmony_ci// a "const char*" or a "string" value that will be implicitly converted to 101767c5feSopenharmony_ci// a StringPiece. The implicit conversion means that it is often appropriate 111767c5feSopenharmony_ci// to include this .h file in other files rather than forward-declaring 121767c5feSopenharmony_ci// StringPiece as would be appropriate for most other Google classes. 131767c5feSopenharmony_ci// 141767c5feSopenharmony_ci// Systematic usage of StringPiece is encouraged as it will reduce unnecessary 151767c5feSopenharmony_ci// conversions from "const char*" to "string" and back again. 161767c5feSopenharmony_ci// 171767c5feSopenharmony_ci 181767c5feSopenharmony_ci#ifndef I18N_PHONENUMBERS_BASE_STRINGS_STRING_PIECE_H_ 191767c5feSopenharmony_ci#define I18N_PHONENUMBERS_BASE_STRINGS_STRING_PIECE_H_ 201767c5feSopenharmony_ci#pragma once 211767c5feSopenharmony_ci 221767c5feSopenharmony_ci#include <string> 231767c5feSopenharmony_ci 241767c5feSopenharmony_ci#include "phonenumbers/base/basictypes.h" 251767c5feSopenharmony_ci 261767c5feSopenharmony_cinamespace i18n { 271767c5feSopenharmony_cinamespace phonenumbers { 281767c5feSopenharmony_ci 291767c5feSopenharmony_ciclass StringPiece { 301767c5feSopenharmony_ci public: 311767c5feSopenharmony_ci // standard STL container boilerplate 321767c5feSopenharmony_ci typedef size_t size_type; 331767c5feSopenharmony_ci typedef char value_type; 341767c5feSopenharmony_ci typedef const char* pointer; 351767c5feSopenharmony_ci typedef const char& reference; 361767c5feSopenharmony_ci typedef const char& const_reference; 371767c5feSopenharmony_ci typedef ptrdiff_t difference_type; 381767c5feSopenharmony_ci typedef const char* const_iterator; 391767c5feSopenharmony_ci typedef const char* iterator; 401767c5feSopenharmony_ci typedef std::reverse_iterator<const_iterator> const_reverse_iterator; 411767c5feSopenharmony_ci typedef std::reverse_iterator<iterator> reverse_iterator; 421767c5feSopenharmony_ci 431767c5feSopenharmony_ci static const size_type npos; 441767c5feSopenharmony_ci 451767c5feSopenharmony_ci public: 461767c5feSopenharmony_ci // We provide non-explicit singleton constructors so users can pass 471767c5feSopenharmony_ci // in a "const char*" or a "string" wherever a "StringPiece" is 481767c5feSopenharmony_ci // expected. 491767c5feSopenharmony_ci StringPiece() : ptr_(NULL), length_(0) { } 501767c5feSopenharmony_ci StringPiece(const char* str) 511767c5feSopenharmony_ci : ptr_(str), length_((str == NULL) ? 0 : strlen(str)) { } 521767c5feSopenharmony_ci StringPiece(const std::string& str) 531767c5feSopenharmony_ci : ptr_(str.data()), length_(str.size()) { } 541767c5feSopenharmony_ci StringPiece(const char* offset, size_type len) 551767c5feSopenharmony_ci : ptr_(offset), length_(len) { } 561767c5feSopenharmony_ci 571767c5feSopenharmony_ci // data() may return a pointer to a buffer with embedded NULs, and the 581767c5feSopenharmony_ci // returned buffer may or may not be null terminated. Therefore it is 591767c5feSopenharmony_ci // typically a mistake to pass data() to a routine that expects a NUL 601767c5feSopenharmony_ci // terminated string. 611767c5feSopenharmony_ci const char* data() const { return ptr_; } 621767c5feSopenharmony_ci size_type size() const { return length_; } 631767c5feSopenharmony_ci size_type length() const { return length_; } 641767c5feSopenharmony_ci bool empty() const { return length_ == 0; } 651767c5feSopenharmony_ci 661767c5feSopenharmony_ci void clear() { 671767c5feSopenharmony_ci ptr_ = NULL; 681767c5feSopenharmony_ci length_ = 0; 691767c5feSopenharmony_ci } 701767c5feSopenharmony_ci void set(const char* data, size_type len) { 711767c5feSopenharmony_ci ptr_ = data; 721767c5feSopenharmony_ci length_ = len; 731767c5feSopenharmony_ci } 741767c5feSopenharmony_ci void set(const char* str) { 751767c5feSopenharmony_ci ptr_ = str; 761767c5feSopenharmony_ci length_ = str ? strlen(str) : 0; 771767c5feSopenharmony_ci } 781767c5feSopenharmony_ci void set(const void* data, size_type len) { 791767c5feSopenharmony_ci ptr_ = reinterpret_cast<const char*>(data); 801767c5feSopenharmony_ci length_ = len; 811767c5feSopenharmony_ci } 821767c5feSopenharmony_ci 831767c5feSopenharmony_ci char operator[](size_type i) const { return ptr_[i]; } 841767c5feSopenharmony_ci 851767c5feSopenharmony_ci void remove_prefix(size_type n) { 861767c5feSopenharmony_ci ptr_ += n; 871767c5feSopenharmony_ci length_ -= n; 881767c5feSopenharmony_ci } 891767c5feSopenharmony_ci 901767c5feSopenharmony_ci void remove_suffix(size_type n) { 911767c5feSopenharmony_ci length_ -= n; 921767c5feSopenharmony_ci } 931767c5feSopenharmony_ci 941767c5feSopenharmony_ci int compare(const StringPiece& x) const { 951767c5feSopenharmony_ci int r = wordmemcmp( 961767c5feSopenharmony_ci ptr_, x.ptr_, (length_ < x.length_ ? length_ : x.length_)); 971767c5feSopenharmony_ci if (r == 0) { 981767c5feSopenharmony_ci if (length_ < x.length_) r = -1; 991767c5feSopenharmony_ci else if (length_ > x.length_) r = +1; 1001767c5feSopenharmony_ci } 1011767c5feSopenharmony_ci return r; 1021767c5feSopenharmony_ci } 1031767c5feSopenharmony_ci 1041767c5feSopenharmony_ci std::string as_string() const { 1051767c5feSopenharmony_ci // std::string doesn't like to take a NULL pointer even with a 0 size. 1061767c5feSopenharmony_ci return std::string(!empty() ? data() : "", size()); 1071767c5feSopenharmony_ci } 1081767c5feSopenharmony_ci 1091767c5feSopenharmony_ci void CopyToString(std::string* target) const; 1101767c5feSopenharmony_ci void AppendToString(std::string* target) const; 1111767c5feSopenharmony_ci 1121767c5feSopenharmony_ci // Does "this" start with "x" 1131767c5feSopenharmony_ci bool starts_with(const StringPiece& x) const { 1141767c5feSopenharmony_ci return ((length_ >= x.length_) && 1151767c5feSopenharmony_ci (wordmemcmp(ptr_, x.ptr_, x.length_) == 0)); 1161767c5feSopenharmony_ci } 1171767c5feSopenharmony_ci 1181767c5feSopenharmony_ci // Does "this" end with "x" 1191767c5feSopenharmony_ci bool ends_with(const StringPiece& x) const { 1201767c5feSopenharmony_ci return ((length_ >= x.length_) && 1211767c5feSopenharmony_ci (wordmemcmp(ptr_ + (length_-x.length_), x.ptr_, x.length_) == 0)); 1221767c5feSopenharmony_ci } 1231767c5feSopenharmony_ci 1241767c5feSopenharmony_ci iterator begin() const { return ptr_; } 1251767c5feSopenharmony_ci iterator end() const { return ptr_ + length_; } 1261767c5feSopenharmony_ci const_reverse_iterator rbegin() const { 1271767c5feSopenharmony_ci return const_reverse_iterator(ptr_ + length_); 1281767c5feSopenharmony_ci } 1291767c5feSopenharmony_ci const_reverse_iterator rend() const { 1301767c5feSopenharmony_ci return const_reverse_iterator(ptr_); 1311767c5feSopenharmony_ci } 1321767c5feSopenharmony_ci 1331767c5feSopenharmony_ci size_type max_size() const { return length_; } 1341767c5feSopenharmony_ci size_type capacity() const { return length_; } 1351767c5feSopenharmony_ci 1361767c5feSopenharmony_ci size_type copy(char* buf, size_type n, size_type pos = 0) const; 1371767c5feSopenharmony_ci 1381767c5feSopenharmony_ci size_type find(const StringPiece& s, size_type pos = 0) const; 1391767c5feSopenharmony_ci size_type find(char c, size_type pos = 0) const; 1401767c5feSopenharmony_ci size_type rfind(const StringPiece& s, size_type pos = npos) const; 1411767c5feSopenharmony_ci size_type rfind(char c, size_type pos = npos) const; 1421767c5feSopenharmony_ci 1431767c5feSopenharmony_ci size_type find_first_of(const StringPiece& s, size_type pos = 0) const; 1441767c5feSopenharmony_ci size_type find_first_of(char c, size_type pos = 0) const { 1451767c5feSopenharmony_ci return find(c, pos); 1461767c5feSopenharmony_ci } 1471767c5feSopenharmony_ci size_type find_first_not_of(const StringPiece& s, size_type pos = 0) const; 1481767c5feSopenharmony_ci size_type find_first_not_of(char c, size_type pos = 0) const; 1491767c5feSopenharmony_ci size_type find_last_of(const StringPiece& s, size_type pos = npos) const; 1501767c5feSopenharmony_ci size_type find_last_of(char c, size_type pos = npos) const { 1511767c5feSopenharmony_ci return rfind(c, pos); 1521767c5feSopenharmony_ci } 1531767c5feSopenharmony_ci size_type find_last_not_of(const StringPiece& s, size_type pos = npos) const; 1541767c5feSopenharmony_ci size_type find_last_not_of(char c, size_type pos = npos) const; 1551767c5feSopenharmony_ci 1561767c5feSopenharmony_ci StringPiece substr(size_type pos, size_type n = npos) const; 1571767c5feSopenharmony_ci 1581767c5feSopenharmony_ci static int wordmemcmp(const char* p, const char* p2, size_type N) { 1591767c5feSopenharmony_ci return memcmp(p, p2, N); 1601767c5feSopenharmony_ci } 1611767c5feSopenharmony_ci 1621767c5feSopenharmony_ci private: 1631767c5feSopenharmony_ci const char* ptr_; 1641767c5feSopenharmony_ci size_type length_; 1651767c5feSopenharmony_ci}; 1661767c5feSopenharmony_ci 1671767c5feSopenharmony_cibool operator==(const StringPiece& x, const StringPiece& y); 1681767c5feSopenharmony_ci 1691767c5feSopenharmony_ciinline bool operator!=(const StringPiece& x, const StringPiece& y) { 1701767c5feSopenharmony_ci return !(x == y); 1711767c5feSopenharmony_ci} 1721767c5feSopenharmony_ci 1731767c5feSopenharmony_ciinline bool operator<(const StringPiece& x, const StringPiece& y) { 1741767c5feSopenharmony_ci const int r = StringPiece::wordmemcmp( 1751767c5feSopenharmony_ci x.data(), y.data(), (x.size() < y.size() ? x.size() : y.size())); 1761767c5feSopenharmony_ci return ((r < 0) || ((r == 0) && (x.size() < y.size()))); 1771767c5feSopenharmony_ci} 1781767c5feSopenharmony_ci 1791767c5feSopenharmony_ciinline bool operator>(const StringPiece& x, const StringPiece& y) { 1801767c5feSopenharmony_ci return y < x; 1811767c5feSopenharmony_ci} 1821767c5feSopenharmony_ci 1831767c5feSopenharmony_ciinline bool operator<=(const StringPiece& x, const StringPiece& y) { 1841767c5feSopenharmony_ci return !(x > y); 1851767c5feSopenharmony_ci} 1861767c5feSopenharmony_ci 1871767c5feSopenharmony_ciinline bool operator>=(const StringPiece& x, const StringPiece& y) { 1881767c5feSopenharmony_ci return !(x < y); 1891767c5feSopenharmony_ci} 1901767c5feSopenharmony_ci 1911767c5feSopenharmony_ci} // namespace phonenumbers 1921767c5feSopenharmony_ci} // namespace i18n 1931767c5feSopenharmony_ci 1941767c5feSopenharmony_ci#endif // I18N_PHONENUMBERS_BASE_STRINGS_STRING_PIECE_H_ 195