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 |