20 #include "UTF8Util.hpp"
26 inline size_t FNVHash(
const char* text,
const size_t byteLength,
27 const size_t FNV_prime,
const size_t FNV_offset_basis) {
28 size_t hash = FNV_offset_basis;
29 for (
const char* pstr = text; pstr < text + byteLength; pstr++) {
36 template <
int>
size_t FNVHash(
const char* text,
const size_t byteLength);
39 inline size_t FNVHash<4>(
const char* text,
const size_t byteLength) {
40 return FNVHash(text, byteLength, 16777619UL, 2166136261UL);
43 #if SIZE_MAX == 0xffffffffffffffff
45 inline size_t FNVHash<8>(
const char* text,
const size_t byteLength) {
46 return FNVHash(text, byteLength, 1099511628211UL, 14695981039346656037UL);
54 typedef LENGTH_TYPE LengthType;
58 byteLength(
static_cast<LengthType
>(strlen(_str))) {}
61 : str(_str), utf8Length(_utf8Length) {
62 CalculateByteLength();
66 const LengthType _byteLength)
67 : str(_str), utf8Length(_utf8Length), byteLength(_byteLength) {
68 CalculateByteLength();
71 LengthType UTF8Length()
const {
return utf8Length; }
73 LengthType ByteLength()
const {
return byteLength; }
76 if (numberOfCharacters == UTF8Length()) {
84 if (numberOfCharacters == UTF8Length()) {
87 const char* pstr = str + byteLength;
88 for (
size_t i = 0; i < numberOfCharacters; i++) {
96 const LengthType numberOfCharacters)
const {
98 return Left(numberOfCharacters);
100 const char* pstr = str;
101 for (
size_t i = 0; i < offset; i++) {
108 string ToString()
const {
return string(str, str + byteLength); }
110 const char* CString()
const {
return str; }
113 if (str == that.str) {
114 return std::min(utf8Length, that.utf8Length);
116 const char* pstr1 = str;
117 const char* pstr2 = that.str;
118 for (
size_t length = 0; length < utf8Length && length < that.utf8Length;
122 if (charLen1 != charLen2 || strncmp(pstr1, pstr2, charLen1) != 0) {
133 if (utf8Length > 0) {
137 byteLength -= charLen;
142 if (utf8Length > 0) {
145 byteLength -= charLen;
150 const char* pstr1 = str + byteLength;
151 const char* pstr2 = that.str + that.byteLength;
152 const size_t length = std::min(utf8Length, that.utf8Length);
153 for (
size_t i = 0; i < length; i++) {
158 const int cmp = strncmp(pstr1, pstr2, std::min(charLen1, charLen2));
161 }
else if (cmp > 0) {
163 }
else if (charLen1 < charLen2) {
165 }
else if (charLen1 > charLen2) {
169 if (utf8Length < that.utf8Length) {
171 }
else if (utf8Length > that.utf8Length) {
179 return static_cast<LengthType
>(
180 ToString().find(pattern.str, 0, pattern.byteLength));
184 return Compare(that) < 0;
188 return Compare(that) > 0;
192 return (str == that.str && utf8Length == that.utf8Length) ||
197 return !this->operator==(that);
203 return internal::FNVHash<sizeof(size_t)>(text.CString(),
210 int cmp = strncmp(str, that.str, std::min(byteLength, that.byteLength));
212 if (utf8Length < that.utf8Length) {
214 }
else if (utf8Length > that.utf8Length) {
223 void CalculateByteLength() {
224 const char* pstr = str;
225 for (
size_t i = 0; i < utf8Length; i++) {
228 byteLength =
static_cast<LengthType
>(pstr - str);
232 LengthType utf8Length;
233 LengthType byteLength;
236 typedef UTF8StringSliceBase<size_t> UTF8StringSlice;
238 template <
typename LENGTH_TYPE>
239 std::ostream& operator<<(::std::ostream& os,
240 const UTF8StringSliceBase<LENGTH_TYPE>& str) {
241 return os << str.ToString();