OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2016 PDFium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com | |
6 | |
7 #ifndef CORE_FXCRT_CFX_STRING_C_TEMPLATE_H_ | |
8 #define CORE_FXCRT_CFX_STRING_C_TEMPLATE_H_ | |
9 | |
10 #include <algorithm> | |
11 #include <type_traits> | |
12 | |
13 #include "core/fxcrt/include/fx_system.h" | |
14 | |
15 // An immutable string with caller-provided storage which must outlive the | |
16 // string itself. These are not necessarily nul-terminated, so that substring | |
17 // extraction (via the Mid(), Left(), and Right() methods) is copy-free. | |
18 template <typename T> | |
19 class CFX_StringCTemplate { | |
20 public: | |
21 using CharType = T; | |
Lei Zhang
2016/05/13 20:47:40
Can you just use:
template <typename CharType>
o
Tom Sepez
2016/05/13 21:20:16
No, there are places where we want to have CFX_Byt
| |
22 using UnsignedType = typename std::make_unsigned<CharType>::type; | |
23 | |
24 CFX_StringCTemplate() : m_Ptr(nullptr), m_Length(0) {} | |
25 | |
26 // Deliberately implicit to avoid calling on every string literal. | |
27 CFX_StringCTemplate(const CharType* ptr) | |
28 : m_Ptr(reinterpret_cast<const UnsignedType*>(ptr)), | |
29 m_Length(ptr ? FXSYS_len(ptr) : 0) {} | |
30 | |
31 CFX_StringCTemplate(const CharType* ptr, FX_STRSIZE len) | |
32 : m_Ptr(reinterpret_cast<const UnsignedType*>(ptr)), | |
33 m_Length(len == -1 ? FXSYS_len(ptr) : len) {} | |
34 | |
35 template <typename U = UnsignedType> | |
36 CFX_StringCTemplate( | |
37 const UnsignedType* ptr, | |
38 FX_STRSIZE size, | |
39 typename std::enable_if<!std::is_same<U, CharType>::value>::type* = 0) | |
40 : m_Ptr(ptr), m_Length(size) {} | |
41 | |
42 // Deliberately implicit to avoid calling on every string literal. | |
43 // |ch| must be an lvalue that outlives the the CFX_StringCTemplate. | |
44 CFX_StringCTemplate(CharType& ch) { | |
45 m_Ptr = reinterpret_cast<const UnsignedType*>(&ch); | |
46 m_Length = 1; | |
47 } | |
48 | |
49 CFX_StringCTemplate(const CFX_StringCTemplate& src) { | |
50 m_Ptr = src.m_Ptr; | |
51 m_Length = src.m_Length; | |
52 } | |
53 | |
54 CFX_StringCTemplate& operator=(const CharType* src) { | |
55 m_Ptr = reinterpret_cast<const UnsignedType*>(src); | |
56 m_Length = src ? FXSYS_len(src) : 0; | |
57 return *this; | |
58 } | |
59 | |
60 CFX_StringCTemplate& operator=(const CFX_StringCTemplate& src) { | |
61 m_Ptr = src.m_Ptr; | |
62 m_Length = src.m_Length; | |
63 return *this; | |
64 } | |
65 | |
66 bool operator==(const CharType* ptr) const { | |
67 return FXSYS_len(ptr) == m_Length && | |
68 FXSYS_cmp(ptr, reinterpret_cast<const CharType*>(m_Ptr), m_Length) == | |
69 0; | |
70 } | |
71 bool operator==(const CFX_StringCTemplate& other) const { | |
72 return other.m_Length == m_Length && | |
73 FXSYS_cmp(reinterpret_cast<const CharType*>(other.m_Ptr), | |
74 reinterpret_cast<const CharType*>(m_Ptr), m_Length) == 0; | |
75 } | |
76 bool operator!=(const CharType* ptr) const { return !(*this == ptr); } | |
77 bool operator!=(const CFX_StringCTemplate& other) const { | |
78 return !(*this == other); | |
79 } | |
80 | |
81 uint32_t GetID(FX_STRSIZE start_pos = 0) const { | |
82 if (m_Length == 0 || start_pos < 0 || start_pos >= m_Length) | |
83 return 0; | |
84 | |
85 uint32_t strid = 0; | |
86 FX_STRSIZE size = std::min(4, m_Length - start_pos); | |
87 for (FX_STRSIZE i = 0; i < size; i++) | |
88 strid = strid * 256 + m_Ptr[start_pos + i]; | |
89 | |
90 return strid << ((4 - size) * 8); | |
91 } | |
92 | |
93 const UnsignedType* raw_str() const { return m_Ptr; } | |
94 const CharType* c_str() const { | |
95 return reinterpret_cast<const CharType*>(m_Ptr); | |
96 } | |
97 | |
98 FX_STRSIZE GetLength() const { return m_Length; } | |
99 bool IsEmpty() const { return m_Length == 0; } | |
100 | |
101 UnsignedType GetAt(FX_STRSIZE index) const { return m_Ptr[index]; } | |
102 CharType CharAt(FX_STRSIZE index) const { | |
103 return static_cast<CharType>(m_Ptr[index]); | |
104 } | |
105 | |
106 FX_STRSIZE Find(CharType ch) const { | |
107 const UnsignedType* found = reinterpret_cast<const UnsignedType*>( | |
108 FXSYS_chr(reinterpret_cast<const CharType*>(m_Ptr), ch, m_Length)); | |
109 return found ? found - m_Ptr : -1; | |
110 } | |
111 | |
112 CFX_StringCTemplate Mid(FX_STRSIZE index, FX_STRSIZE count = -1) const { | |
113 index = std::max(0, index); | |
114 if (index > m_Length) | |
115 return CFX_StringCTemplate(); | |
116 | |
117 if (count < 0 || count > m_Length - index) | |
118 count = m_Length - index; | |
119 | |
120 return CFX_StringCTemplate(m_Ptr + index, count); | |
121 } | |
122 | |
123 CFX_StringCTemplate Left(FX_STRSIZE count) const { | |
124 if (count <= 0) | |
125 return CFX_StringCTemplate(); | |
126 | |
127 return CFX_StringCTemplate(m_Ptr, std::min(count, m_Length)); | |
128 } | |
129 | |
130 CFX_StringCTemplate Right(FX_STRSIZE count) const { | |
131 if (count <= 0) | |
132 return CFX_StringCTemplate(); | |
133 | |
134 count = std::min(count, m_Length); | |
135 return CFX_StringCTemplate(m_Ptr + m_Length - count, count); | |
136 } | |
137 | |
138 const UnsignedType& operator[](size_t index) const { return m_Ptr[index]; } | |
139 | |
140 bool operator<(const CFX_StringCTemplate& that) const { | |
141 int result = FXSYS_cmp(reinterpret_cast<const CharType*>(m_Ptr), | |
142 reinterpret_cast<const CharType*>(that.m_Ptr), | |
143 std::min(m_Length, that.m_Length)); | |
144 return result < 0 || (result == 0 && m_Length < that.m_Length); | |
145 } | |
146 | |
147 protected: | |
148 const UnsignedType* m_Ptr; | |
149 FX_STRSIZE m_Length; | |
150 | |
151 private: | |
152 void* operator new(size_t) throw() { return nullptr; } | |
153 }; | |
154 | |
155 template <typename T> | |
156 inline bool operator==(const T* lhs, const CFX_StringCTemplate<T>& rhs) { | |
157 return rhs == lhs; | |
158 } | |
159 | |
160 template <typename T> | |
161 inline bool operator!=(const T* lhs, const CFX_StringCTemplate<T>& rhs) { | |
162 return rhs != lhs; | |
163 } | |
164 | |
165 extern template class CFX_StringCTemplate<FX_CHAR>; | |
166 extern template class CFX_StringCTemplate<FX_WCHAR>; | |
167 | |
168 #endif // CORE_FXCRT_CFX_STRING_C_TEMPLATE_H_ | |
OLD | NEW |