54template <
typename LENGTH_TYPE>
class UTF8StringSliceBase {
56 typedef LENGTH_TYPE LengthType;
58 UTF8StringSliceBase(
const char* _str)
60 byteLength(
static_cast<LengthType
>(strlen(_str))) {}
62 UTF8StringSliceBase(
const char* _str,
const LengthType _utf8Length)
63 : str(_str), utf8Length(_utf8Length) {
64 CalculateByteLength();
67 UTF8StringSliceBase(
const char* _str,
const LengthType _utf8Length,
68 const LengthType _byteLength)
69 : str(_str), utf8Length(_utf8Length), byteLength(_byteLength) {
70 CalculateByteLength();
73 LengthType UTF8Length()
const {
return utf8Length; }
75 LengthType ByteLength()
const {
return byteLength; }
77 UTF8StringSliceBase Left(
const LengthType numberOfCharacters)
const {
78 if (numberOfCharacters == UTF8Length()) {
81 return UTF8StringSliceBase(str, numberOfCharacters);
85 UTF8StringSliceBase Right(
const LengthType numberOfCharacters)
const {
86 if (numberOfCharacters == UTF8Length()) {
89 const char* pstr = str + byteLength;
90 for (
size_t i = 0; i < numberOfCharacters; i++) {
93 return UTF8StringSliceBase(pstr, numberOfCharacters);
97 UTF8StringSliceBase SubString(
const LengthType offset,
98 const LengthType numberOfCharacters)
const {
100 return Left(numberOfCharacters);
102 const char* pstr = str;
103 for (
size_t i = 0; i < offset; i++) {
106 return UTF8StringSliceBase(pstr, numberOfCharacters);
110 std::string ToString()
const {
return std::string(str, str + byteLength); }
112 const char* CString()
const {
return str; }
114 LengthType CommonPrefixLength(
const UTF8StringSliceBase& that)
const {
115 if (str == that.str) {
116 return (std::min)(utf8Length, that.utf8Length);
118 const char* pstr1 = str;
119 const char* pstr2 = that.str;
120 for (
size_t length = 0; length < utf8Length && length < that.utf8Length;
124 if (charLen1 != charLen2 || strncmp(pstr1, pstr2, charLen1) != 0) {
135 if (utf8Length > 0) {
139 byteLength -= charLen;
144 if (utf8Length > 0) {
147 byteLength -= charLen;
151 int ReverseCompare(
const UTF8StringSliceBase& that)
const {
152 const char* pstr1 = str + byteLength;
153 const char* pstr2 = that.str + that.byteLength;
154 const size_t length = (std::min)(utf8Length, that.utf8Length);
155 for (
size_t i = 0; i < length; i++) {
160 const int cmp = strncmp(pstr1, pstr2, (std::min)(charLen1, charLen2));
163 }
else if (cmp > 0) {
165 }
else if (charLen1 < charLen2) {
167 }
else if (charLen1 > charLen2) {
171 if (utf8Length < that.utf8Length) {
173 }
else if (utf8Length > that.utf8Length) {
180 LengthType FindBytePosition(
const UTF8StringSliceBase& pattern)
const {
181 return static_cast<LengthType
>(
182 ToString().find(pattern.str, 0, pattern.byteLength));
185 bool operator<(
const UTF8StringSliceBase& that)
const {
186 return Compare(that) < 0;
189 bool operator>(
const UTF8StringSliceBase& that)
const {
190 return Compare(that) > 0;
193 bool operator==(
const UTF8StringSliceBase& that)
const {
194 return (str == that.str && utf8Length == that.utf8Length) ||
198 bool operator!=(
const UTF8StringSliceBase& that)
const {
199 return !this->operator==(that);
204 size_t operator()(
const UTF8StringSliceBase& text)
const {
205 return internal::FNVHash<sizeof(size_t)>(text.CString(),
211 inline int Compare(
const UTF8StringSliceBase& that)
const {
212 int cmp = strncmp(str, that.str, (std::min)(byteLength, that.byteLength));
214 if (utf8Length < that.utf8Length) {
216 }
else if (utf8Length > that.utf8Length) {
225 void CalculateByteLength() {
226 const char* pstr = str;
227 for (
size_t i = 0; i < utf8Length; i++) {
230 byteLength =
static_cast<LengthType
>(pstr - str);
234 LengthType utf8Length;
235 LengthType byteLength;