Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2014 PDFium Authors. All rights reserved. | 1 // Copyright 2014 PDFium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com | 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com |
| 6 | 6 |
| 7 #ifndef CORE_FXCRT_INCLUDE_FX_STRING_H_ | 7 #ifndef CORE_FXCRT_INCLUDE_FX_STRING_H_ |
| 8 #define CORE_FXCRT_INCLUDE_FX_STRING_H_ | 8 #define CORE_FXCRT_INCLUDE_FX_STRING_H_ |
| 9 | 9 |
| 10 #include <stdint.h> // For intptr_t. | 10 #include <stdint.h> // For intptr_t. |
| 11 #include <algorithm> | 11 #include <algorithm> |
| 12 #include <type_traits> | |
|
Lei Zhang
2016/05/13 20:47:40
Not needed here?
Tom Sepez
2016/05/13 21:20:16
Done.
| |
| 12 | 13 |
| 14 #include "core/fxcrt/cfx_string_c_template.h" | |
| 13 #include "core/fxcrt/cfx_string_data_template.h" | 15 #include "core/fxcrt/cfx_string_data_template.h" |
| 14 #include "core/fxcrt/include/cfx_retain_ptr.h" | 16 #include "core/fxcrt/include/cfx_retain_ptr.h" |
| 15 #include "core/fxcrt/include/fx_memory.h" | 17 #include "core/fxcrt/include/fx_memory.h" |
| 16 #include "core/fxcrt/include/fx_system.h" | 18 #include "core/fxcrt/include/fx_system.h" |
| 17 | 19 |
| 18 class CFX_ByteString; | 20 class CFX_ByteString; |
| 19 class CFX_WideString; | 21 class CFX_WideString; |
| 20 | 22 |
| 21 // An immutable string with caller-provided storage which must outlive the | 23 using CFX_ByteStringC = CFX_StringCTemplate<FX_CHAR>; |
| 22 // string itself. These are not necessarily nul-terminated, so that substring | 24 using CFX_WideStringC = CFX_StringCTemplate<FX_WCHAR>; |
| 23 // extraction (via the Mid() method) is copy-free. | |
| 24 class CFX_ByteStringC { | |
| 25 public: | |
| 26 typedef FX_CHAR value_type; | |
| 27 | 25 |
| 28 CFX_ByteStringC() { | |
| 29 m_Ptr = NULL; | |
| 30 m_Length = 0; | |
| 31 } | |
| 32 | |
| 33 CFX_ByteStringC(const uint8_t* ptr, FX_STRSIZE size) { | |
| 34 m_Ptr = ptr; | |
| 35 m_Length = size; | |
| 36 } | |
| 37 | |
| 38 // Deliberately implicit to avoid calling on every string literal. | |
| 39 CFX_ByteStringC(const FX_CHAR* ptr) { | |
| 40 m_Ptr = (const uint8_t*)ptr; | |
| 41 m_Length = ptr ? FXSYS_strlen(ptr) : 0; | |
| 42 } | |
| 43 | |
| 44 // Deliberately implicit to avoid calling on every string literal. | |
| 45 // |ch| must be an lvalue that outlives the the CFX_ByteStringC. | |
| 46 CFX_ByteStringC(FX_CHAR& ch) { | |
| 47 m_Ptr = (const uint8_t*)&ch; | |
| 48 m_Length = 1; | |
| 49 } | |
| 50 | |
| 51 CFX_ByteStringC(const FX_CHAR* ptr, FX_STRSIZE len) { | |
| 52 m_Ptr = (const uint8_t*)ptr; | |
| 53 m_Length = (len == -1) ? FXSYS_strlen(ptr) : len; | |
| 54 } | |
| 55 | |
| 56 CFX_ByteStringC(const CFX_ByteStringC& src) { | |
| 57 m_Ptr = src.m_Ptr; | |
| 58 m_Length = src.m_Length; | |
| 59 } | |
| 60 | |
| 61 CFX_ByteStringC& operator=(const FX_CHAR* src) { | |
| 62 m_Ptr = (const uint8_t*)src; | |
| 63 m_Length = m_Ptr ? FXSYS_strlen(src) : 0; | |
| 64 return *this; | |
| 65 } | |
| 66 | |
| 67 CFX_ByteStringC& operator=(const CFX_ByteStringC& src) { | |
| 68 m_Ptr = src.m_Ptr; | |
| 69 m_Length = src.m_Length; | |
| 70 return *this; | |
| 71 } | |
| 72 | |
| 73 bool operator==(const char* ptr) const { | |
| 74 return FXSYS_strlen(ptr) == m_Length && | |
| 75 FXSYS_memcmp(ptr, m_Ptr, m_Length) == 0; | |
| 76 } | |
| 77 bool operator==(const CFX_ByteStringC& other) const { | |
| 78 return other.m_Length == m_Length && | |
| 79 FXSYS_memcmp(other.m_Ptr, m_Ptr, m_Length) == 0; | |
| 80 } | |
| 81 bool operator!=(const char* ptr) const { return !(*this == ptr); } | |
| 82 bool operator!=(const CFX_ByteStringC& other) const { | |
| 83 return !(*this == other); | |
| 84 } | |
| 85 | |
| 86 uint32_t GetID(FX_STRSIZE start_pos = 0) const; | |
| 87 | |
| 88 const uint8_t* raw_str() const { return m_Ptr; } | |
| 89 const FX_CHAR* c_str() const { | |
| 90 return reinterpret_cast<const FX_CHAR*>(m_Ptr); | |
| 91 } | |
| 92 | |
| 93 FX_STRSIZE GetLength() const { return m_Length; } | |
| 94 bool IsEmpty() const { return m_Length == 0; } | |
| 95 | |
| 96 uint8_t GetAt(FX_STRSIZE index) const { return m_Ptr[index]; } | |
| 97 FX_CHAR CharAt(FX_STRSIZE index) const { | |
| 98 return static_cast<FX_CHAR>(m_Ptr[index]); | |
| 99 } | |
| 100 | |
| 101 FX_STRSIZE Find(FX_CHAR ch) const { | |
| 102 const uint8_t* found = | |
| 103 static_cast<const uint8_t*>(memchr(m_Ptr, ch, m_Length)); | |
| 104 return found ? found - m_Ptr : -1; | |
| 105 } | |
| 106 | |
| 107 CFX_ByteStringC Mid(FX_STRSIZE index, FX_STRSIZE count = -1) const { | |
| 108 if (index < 0) { | |
| 109 index = 0; | |
| 110 } | |
| 111 if (index > m_Length) { | |
| 112 return CFX_ByteStringC(); | |
| 113 } | |
| 114 if (count < 0 || count > m_Length - index) { | |
| 115 count = m_Length - index; | |
| 116 } | |
| 117 return CFX_ByteStringC(m_Ptr + index, count); | |
| 118 } | |
| 119 | |
| 120 const uint8_t& operator[](size_t index) const { return m_Ptr[index]; } | |
| 121 | |
| 122 bool operator<(const CFX_ByteStringC& that) const { | |
| 123 int result = memcmp(m_Ptr, that.m_Ptr, std::min(m_Length, that.m_Length)); | |
| 124 return result < 0 || (result == 0 && m_Length < that.m_Length); | |
| 125 } | |
| 126 | |
| 127 protected: | |
| 128 const uint8_t* m_Ptr; | |
| 129 FX_STRSIZE m_Length; | |
| 130 | |
| 131 private: | |
| 132 void* operator new(size_t) throw() { return NULL; } | |
| 133 }; | |
| 134 inline bool operator==(const char* lhs, const CFX_ByteStringC& rhs) { | |
| 135 return rhs == lhs; | |
| 136 } | |
| 137 inline bool operator!=(const char* lhs, const CFX_ByteStringC& rhs) { | |
| 138 return rhs != lhs; | |
| 139 } | |
| 140 #define FXBSTR_ID(c1, c2, c3, c4) \ | 26 #define FXBSTR_ID(c1, c2, c3, c4) \ |
| 141 (((uint32_t)c1 << 24) | ((uint32_t)c2 << 16) | ((uint32_t)c3 << 8) | \ | 27 (((uint32_t)c1 << 24) | ((uint32_t)c2 << 16) | ((uint32_t)c3 << 8) | \ |
| 142 ((uint32_t)c4)) | 28 ((uint32_t)c4)) |
| 143 | 29 |
| 30 #define FX_WSTRC(wstr) CFX_WideStringC(wstr, FX_ArraySize(wstr) - 1) | |
| 31 | |
| 144 // A mutable string with shared buffers using copy-on-write semantics that | 32 // A mutable string with shared buffers using copy-on-write semantics that |
| 145 // avoids the cost of std::string's iterator stability guarantees. | 33 // avoids the cost of std::string's iterator stability guarantees. |
| 146 class CFX_ByteString { | 34 class CFX_ByteString { |
| 147 public: | 35 public: |
| 148 typedef FX_CHAR value_type; | 36 using CharType = FX_CHAR; |
| 149 | 37 |
| 150 CFX_ByteString() {} | 38 CFX_ByteString() {} |
| 151 CFX_ByteString(const CFX_ByteString& other) : m_pData(other.m_pData) {} | 39 CFX_ByteString(const CFX_ByteString& other) : m_pData(other.m_pData) {} |
| 152 CFX_ByteString(CFX_ByteString&& other) { m_pData.Swap(other.m_pData); } | 40 CFX_ByteString(CFX_ByteString&& other) { m_pData.Swap(other.m_pData); } |
| 153 | 41 |
| 154 // Deliberately implicit to avoid calling on every string literal. | 42 // Deliberately implicit to avoid calling on every string literal. |
| 155 CFX_ByteString(char ch); | 43 CFX_ByteString(char ch); |
| 156 CFX_ByteString(const FX_CHAR* ptr) | 44 CFX_ByteString(const FX_CHAR* ptr) |
| 157 : CFX_ByteString(ptr, ptr ? FXSYS_strlen(ptr) : 0) {} | 45 : CFX_ByteString(ptr, ptr ? FXSYS_strlen(ptr) : 0) {} |
| 158 | 46 |
| (...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 339 } | 227 } |
| 340 inline CFX_ByteString operator+(const CFX_ByteString& str1, | 228 inline CFX_ByteString operator+(const CFX_ByteString& str1, |
| 341 const CFX_ByteStringC& str2) { | 229 const CFX_ByteStringC& str2) { |
| 342 return CFX_ByteString(str1.AsStringC(), str2); | 230 return CFX_ByteString(str1.AsStringC(), str2); |
| 343 } | 231 } |
| 344 inline CFX_ByteString operator+(const CFX_ByteStringC& str1, | 232 inline CFX_ByteString operator+(const CFX_ByteStringC& str1, |
| 345 const CFX_ByteString& str2) { | 233 const CFX_ByteString& str2) { |
| 346 return CFX_ByteString(str1, str2.AsStringC()); | 234 return CFX_ByteString(str1, str2.AsStringC()); |
| 347 } | 235 } |
| 348 | 236 |
| 349 class CFX_WideStringC { | |
| 350 public: | |
| 351 typedef FX_WCHAR value_type; | |
| 352 | |
| 353 CFX_WideStringC() { | |
| 354 m_Ptr = NULL; | |
| 355 m_Length = 0; | |
| 356 } | |
| 357 | |
| 358 // Deliberately implicit to avoid calling on every string literal. | |
| 359 CFX_WideStringC(const FX_WCHAR* ptr) { | |
| 360 m_Ptr = ptr; | |
| 361 m_Length = ptr ? FXSYS_wcslen(ptr) : 0; | |
| 362 } | |
| 363 | |
| 364 // Deliberately implicit to avoid calling on every string literal. | |
| 365 // |ch| must be an lvalue that outlives the the CFX_WideStringC. | |
| 366 CFX_WideStringC(FX_WCHAR& ch) { | |
| 367 m_Ptr = &ch; | |
| 368 m_Length = 1; | |
| 369 } | |
| 370 | |
| 371 CFX_WideStringC(const FX_WCHAR* ptr, FX_STRSIZE len) { | |
| 372 m_Ptr = ptr; | |
| 373 m_Length = (len == -1) ? FXSYS_wcslen(ptr) : len; | |
| 374 } | |
| 375 | |
| 376 CFX_WideStringC(const CFX_WideStringC& src) { | |
| 377 m_Ptr = src.m_Ptr; | |
| 378 m_Length = src.m_Length; | |
| 379 } | |
| 380 | |
| 381 CFX_WideStringC& operator=(const FX_WCHAR* src) { | |
| 382 m_Ptr = src; | |
| 383 m_Length = FXSYS_wcslen(src); | |
| 384 return *this; | |
| 385 } | |
| 386 | |
| 387 CFX_WideStringC& operator=(const CFX_WideStringC& src) { | |
| 388 m_Ptr = src.m_Ptr; | |
| 389 m_Length = src.m_Length; | |
| 390 return *this; | |
| 391 } | |
| 392 | |
| 393 bool operator==(const wchar_t* ptr) const { | |
| 394 return FXSYS_wcslen(ptr) == m_Length && wmemcmp(ptr, m_Ptr, m_Length) == 0; | |
| 395 } | |
| 396 bool operator==(const CFX_WideStringC& str) const { | |
| 397 return str.m_Length == m_Length && wmemcmp(str.m_Ptr, m_Ptr, m_Length) == 0; | |
| 398 } | |
| 399 bool operator!=(const wchar_t* ptr) const { return !(*this == ptr); } | |
| 400 bool operator!=(const CFX_WideStringC& str) const { return !(*this == str); } | |
| 401 | |
| 402 const FX_WCHAR* c_str() const { return m_Ptr; } | |
| 403 | |
| 404 FX_STRSIZE GetLength() const { return m_Length; } | |
| 405 bool IsEmpty() const { return m_Length == 0; } | |
| 406 | |
| 407 FX_WCHAR GetAt(FX_STRSIZE index) const { return m_Ptr[index]; } | |
| 408 | |
| 409 CFX_WideStringC Left(FX_STRSIZE count) const { | |
| 410 if (count < 1) { | |
| 411 return CFX_WideStringC(); | |
| 412 } | |
| 413 if (count > m_Length) { | |
| 414 count = m_Length; | |
| 415 } | |
| 416 return CFX_WideStringC(m_Ptr, count); | |
| 417 } | |
| 418 | |
| 419 FX_STRSIZE Find(FX_WCHAR ch) const { | |
| 420 const FX_WCHAR* found = | |
| 421 static_cast<const FX_WCHAR*>(wmemchr(m_Ptr, ch, m_Length)); | |
| 422 return found ? found - m_Ptr : -1; | |
| 423 } | |
| 424 | |
| 425 CFX_WideStringC Mid(FX_STRSIZE index, FX_STRSIZE count = -1) const { | |
| 426 if (index < 0) { | |
| 427 index = 0; | |
| 428 } | |
| 429 if (index > m_Length) { | |
| 430 return CFX_WideStringC(); | |
| 431 } | |
| 432 if (count < 0 || count > m_Length - index) { | |
| 433 count = m_Length - index; | |
| 434 } | |
| 435 return CFX_WideStringC(m_Ptr + index, count); | |
| 436 } | |
| 437 | |
| 438 CFX_WideStringC Right(FX_STRSIZE count) const { | |
| 439 if (count < 1) { | |
| 440 return CFX_WideStringC(); | |
| 441 } | |
| 442 if (count > m_Length) { | |
| 443 count = m_Length; | |
| 444 } | |
| 445 return CFX_WideStringC(m_Ptr + m_Length - count, count); | |
| 446 } | |
| 447 | |
| 448 const FX_WCHAR& operator[](size_t index) const { return m_Ptr[index]; } | |
| 449 | |
| 450 bool operator<(const CFX_WideStringC& that) const { | |
| 451 int result = wmemcmp(m_Ptr, that.m_Ptr, std::min(m_Length, that.m_Length)); | |
| 452 return result < 0 || (result == 0 && m_Length < that.m_Length); | |
| 453 } | |
| 454 | |
| 455 protected: | |
| 456 const FX_WCHAR* m_Ptr; | |
| 457 FX_STRSIZE m_Length; | |
| 458 | |
| 459 private: | |
| 460 void* operator new(size_t) throw() { return NULL; } | |
| 461 }; | |
| 462 | |
| 463 inline bool operator==(const wchar_t* lhs, const CFX_WideStringC& rhs) { | |
| 464 return rhs == lhs; | |
| 465 } | |
| 466 inline bool operator!=(const wchar_t* lhs, const CFX_WideStringC& rhs) { | |
| 467 return rhs != lhs; | |
| 468 } | |
| 469 #define FX_WSTRC(wstr) CFX_WideStringC(wstr, FX_ArraySize(wstr) - 1) | |
| 470 | |
| 471 // A mutable string with shared buffers using copy-on-write semantics that | 237 // A mutable string with shared buffers using copy-on-write semantics that |
| 472 // avoids the cost of std::string's iterator stability guarantees. | 238 // avoids the cost of std::string's iterator stability guarantees. |
| 473 class CFX_WideString { | 239 class CFX_WideString { |
| 474 public: | 240 public: |
| 475 typedef FX_WCHAR value_type; | 241 using CharType = FX_WCHAR; |
| 476 | 242 |
| 477 CFX_WideString() {} | 243 CFX_WideString() {} |
| 478 CFX_WideString(const CFX_WideString& other) : m_pData(other.m_pData) {} | 244 CFX_WideString(const CFX_WideString& other) : m_pData(other.m_pData) {} |
| 479 CFX_WideString(CFX_WideString&& other) { m_pData.Swap(other.m_pData); } | 245 CFX_WideString(CFX_WideString&& other) { m_pData.Swap(other.m_pData); } |
| 480 | 246 |
| 481 // Deliberately implicit to avoid calling on every string literal. | 247 // Deliberately implicit to avoid calling on every string literal. |
| 482 CFX_WideString(FX_WCHAR ch); | 248 CFX_WideString(FX_WCHAR ch); |
| 483 CFX_WideString(const FX_WCHAR* ptr) | 249 CFX_WideString(const FX_WCHAR* ptr) |
| 484 : CFX_WideString(ptr, ptr ? FXSYS_wcslen(ptr) : 0) {} | 250 : CFX_WideString(ptr, ptr ? FXSYS_wcslen(ptr) : 0) {} |
| 485 | 251 |
| (...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 673 } | 439 } |
| 674 | 440 |
| 675 FX_FLOAT FX_atof(const CFX_ByteStringC& str); | 441 FX_FLOAT FX_atof(const CFX_ByteStringC& str); |
| 676 inline FX_FLOAT FX_atof(const CFX_WideStringC& wsStr) { | 442 inline FX_FLOAT FX_atof(const CFX_WideStringC& wsStr) { |
| 677 return FX_atof(FX_UTF8Encode(wsStr.c_str(), wsStr.GetLength()).c_str()); | 443 return FX_atof(FX_UTF8Encode(wsStr.c_str(), wsStr.GetLength()).c_str()); |
| 678 } | 444 } |
| 679 void FX_atonum(const CFX_ByteStringC& str, FX_BOOL& bInteger, void* pData); | 445 void FX_atonum(const CFX_ByteStringC& str, FX_BOOL& bInteger, void* pData); |
| 680 FX_STRSIZE FX_ftoa(FX_FLOAT f, FX_CHAR* buf); | 446 FX_STRSIZE FX_ftoa(FX_FLOAT f, FX_CHAR* buf); |
| 681 | 447 |
| 682 #endif // CORE_FXCRT_INCLUDE_FX_STRING_H_ | 448 #endif // CORE_FXCRT_INCLUDE_FX_STRING_H_ |
| OLD | NEW |