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