michael@0: // Copyright (C) 2009-2013, International Business Machines michael@0: // Corporation and others. All Rights Reserved. michael@0: // michael@0: // Copyright 2001 and onwards Google Inc. michael@0: // Author: Sanjay Ghemawat michael@0: michael@0: // This code is a contribution of Google code, and the style used here is michael@0: // a compromise between the original Google code and the ICU coding guidelines. michael@0: // For example, data types are ICU-ified (size_t,int->int32_t), michael@0: // and API comments doxygen-ified, but function names and behavior are michael@0: // as in the original, if possible. michael@0: // Assertion-style error handling, not available in ICU, was changed to michael@0: // parameter "pinning" similar to UnicodeString. michael@0: // michael@0: // In addition, this is only a partial port of the original Google code, michael@0: // limited to what was needed so far. The (nearly) complete original code michael@0: // is in the ICU svn repository at icuhtml/trunk/design/strings/contrib michael@0: // (see ICU ticket 6765, r25517). michael@0: michael@0: #ifndef __STRINGPIECE_H__ michael@0: #define __STRINGPIECE_H__ michael@0: michael@0: /** michael@0: * \file michael@0: * \brief C++ API: StringPiece: Read-only byte string wrapper class. michael@0: */ michael@0: michael@0: #include "unicode/utypes.h" michael@0: #include "unicode/uobject.h" michael@0: #include "unicode/std_string.h" michael@0: michael@0: // Arghh! I wish C++ literals were "string". michael@0: michael@0: U_NAMESPACE_BEGIN michael@0: michael@0: /** michael@0: * A string-like object that points to a sized piece of memory. michael@0: * michael@0: * We provide non-explicit singleton constructors so users can pass michael@0: * in a "const char*" or a "string" wherever a "StringPiece" is michael@0: * expected. michael@0: * michael@0: * Functions or methods may use const StringPiece& parameters to accept either michael@0: * a "const char*" or a "string" value that will be implicitly converted to michael@0: * a StringPiece. michael@0: * michael@0: * Systematic usage of StringPiece is encouraged as it will reduce unnecessary michael@0: * conversions from "const char*" to "string" and back again. michael@0: * michael@0: * @stable ICU 4.2 michael@0: */ michael@0: class U_COMMON_API StringPiece : public UMemory { michael@0: private: michael@0: const char* ptr_; michael@0: int32_t length_; michael@0: michael@0: public: michael@0: /** michael@0: * Default constructor, creates an empty StringPiece. michael@0: * @stable ICU 4.2 michael@0: */ michael@0: StringPiece() : ptr_(NULL), length_(0) { } michael@0: /** michael@0: * Constructs from a NUL-terminated const char * pointer. michael@0: * @param str a NUL-terminated const char * pointer michael@0: * @stable ICU 4.2 michael@0: */ michael@0: StringPiece(const char* str); michael@0: #if U_HAVE_STD_STRING michael@0: /** michael@0: * Constructs from a std::string. michael@0: * @stable ICU 4.2 michael@0: */ michael@0: StringPiece(const std::string& str) michael@0: : ptr_(str.data()), length_(static_cast(str.size())) { } michael@0: #endif michael@0: /** michael@0: * Constructs from a const char * pointer and a specified length. michael@0: * @param offset a const char * pointer (need not be terminated) michael@0: * @param len the length of the string; must be non-negative michael@0: * @stable ICU 4.2 michael@0: */ michael@0: StringPiece(const char* offset, int32_t len) : ptr_(offset), length_(len) { } michael@0: /** michael@0: * Substring of another StringPiece. michael@0: * @param x the other StringPiece michael@0: * @param pos start position in x; must be non-negative and <= x.length(). michael@0: * @stable ICU 4.2 michael@0: */ michael@0: StringPiece(const StringPiece& x, int32_t pos); michael@0: /** michael@0: * Substring of another StringPiece. michael@0: * @param x the other StringPiece michael@0: * @param pos start position in x; must be non-negative and <= x.length(). michael@0: * @param len length of the substring; michael@0: * must be non-negative and will be pinned to at most x.length() - pos. michael@0: * @stable ICU 4.2 michael@0: */ michael@0: StringPiece(const StringPiece& x, int32_t pos, int32_t len); michael@0: michael@0: /** michael@0: * Returns the string pointer. May be NULL if it is empty. michael@0: * michael@0: * data() may return a pointer to a buffer with embedded NULs, and the michael@0: * returned buffer may or may not be null terminated. Therefore it is michael@0: * typically a mistake to pass data() to a routine that expects a NUL michael@0: * terminated string. michael@0: * @return the string pointer michael@0: * @stable ICU 4.2 michael@0: */ michael@0: const char* data() const { return ptr_; } michael@0: /** michael@0: * Returns the string length. Same as length(). michael@0: * @return the string length michael@0: * @stable ICU 4.2 michael@0: */ michael@0: int32_t size() const { return length_; } michael@0: /** michael@0: * Returns the string length. Same as size(). michael@0: * @return the string length michael@0: * @stable ICU 4.2 michael@0: */ michael@0: int32_t length() const { return length_; } michael@0: /** michael@0: * Returns whether the string is empty. michael@0: * @return TRUE if the string is empty michael@0: * @stable ICU 4.2 michael@0: */ michael@0: UBool empty() const { return length_ == 0; } michael@0: michael@0: /** michael@0: * Sets to an empty string. michael@0: * @stable ICU 4.2 michael@0: */ michael@0: void clear() { ptr_ = NULL; length_ = 0; } michael@0: michael@0: /** michael@0: * Reset the stringpiece to refer to new data. michael@0: * @param xdata pointer the new string data. Need not be nul terminated. michael@0: * @param len the length of the new data michael@0: * @stable ICU 4.8 michael@0: */ michael@0: void set(const char* xdata, int32_t len) { ptr_ = xdata; length_ = len; } michael@0: michael@0: /** michael@0: * Reset the stringpiece to refer to new data. michael@0: * @param str a pointer to a NUL-terminated string. michael@0: * @stable ICU 4.8 michael@0: */ michael@0: void set(const char* str); michael@0: michael@0: /** michael@0: * Removes the first n string units. michael@0: * @param n prefix length, must be non-negative and <=length() michael@0: * @stable ICU 4.2 michael@0: */ michael@0: void remove_prefix(int32_t n) { michael@0: if (n >= 0) { michael@0: if (n > length_) { michael@0: n = length_; michael@0: } michael@0: ptr_ += n; michael@0: length_ -= n; michael@0: } michael@0: } michael@0: michael@0: /** michael@0: * Removes the last n string units. michael@0: * @param n suffix length, must be non-negative and <=length() michael@0: * @stable ICU 4.2 michael@0: */ michael@0: void remove_suffix(int32_t n) { michael@0: if (n >= 0) { michael@0: if (n <= length_) { michael@0: length_ -= n; michael@0: } else { michael@0: length_ = 0; michael@0: } michael@0: } michael@0: } michael@0: michael@0: /** michael@0: * Maximum integer, used as a default value for substring methods. michael@0: * @stable ICU 4.2 michael@0: */ michael@0: static const int32_t npos; // = 0x7fffffff; michael@0: michael@0: /** michael@0: * Returns a substring of this StringPiece. michael@0: * @param pos start position; must be non-negative and <= length(). michael@0: * @param len length of the substring; michael@0: * must be non-negative and will be pinned to at most length() - pos. michael@0: * @return the substring StringPiece michael@0: * @stable ICU 4.2 michael@0: */ michael@0: StringPiece substr(int32_t pos, int32_t len = npos) const { michael@0: return StringPiece(*this, pos, len); michael@0: } michael@0: }; michael@0: michael@0: /** michael@0: * Global operator == for StringPiece michael@0: * @param x The first StringPiece to compare. michael@0: * @param y The second StringPiece to compare. michael@0: * @return TRUE if the string data is equal michael@0: * @stable ICU 4.8 michael@0: */ michael@0: U_EXPORT UBool U_EXPORT2 michael@0: operator==(const StringPiece& x, const StringPiece& y); michael@0: michael@0: /** michael@0: * Global operator != for StringPiece michael@0: * @param x The first StringPiece to compare. michael@0: * @param y The second StringPiece to compare. michael@0: * @return TRUE if the string data is not equal michael@0: * @stable ICU 4.8 michael@0: */ michael@0: inline UBool operator!=(const StringPiece& x, const StringPiece& y) { michael@0: return !(x == y); michael@0: } michael@0: michael@0: U_NAMESPACE_END michael@0: michael@0: #endif // __STRINGPIECE_H__