Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(149)

Side by Side Diff: core/fxcrt/fx_basic_wstring.cpp

Issue 1846793002: Make wide strings use StringData template (Closed) Base URL: https://pdfium.googlesource.com/pdfium.git@template_str
Patch Set: Fix mac compile Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « core/fxcrt/fx_basic_bstring.cpp ('k') | core/fxcrt/fx_basic_wstring_unittest.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 #include <stddef.h> 7 #include <stddef.h>
8 8
9 #include <algorithm> 9 #include <algorithm>
10 #include <cctype> 10 #include <cctype>
11 11
12 #include "core/fxcrt/include/fx_basic.h" 12 #include "core/fxcrt/include/fx_basic.h"
13 #include "core/fxcrt/include/fx_ext.h" 13 #include "core/fxcrt/include/fx_ext.h"
14 #include "third_party/base/numerics/safe_math.h" 14 #include "third_party/base/numerics/safe_math.h"
15 15
16 template class CFX_StringDataTemplate<FX_WCHAR>;
17
16 namespace { 18 namespace {
17 19
18 #ifndef NDEBUG 20 #ifndef NDEBUG
19 bool IsValidCodePage(uint16_t codepage) { 21 bool IsValidCodePage(uint16_t codepage) {
20 switch (codepage) { 22 switch (codepage) {
21 case 0: 23 case 0:
22 case 932: 24 case 932:
23 case 936: 25 case 936:
24 case 949: 26 case 949:
25 case 950: 27 case 950:
26 return true; 28 return true;
27 29
28 default: 30 default:
29 return false; 31 return false;
30 } 32 }
31 } 33 }
32 #endif 34 #endif
33 35
36 const FX_WCHAR* FX_wcsstr(const FX_WCHAR* haystack,
37 int haystack_len,
38 const FX_WCHAR* needle,
39 int needle_len) {
40 if (needle_len > haystack_len || needle_len == 0) {
41 return nullptr;
42 }
43 const FX_WCHAR* end_ptr = haystack + haystack_len - needle_len;
44 while (haystack <= end_ptr) {
45 int i = 0;
46 while (1) {
47 if (haystack[i] != needle[i]) {
48 break;
49 }
50 i++;
51 if (i == needle_len) {
52 return haystack;
53 }
54 }
55 haystack++;
56 }
57 return nullptr;
58 }
59
34 } // namespace 60 } // namespace
35 61
36 // static 62 CFX_WideString::CFX_WideString(const FX_WCHAR* pStr, FX_STRSIZE nLen) {
37 CFX_WideString::StringData* CFX_WideString::StringData::Create(int nLen) { 63 if (nLen < 0)
38 // TODO(palmer): |nLen| should really be declared as |size_t|, or 64 nLen = pStr ? FXSYS_wcslen(pStr) : 0;
39 // at least unsigned.
40 if (nLen == 0 || nLen < 0) {
41 return NULL;
42 }
43 65
44 // Fixed portion of header plus a NUL wide char not in m_nAllocLength. 66 if (nLen)
45 int overhead = offsetof(StringData, m_String) + sizeof(FX_WCHAR); 67 m_pData.Reset(StringData::Create(pStr, nLen));
46 pdfium::base::CheckedNumeric<int> iSize = nLen; 68 }
47 iSize *= sizeof(FX_WCHAR);
48 iSize += overhead;
49 69
50 // Now round to an 8-byte boundary. We'd expect that this is the minimum 70 CFX_WideString::CFX_WideString(FX_WCHAR ch) {
51 // granularity of any of the underlying allocators, so there may be cases 71 m_pData.Reset(StringData::Create(1));
52 // where we can save a re-alloc when adding a few characters to a string 72 m_pData->m_String[0] = ch;
53 // by using this otherwise wasted space. 73 }
54 iSize += 7;
55 int totalSize = iSize.ValueOrDie() & ~7;
56 int usableLen = (totalSize - overhead) / sizeof(FX_WCHAR);
57 FXSYS_assert(usableLen >= nLen);
58 74
59 void* pData = FX_Alloc(uint8_t, totalSize); 75 CFX_WideString::CFX_WideString(const CFX_WideStringC& stringSrc) {
60 return new (pData) StringData(nLen, usableLen); 76 if (!stringSrc.IsEmpty()) {
61 } 77 m_pData.Reset(StringData::Create(stringSrc.c_str(), stringSrc.GetLength()));
62 CFX_WideString::~CFX_WideString() {
63 if (m_pData) {
64 m_pData->Release();
65 } 78 }
66 } 79 }
67 CFX_WideString::CFX_WideString(const CFX_WideString& stringSrc) { 80
68 if (!stringSrc.m_pData) {
69 m_pData = NULL;
70 return;
71 }
72 if (stringSrc.m_pData->m_nRefs >= 0) {
73 m_pData = stringSrc.m_pData;
74 m_pData->Retain();
75 } else {
76 m_pData = NULL;
77 *this = stringSrc;
78 }
79 }
80 CFX_WideString::CFX_WideString(const FX_WCHAR* lpsz, FX_STRSIZE nLen) {
81 if (nLen < 0) {
82 nLen = lpsz ? FXSYS_wcslen(lpsz) : 0;
83 }
84 if (nLen) {
85 m_pData = StringData::Create(nLen);
86 if (m_pData) {
87 FXSYS_memcpy(m_pData->m_String, lpsz, nLen * sizeof(FX_WCHAR));
88 }
89 } else {
90 m_pData = NULL;
91 }
92 }
93 CFX_WideString::CFX_WideString(FX_WCHAR ch) {
94 m_pData = StringData::Create(1);
95 if (m_pData) {
96 m_pData->m_String[0] = ch;
97 }
98 }
99 CFX_WideString::CFX_WideString(const CFX_WideStringC& str) {
100 if (str.IsEmpty()) {
101 m_pData = NULL;
102 return;
103 }
104 m_pData = StringData::Create(str.GetLength());
105 if (m_pData) {
106 FXSYS_memcpy(m_pData->m_String, str.c_str(),
107 str.GetLength() * sizeof(FX_WCHAR));
108 }
109 }
110 CFX_WideString::CFX_WideString(const CFX_WideStringC& str1, 81 CFX_WideString::CFX_WideString(const CFX_WideStringC& str1,
111 const CFX_WideStringC& str2) { 82 const CFX_WideStringC& str2) {
112 m_pData = NULL;
113 int nNewLen = str1.GetLength() + str2.GetLength(); 83 int nNewLen = str1.GetLength() + str2.GetLength();
114 if (nNewLen == 0) { 84 if (nNewLen == 0)
115 return; 85 return;
116 } 86
117 m_pData = StringData::Create(nNewLen); 87 m_pData.Reset(StringData::Create(nNewLen));
118 if (m_pData) { 88 m_pData->CopyContents(str1.c_str(), str1.GetLength());
119 FXSYS_memcpy(m_pData->m_String, str1.c_str(), 89 m_pData->CopyContentsAt(str1.GetLength(), str2.c_str(), str2.GetLength());
120 str1.GetLength() * sizeof(FX_WCHAR));
121 FXSYS_memcpy(m_pData->m_String + str1.GetLength(), str2.c_str(),
122 str2.GetLength() * sizeof(FX_WCHAR));
123 }
124 } 90 }
125 void CFX_WideString::ReleaseBuffer(FX_STRSIZE nNewLength) { 91
126 if (!m_pData) { 92 CFX_WideString::~CFX_WideString() {}
127 return; 93
128 } 94 const CFX_WideString& CFX_WideString::operator=(const FX_WCHAR* pStr) {
129 CopyBeforeWrite(); 95 if (!pStr || !pStr[0])
130 if (nNewLength == -1) { 96 clear();
131 nNewLength = m_pData ? FXSYS_wcslen(m_pData->m_String) : 0; 97 else
132 } 98 AssignCopy(pStr, FXSYS_wcslen(pStr));
133 if (nNewLength == 0) { 99
134 Empty();
135 return;
136 }
137 FXSYS_assert(nNewLength <= m_pData->m_nAllocLength);
138 m_pData->m_nDataLength = nNewLength;
139 m_pData->m_String[nNewLength] = 0;
140 }
141 const CFX_WideString& CFX_WideString::operator=(const FX_WCHAR* lpsz) {
142 if (!lpsz || lpsz[0] == 0) {
143 Empty();
144 } else {
145 AssignCopy(FXSYS_wcslen(lpsz), lpsz);
146 }
147 return *this; 100 return *this;
148 } 101 }
102
149 const CFX_WideString& CFX_WideString::operator=( 103 const CFX_WideString& CFX_WideString::operator=(
150 const CFX_WideStringC& stringSrc) { 104 const CFX_WideStringC& stringSrc) {
151 if (stringSrc.IsEmpty()) { 105 if (stringSrc.IsEmpty())
152 Empty(); 106 clear();
153 } else { 107 else
154 AssignCopy(stringSrc.GetLength(), stringSrc.c_str()); 108 AssignCopy(stringSrc.c_str(), stringSrc.GetLength());
155 } 109
156 return *this; 110 return *this;
157 } 111 }
112
158 const CFX_WideString& CFX_WideString::operator=( 113 const CFX_WideString& CFX_WideString::operator=(
159 const CFX_WideString& stringSrc) { 114 const CFX_WideString& stringSrc) {
160 if (m_pData == stringSrc.m_pData) { 115 if (m_pData != stringSrc.m_pData)
161 return *this;
162 }
163 if (stringSrc.IsEmpty()) {
164 Empty();
165 } else if ((m_pData && m_pData->m_nRefs < 0) ||
166 (stringSrc.m_pData && stringSrc.m_pData->m_nRefs < 0)) {
167 AssignCopy(stringSrc.m_pData->m_nDataLength, stringSrc.m_pData->m_String);
168 } else {
169 Empty();
170 m_pData = stringSrc.m_pData; 116 m_pData = stringSrc.m_pData;
171 if (m_pData) { 117
172 m_pData->Retain();
173 }
174 }
175 return *this; 118 return *this;
176 } 119 }
177 const CFX_WideString& CFX_WideString::operator+=(FX_WCHAR ch) { 120
178 ConcatInPlace(1, &ch); 121 const CFX_WideString& CFX_WideString::operator+=(const FX_WCHAR* pStr) {
122 if (pStr)
123 Concat(pStr, FXSYS_wcslen(pStr));
124
179 return *this; 125 return *this;
180 } 126 }
181 const CFX_WideString& CFX_WideString::operator+=(const FX_WCHAR* lpsz) { 127
182 if (lpsz) { 128 const CFX_WideString& CFX_WideString::operator+=(FX_WCHAR ch) {
183 ConcatInPlace(FXSYS_wcslen(lpsz), lpsz); 129 Concat(&ch, 1);
184 }
185 return *this; 130 return *this;
186 } 131 }
132
187 const CFX_WideString& CFX_WideString::operator+=(const CFX_WideString& str) { 133 const CFX_WideString& CFX_WideString::operator+=(const CFX_WideString& str) {
188 if (!str.m_pData) { 134 if (str.m_pData)
189 return *this; 135 Concat(str.m_pData->m_String, str.m_pData->m_nDataLength);
190 } 136
191 ConcatInPlace(str.m_pData->m_nDataLength, str.m_pData->m_String);
192 return *this; 137 return *this;
193 } 138 }
139
194 const CFX_WideString& CFX_WideString::operator+=(const CFX_WideStringC& str) { 140 const CFX_WideString& CFX_WideString::operator+=(const CFX_WideStringC& str) {
195 if (str.IsEmpty()) { 141 if (!str.IsEmpty())
196 return *this; 142 Concat(str.c_str(), str.GetLength());
197 } 143
198 ConcatInPlace(str.GetLength(), str.c_str());
199 return *this; 144 return *this;
200 } 145 }
146
201 bool CFX_WideString::operator==(const wchar_t* ptr) const { 147 bool CFX_WideString::operator==(const wchar_t* ptr) const {
202 if (!m_pData) 148 if (!m_pData)
203 return !ptr || !ptr[0]; 149 return !ptr || !ptr[0];
204 150
205 if (!ptr) 151 if (!ptr)
206 return m_pData->m_nDataLength == 0; 152 return m_pData->m_nDataLength == 0;
207 153
208 return wcslen(ptr) == static_cast<size_t>(m_pData->m_nDataLength) && 154 return wcslen(ptr) == static_cast<size_t>(m_pData->m_nDataLength) &&
209 wmemcmp(ptr, m_pData->m_String, m_pData->m_nDataLength) == 0; 155 wmemcmp(ptr, m_pData->m_String, m_pData->m_nDataLength) == 0;
210 } 156 }
157
211 bool CFX_WideString::operator==(const CFX_WideStringC& str) const { 158 bool CFX_WideString::operator==(const CFX_WideStringC& str) const {
212 if (!m_pData) 159 if (!m_pData)
213 return str.IsEmpty(); 160 return str.IsEmpty();
214 161
215 return str.GetLength() == m_pData->m_nDataLength && 162 return m_pData->m_nDataLength == str.GetLength() &&
216 wmemcmp(str.c_str(), m_pData->m_String, m_pData->m_nDataLength) == 0; 163 wmemcmp(m_pData->m_String, str.c_str(), str.GetLength()) == 0;
217 } 164 }
165
218 bool CFX_WideString::operator==(const CFX_WideString& other) const { 166 bool CFX_WideString::operator==(const CFX_WideString& other) const {
219 if (IsEmpty()) 167 if (IsEmpty())
220 return other.IsEmpty(); 168 return other.IsEmpty();
221 169
222 if (other.IsEmpty()) 170 if (other.IsEmpty())
223 return false; 171 return false;
224 172
225 return other.m_pData->m_nDataLength == m_pData->m_nDataLength && 173 return other.m_pData->m_nDataLength == m_pData->m_nDataLength &&
226 wmemcmp(other.m_pData->m_String, m_pData->m_String, 174 wmemcmp(other.m_pData->m_String, m_pData->m_String,
227 m_pData->m_nDataLength) == 0; 175 m_pData->m_nDataLength) == 0;
228 } 176 }
229 void CFX_WideString::Empty() { 177
230 if (m_pData) { 178 void CFX_WideString::AssignCopy(const FX_WCHAR* pSrcData, FX_STRSIZE nSrcLen) {
231 m_pData->Release(); 179 AllocBeforeWrite(nSrcLen);
232 m_pData = NULL; 180 m_pData->CopyContents(pSrcData, nSrcLen);
233 } 181 m_pData->m_nDataLength = nSrcLen;
234 } 182 }
235 void CFX_WideString::ConcatInPlace(FX_STRSIZE nSrcLen, 183
236 const FX_WCHAR* lpszSrcData) { 184 void CFX_WideString::ReallocBeforeWrite(FX_STRSIZE nNewLength) {
237 if (nSrcLen == 0 || !lpszSrcData) { 185 if (m_pData && m_pData->CanOperateInPlace(nNewLength))
186 return;
187
188 if (nNewLength <= 0) {
189 clear();
238 return; 190 return;
239 } 191 }
240 if (!m_pData) { 192
241 m_pData = StringData::Create(nSrcLen); 193 CFX_RetainPtr<StringData> pNewData(StringData::Create(nNewLength));
242 if (m_pData) { 194 if (m_pData) {
243 FXSYS_memcpy(m_pData->m_String, lpszSrcData, nSrcLen * sizeof(FX_WCHAR)); 195 FX_STRSIZE nCopyLength = std::min(m_pData->m_nDataLength, nNewLength);
244 } 196 pNewData->CopyContents(m_pData->m_String, nCopyLength);
197 pNewData->m_nDataLength = nCopyLength;
198 } else {
199 pNewData->m_nDataLength = 0;
200 }
201 pNewData->m_String[pNewData->m_nDataLength] = 0;
202 m_pData.Swap(pNewData);
203 }
204
205 void CFX_WideString::AllocBeforeWrite(FX_STRSIZE nNewLength) {
206 if (m_pData && m_pData->CanOperateInPlace(nNewLength))
207 return;
208
209 if (nNewLength <= 0) {
210 clear();
245 return; 211 return;
246 } 212 }
247 if (m_pData->m_nRefs > 1 || 213
248 m_pData->m_nDataLength + nSrcLen > m_pData->m_nAllocLength) { 214 m_pData.Reset(StringData::Create(nNewLength));
249 ConcatCopy(m_pData->m_nDataLength, m_pData->m_String, nSrcLen, lpszSrcData);
250 } else {
251 FXSYS_memcpy(m_pData->m_String + m_pData->m_nDataLength, lpszSrcData,
252 nSrcLen * sizeof(FX_WCHAR));
253 m_pData->m_nDataLength += nSrcLen;
254 m_pData->m_String[m_pData->m_nDataLength] = 0;
255 }
256 } 215 }
257 void CFX_WideString::ConcatCopy(FX_STRSIZE nSrc1Len, 216
258 const FX_WCHAR* lpszSrc1Data, 217 void CFX_WideString::ReleaseBuffer(FX_STRSIZE nNewLength) {
259 FX_STRSIZE nSrc2Len, 218 if (!m_pData)
260 const FX_WCHAR* lpszSrc2Data) { 219 return;
261 FX_STRSIZE nNewLen = nSrc1Len + nSrc2Len; 220
262 if (nNewLen <= 0) { 221 if (nNewLength == -1)
222 nNewLength = FXSYS_wcslen(m_pData->m_String);
223
224 if (nNewLength == 0) {
225 clear();
263 return; 226 return;
264 } 227 }
265 // Don't release until done copying, might be one of the arguments. 228
266 StringData* pOldData = m_pData; 229 FXSYS_assert(nNewLength <= m_pData->m_nAllocLength);
267 m_pData = StringData::Create(nNewLen); 230 ReallocBeforeWrite(nNewLength);
268 if (m_pData) { 231 m_pData->m_nDataLength = nNewLength;
269 wmemcpy(m_pData->m_String, lpszSrc1Data, nSrc1Len); 232 m_pData->m_String[nNewLength] = 0;
270 wmemcpy(m_pData->m_String + nSrc1Len, lpszSrc2Data, nSrc2Len); 233 }
234
235 void CFX_WideString::Reserve(FX_STRSIZE len) {
236 GetBuffer(len);
237 ReleaseBuffer(GetLength());
238 }
239
240 FX_WCHAR* CFX_WideString::GetBuffer(FX_STRSIZE nMinBufLength) {
241 if (!m_pData) {
242 if (nMinBufLength == 0)
243 return nullptr;
244
245 m_pData.Reset(StringData::Create(nMinBufLength));
246 m_pData->m_nDataLength = 0;
247 m_pData->m_String[0] = 0;
248 return m_pData->m_String;
271 } 249 }
272 pOldData->Release(); 250
251 if (m_pData->CanOperateInPlace(nMinBufLength))
252 return m_pData->m_String;
253
254 nMinBufLength = std::max(nMinBufLength, m_pData->m_nDataLength);
255 if (nMinBufLength == 0)
256 return nullptr;
257
258 CFX_RetainPtr<StringData> pNewData(StringData::Create(nMinBufLength));
259 pNewData->CopyContents(*m_pData);
260 pNewData->m_nDataLength = m_pData->m_nDataLength;
261 m_pData.Swap(pNewData);
262 return m_pData->m_String;
273 } 263 }
274 void CFX_WideString::CopyBeforeWrite() { 264
275 if (!m_pData || m_pData->m_nRefs <= 1) { 265 FX_STRSIZE CFX_WideString::Delete(FX_STRSIZE nIndex, FX_STRSIZE nCount) {
266 if (!m_pData)
267 return 0;
268
269 if (nIndex < 0)
270 nIndex = 0;
271
272 FX_STRSIZE nOldLength = m_pData->m_nDataLength;
273 if (nCount > 0 && nIndex < nOldLength) {
274 FX_STRSIZE mLength = nIndex + nCount;
275 if (mLength >= nOldLength) {
276 m_pData->m_nDataLength = nIndex;
277 return m_pData->m_nDataLength;
278 }
279 ReallocBeforeWrite(nOldLength);
280 int nCharsToCopy = nOldLength - mLength + 1;
281 wmemmove(m_pData->m_String + nIndex, m_pData->m_String + mLength,
282 nCharsToCopy);
283 m_pData->m_nDataLength = nOldLength - nCount;
284 }
285 return m_pData->m_nDataLength;
286 }
287
288 void CFX_WideString::Concat(const FX_WCHAR* pSrcData, FX_STRSIZE nSrcLen) {
289 if (!pSrcData || nSrcLen <= 0)
290 return;
291
292 if (!m_pData) {
293 m_pData.Reset(StringData::Create(pSrcData, nSrcLen));
276 return; 294 return;
277 } 295 }
278 StringData* pData = m_pData; 296
279 m_pData->Release(); 297 if (m_pData->CanOperateInPlace(m_pData->m_nDataLength + nSrcLen)) {
280 FX_STRSIZE nDataLength = pData->m_nDataLength; 298 m_pData->CopyContentsAt(m_pData->m_nDataLength, pSrcData, nSrcLen);
281 m_pData = StringData::Create(nDataLength); 299 m_pData->m_nDataLength += nSrcLen;
282 if (m_pData) {
283 FXSYS_memcpy(m_pData->m_String, pData->m_String,
284 (nDataLength + 1) * sizeof(FX_WCHAR));
285 }
286 }
287 void CFX_WideString::AllocBeforeWrite(FX_STRSIZE nLen) {
288 if (m_pData && m_pData->m_nRefs <= 1 && m_pData->m_nAllocLength >= nLen) {
289 return; 300 return;
290 } 301 }
291 Empty(); 302
292 m_pData = StringData::Create(nLen); 303 CFX_RetainPtr<StringData> pNewData(
304 StringData::Create(m_pData->m_nDataLength + nSrcLen));
305 pNewData->CopyContents(*m_pData);
306 pNewData->CopyContentsAt(m_pData->m_nDataLength, pSrcData, nSrcLen);
307 m_pData.Swap(pNewData);
293 } 308 }
294 void CFX_WideString::AssignCopy(FX_STRSIZE nSrcLen, 309
295 const FX_WCHAR* lpszSrcData) { 310 // static
296 AllocBeforeWrite(nSrcLen);
297 FXSYS_memcpy(m_pData->m_String, lpszSrcData, nSrcLen * sizeof(FX_WCHAR));
298 m_pData->m_nDataLength = nSrcLen;
299 m_pData->m_String[nSrcLen] = 0;
300 }
301 int CFX_WideString::Compare(const FX_WCHAR* lpsz) const {
302 if (m_pData)
303 return FXSYS_wcscmp(m_pData->m_String, lpsz);
304 return (!lpsz || lpsz[0] == 0) ? 0 : -1;
305 }
306 CFX_ByteString CFX_WideString::UTF8Encode() const { 311 CFX_ByteString CFX_WideString::UTF8Encode() const {
307 return FX_UTF8Encode(*this); 312 return FX_UTF8Encode(*this);
308 } 313 }
314
315 // static
309 CFX_ByteString CFX_WideString::UTF16LE_Encode() const { 316 CFX_ByteString CFX_WideString::UTF16LE_Encode() const {
310 if (!m_pData) { 317 if (!m_pData) {
311 return CFX_ByteString("\0\0", 2); 318 return CFX_ByteString("\0\0", 2);
312 } 319 }
313 int len = m_pData->m_nDataLength; 320 int len = m_pData->m_nDataLength;
314 CFX_ByteString result; 321 CFX_ByteString result;
315 FX_CHAR* buffer = result.GetBuffer(len * 2 + 2); 322 FX_CHAR* buffer = result.GetBuffer(len * 2 + 2);
316 for (int i = 0; i < len; i++) { 323 for (int i = 0; i < len; i++) {
317 buffer[i * 2] = m_pData->m_String[i] & 0xff; 324 buffer[i * 2] = m_pData->m_String[i] & 0xff;
318 buffer[i * 2 + 1] = m_pData->m_String[i] >> 8; 325 buffer[i * 2 + 1] = m_pData->m_String[i] >> 8;
319 } 326 }
320 buffer[len * 2] = 0; 327 buffer[len * 2] = 0;
321 buffer[len * 2 + 1] = 0; 328 buffer[len * 2 + 1] = 0;
322 result.ReleaseBuffer(len * 2 + 2); 329 result.ReleaseBuffer(len * 2 + 2);
323 return result; 330 return result;
324 } 331 }
325 332
326 void CFX_WideString::Reserve(FX_STRSIZE len) {
327 GetBuffer(len);
328 ReleaseBuffer(GetLength());
329 }
330 FX_WCHAR* CFX_WideString::GetBuffer(FX_STRSIZE nMinBufLength) {
331 if (!m_pData && nMinBufLength == 0) {
332 return NULL;
333 }
334 if (m_pData && m_pData->m_nRefs <= 1 &&
335 m_pData->m_nAllocLength >= nMinBufLength) {
336 return m_pData->m_String;
337 }
338 if (!m_pData) {
339 m_pData = StringData::Create(nMinBufLength);
340 if (!m_pData) {
341 return NULL;
342 }
343 m_pData->m_nDataLength = 0;
344 m_pData->m_String[0] = 0;
345 return m_pData->m_String;
346 }
347 StringData* pOldData = m_pData;
348 FX_STRSIZE nOldLen = pOldData->m_nDataLength;
349 if (nMinBufLength < nOldLen) {
350 nMinBufLength = nOldLen;
351 }
352 m_pData = StringData::Create(nMinBufLength);
353 if (!m_pData) {
354 return NULL;
355 }
356 FXSYS_memcpy(m_pData->m_String, pOldData->m_String,
357 (nOldLen + 1) * sizeof(FX_WCHAR));
358 m_pData->m_nDataLength = nOldLen;
359 pOldData->Release();
360 return m_pData->m_String;
361 }
362
363 // static
364 CFX_WideString CFX_WideString::FromLocal(const CFX_ByteString& str) {
365 return FromCodePage(str, 0);
366 }
367
368 // static
369 CFX_WideString CFX_WideString::FromCodePage(const CFX_ByteString& str,
370 uint16_t codepage) {
371 return CFX_CharMap::GetWideString(codepage, str);
372 }
373
374 // static
375 CFX_WideString CFX_WideString::FromUTF8(const CFX_ByteStringC& str) {
376 if (str.IsEmpty())
377 return CFX_WideString();
378
379 CFX_UTF8Decoder decoder;
380 for (FX_STRSIZE i = 0; i < str.GetLength(); i++) {
381 decoder.Input(str[i]);
382 }
383 return decoder.GetResult();
384 }
385
386 // static
387 CFX_WideString CFX_WideString::FromUTF16LE(const unsigned short* wstr,
388 FX_STRSIZE wlen) {
389 if (!wstr || 0 == wlen) {
390 return CFX_WideString();
391 }
392
393 CFX_WideString result;
394 FX_WCHAR* buf = result.GetBuffer(wlen);
395 for (int i = 0; i < wlen; i++) {
396 buf[i] = wstr[i];
397 }
398 result.ReleaseBuffer(wlen);
399 return result;
400 }
401
402 FX_STRSIZE CFX_WideString::WStringLength(const unsigned short* str) {
403 FX_STRSIZE len = 0;
404 if (str)
405 while (str[len])
406 len++;
407 return len;
408 }
409
410 void CFX_WideString::AllocCopy(CFX_WideString& dest,
411 FX_STRSIZE nCopyLen,
412 FX_STRSIZE nCopyIndex) const {
413 // |FX_STRSIZE| is currently typedef'd as in |int|. TODO(palmer): It
414 // should be a |size_t|, or at least unsigned.
415 if (nCopyLen == 0 || nCopyLen < 0) {
416 return;
417 }
418 pdfium::base::CheckedNumeric<FX_STRSIZE> iSize =
419 static_cast<FX_STRSIZE>(sizeof(FX_WCHAR));
420 iSize *= nCopyLen;
421 ASSERT(!dest.m_pData);
422 dest.m_pData = StringData::Create(nCopyLen);
423 if (dest.m_pData) {
424 FXSYS_memcpy(dest.m_pData->m_String, m_pData->m_String + nCopyIndex,
425 iSize.ValueOrDie());
426 }
427 }
428 CFX_WideString CFX_WideString::Left(FX_STRSIZE nCount) const {
429 if (!m_pData) {
430 return CFX_WideString();
431 }
432 if (nCount < 0) {
433 nCount = 0;
434 }
435 if (nCount >= m_pData->m_nDataLength) {
436 return *this;
437 }
438 CFX_WideString dest;
439 AllocCopy(dest, nCount, 0);
440 return dest;
441 }
442 CFX_WideString CFX_WideString::Mid(FX_STRSIZE nFirst) const { 333 CFX_WideString CFX_WideString::Mid(FX_STRSIZE nFirst) const {
443 if (!m_pData) 334 if (!m_pData)
444 return CFX_WideString(); 335 return CFX_WideString();
445 336
446 return Mid(nFirst, m_pData->m_nDataLength - nFirst); 337 return Mid(nFirst, m_pData->m_nDataLength - nFirst);
447 } 338 }
339
448 CFX_WideString CFX_WideString::Mid(FX_STRSIZE nFirst, FX_STRSIZE nCount) const { 340 CFX_WideString CFX_WideString::Mid(FX_STRSIZE nFirst, FX_STRSIZE nCount) const {
449 if (!m_pData) 341 if (!m_pData)
450 return CFX_WideString(); 342 return CFX_WideString();
451 343
452 nFirst = std::min(std::max(nFirst, 0), m_pData->m_nDataLength); 344 nFirst = std::min(std::max(nFirst, 0), m_pData->m_nDataLength);
453 nCount = std::min(std::max(nCount, 0), m_pData->m_nDataLength - nFirst); 345 nCount = std::min(std::max(nCount, 0), m_pData->m_nDataLength - nFirst);
346 if (nCount == 0)
347 return CFX_WideString();
348
454 if (nFirst == 0 && nCount == m_pData->m_nDataLength) 349 if (nFirst == 0 && nCount == m_pData->m_nDataLength)
455 return *this; 350 return *this;
456 351
457 CFX_WideString dest; 352 CFX_WideString dest;
458 AllocCopy(dest, nCount, nFirst); 353 AllocCopy(dest, nCount, nFirst);
459 return dest; 354 return dest;
460 } 355 }
461 CFX_WideString CFX_WideString::Right(FX_STRSIZE nCount) const { 356
462 if (!m_pData) { 357 void CFX_WideString::AllocCopy(CFX_WideString& dest,
463 return CFX_WideString(); 358 FX_STRSIZE nCopyLen,
464 } 359 FX_STRSIZE nCopyIndex) const {
465 if (nCount < 0) { 360 if (nCopyLen <= 0)
466 nCount = 0; 361 return;
467 } 362
468 if (nCount >= m_pData->m_nDataLength) { 363 CFX_RetainPtr<StringData> pNewData(
469 return *this; 364 StringData::Create(m_pData->m_String + nCopyIndex, nCopyLen));
470 } 365 dest.m_pData.Swap(pNewData);
471 CFX_WideString dest;
472 AllocCopy(dest, nCount, m_pData->m_nDataLength - nCount);
473 return dest;
474 } 366 }
475 int CFX_WideString::CompareNoCase(const FX_WCHAR* lpsz) const { 367
476 if (!m_pData) {
477 return (!lpsz || lpsz[0] == 0) ? 0 : -1;
478 }
479 return FXSYS_wcsicmp(m_pData->m_String, lpsz);
480 }
481 int CFX_WideString::Compare(const CFX_WideString& str) const {
482 if (!m_pData) {
483 if (!str.m_pData) {
484 return 0;
485 }
486 return -1;
487 }
488 if (!str.m_pData) {
489 return 1;
490 }
491 int this_len = m_pData->m_nDataLength;
492 int that_len = str.m_pData->m_nDataLength;
493 int min_len = this_len < that_len ? this_len : that_len;
494 for (int i = 0; i < min_len; i++) {
495 if (m_pData->m_String[i] < str.m_pData->m_String[i]) {
496 return -1;
497 }
498 if (m_pData->m_String[i] > str.m_pData->m_String[i]) {
499 return 1;
500 }
501 }
502 if (this_len < that_len) {
503 return -1;
504 }
505 if (this_len > that_len) {
506 return 1;
507 }
508 return 0;
509 }
510 void CFX_WideString::SetAt(FX_STRSIZE nIndex, FX_WCHAR ch) {
511 if (!m_pData) {
512 return;
513 }
514 ASSERT(nIndex >= 0);
515 ASSERT(nIndex < m_pData->m_nDataLength);
516 CopyBeforeWrite();
517 m_pData->m_String[nIndex] = ch;
518 }
519 void CFX_WideString::MakeLower() {
520 if (!m_pData) {
521 return;
522 }
523 CopyBeforeWrite();
524 if (GetLength() < 1) {
525 return;
526 }
527 FXSYS_wcslwr(m_pData->m_String);
528 }
529 void CFX_WideString::MakeUpper() {
530 if (!m_pData) {
531 return;
532 }
533 CopyBeforeWrite();
534 if (GetLength() < 1) {
535 return;
536 }
537 FXSYS_wcsupr(m_pData->m_String);
538 }
539 FX_STRSIZE CFX_WideString::Find(const FX_WCHAR* lpszSub,
540 FX_STRSIZE nStart) const {
541 FX_STRSIZE nLength = GetLength();
542 if (nLength < 1 || nStart > nLength) {
543 return -1;
544 }
545 const FX_WCHAR* lpsz = FXSYS_wcsstr(m_pData->m_String + nStart, lpszSub);
546 return lpsz ? (int)(lpsz - m_pData->m_String) : -1;
547 }
548 FX_STRSIZE CFX_WideString::Find(FX_WCHAR ch, FX_STRSIZE nStart) const {
549 if (!m_pData) {
550 return -1;
551 }
552 FX_STRSIZE nLength = m_pData->m_nDataLength;
553 if (nStart >= nLength) {
554 return -1;
555 }
556 const FX_WCHAR* lpsz = FXSYS_wcschr(m_pData->m_String + nStart, ch);
557 return (lpsz) ? (int)(lpsz - m_pData->m_String) : -1;
558 }
559 void CFX_WideString::TrimRight(const FX_WCHAR* lpszTargetList) {
560 FXSYS_assert(lpszTargetList);
561 if (!m_pData || *lpszTargetList == 0) {
562 return;
563 }
564 CopyBeforeWrite();
565 FX_STRSIZE len = GetLength();
566 if (len < 1) {
567 return;
568 }
569 FX_STRSIZE pos = len;
570 while (pos) {
571 if (!FXSYS_wcschr(lpszTargetList, m_pData->m_String[pos - 1])) {
572 break;
573 }
574 pos--;
575 }
576 if (pos < len) {
577 m_pData->m_String[pos] = 0;
578 m_pData->m_nDataLength = pos;
579 }
580 }
581 void CFX_WideString::TrimRight(FX_WCHAR chTarget) {
582 FX_WCHAR str[2] = {chTarget, 0};
583 TrimRight(str);
584 }
585 void CFX_WideString::TrimRight() {
586 TrimRight(L"\x09\x0a\x0b\x0c\x0d\x20");
587 }
588 void CFX_WideString::TrimLeft(const FX_WCHAR* lpszTargets) {
589 FXSYS_assert(lpszTargets);
590 if (!m_pData || *lpszTargets == 0) {
591 return;
592 }
593 CopyBeforeWrite();
594 if (GetLength() < 1) {
595 return;
596 }
597 const FX_WCHAR* lpsz = m_pData->m_String;
598 while (*lpsz != 0) {
599 if (!FXSYS_wcschr(lpszTargets, *lpsz)) {
600 break;
601 }
602 lpsz++;
603 }
604 if (lpsz != m_pData->m_String) {
605 int nDataLength =
606 m_pData->m_nDataLength - (FX_STRSIZE)(lpsz - m_pData->m_String);
607 FXSYS_memmove(m_pData->m_String, lpsz,
608 (nDataLength + 1) * sizeof(FX_WCHAR));
609 m_pData->m_nDataLength = nDataLength;
610 }
611 }
612 void CFX_WideString::TrimLeft(FX_WCHAR chTarget) {
613 FX_WCHAR str[2] = {chTarget, 0};
614 TrimLeft(str);
615 }
616 void CFX_WideString::TrimLeft() {
617 TrimLeft(L"\x09\x0a\x0b\x0c\x0d\x20");
618 }
619 FX_STRSIZE CFX_WideString::Replace(const FX_WCHAR* lpszOld,
620 const FX_WCHAR* lpszNew) {
621 if (GetLength() < 1) {
622 return 0;
623 }
624 if (!lpszOld) {
625 return 0;
626 }
627 FX_STRSIZE nSourceLen = FXSYS_wcslen(lpszOld);
628 if (nSourceLen == 0) {
629 return 0;
630 }
631 FX_STRSIZE nReplacementLen = lpszNew ? FXSYS_wcslen(lpszNew) : 0;
632 FX_STRSIZE nCount = 0;
633 FX_WCHAR* lpszStart = m_pData->m_String;
634 FX_WCHAR* lpszEnd = m_pData->m_String + m_pData->m_nDataLength;
635 while (lpszStart < lpszEnd) {
636 FX_WCHAR* lpszTarget = FXSYS_wcsstr(lpszStart, lpszOld);
637 if (!lpszTarget)
638 break;
639 nCount++;
640 lpszStart = lpszTarget + nSourceLen;
641 }
642 if (nCount > 0) {
643 CopyBeforeWrite();
644 FX_STRSIZE nOldLength = m_pData->m_nDataLength;
645 FX_STRSIZE nNewLength =
646 nOldLength + (nReplacementLen - nSourceLen) * nCount;
647 if (m_pData->m_nAllocLength < nNewLength || m_pData->m_nRefs > 1) {
648 StringData* pOldData = m_pData;
649 const FX_WCHAR* pstr = m_pData->m_String;
650 m_pData = StringData::Create(nNewLength);
651 if (!m_pData) {
652 return 0;
653 }
654 FXSYS_memcpy(m_pData->m_String, pstr,
655 pOldData->m_nDataLength * sizeof(FX_WCHAR));
656 pOldData->Release();
657 }
658 lpszStart = m_pData->m_String;
659 lpszEnd = m_pData->m_String + std::max(m_pData->m_nDataLength, nNewLength);
660 {
661 while (lpszStart < lpszEnd) {
662 FX_WCHAR* lpszTarget = FXSYS_wcsstr(lpszStart, lpszOld);
663 if (!lpszTarget)
664 break;
665 FX_STRSIZE nBalance =
666 nOldLength -
667 (FX_STRSIZE)(lpszTarget - m_pData->m_String + nSourceLen);
668 FXSYS_memmove(lpszTarget + nReplacementLen, lpszTarget + nSourceLen,
669 nBalance * sizeof(FX_WCHAR));
670 FXSYS_memcpy(lpszTarget, lpszNew, nReplacementLen * sizeof(FX_WCHAR));
671 lpszStart = lpszTarget + nReplacementLen;
672 lpszStart[nBalance] = 0;
673 nOldLength += (nReplacementLen - nSourceLen);
674 }
675 }
676 ASSERT(m_pData->m_String[nNewLength] == 0);
677 m_pData->m_nDataLength = nNewLength;
678 }
679 return nCount;
680 }
681 FX_STRSIZE CFX_WideString::Insert(FX_STRSIZE nIndex, FX_WCHAR ch) {
682 CopyBeforeWrite();
683 if (nIndex < 0) {
684 nIndex = 0;
685 }
686 FX_STRSIZE nNewLength = GetLength();
687 if (nIndex > nNewLength) {
688 nIndex = nNewLength;
689 }
690 nNewLength++;
691 if (!m_pData || m_pData->m_nAllocLength < nNewLength) {
692 StringData* pOldData = m_pData;
693 const FX_WCHAR* pstr = m_pData->m_String;
694 m_pData = StringData::Create(nNewLength);
695 if (!m_pData) {
696 return 0;
697 }
698 if (pOldData) {
699 FXSYS_memmove(m_pData->m_String, pstr,
700 (pOldData->m_nDataLength + 1) * sizeof(FX_WCHAR));
701 pOldData->Release();
702 } else {
703 m_pData->m_String[0] = 0;
704 }
705 }
706 FXSYS_memmove(m_pData->m_String + nIndex + 1, m_pData->m_String + nIndex,
707 (nNewLength - nIndex) * sizeof(FX_WCHAR));
708 m_pData->m_String[nIndex] = ch;
709 m_pData->m_nDataLength = nNewLength;
710 return nNewLength;
711 }
712 FX_STRSIZE CFX_WideString::Delete(FX_STRSIZE nIndex, FX_STRSIZE nCount) {
713 if (GetLength() < 1) {
714 return 0;
715 }
716 if (nIndex < 0) {
717 nIndex = 0;
718 }
719 FX_STRSIZE nOldLength = m_pData->m_nDataLength;
720 if (nCount > 0 && nIndex < nOldLength) {
721 CopyBeforeWrite();
722 int nBytesToCopy = nOldLength - (nIndex + nCount) + 1;
723 FXSYS_memmove(m_pData->m_String + nIndex,
724 m_pData->m_String + nIndex + nCount,
725 nBytesToCopy * sizeof(FX_WCHAR));
726 m_pData->m_nDataLength = nOldLength - nCount;
727 }
728 return m_pData->m_nDataLength;
729 }
730 FX_STRSIZE CFX_WideString::Remove(FX_WCHAR chRemove) {
731 if (!m_pData) {
732 return 0;
733 }
734 CopyBeforeWrite();
735 if (GetLength() < 1) {
736 return 0;
737 }
738 FX_WCHAR* pstrSource = m_pData->m_String;
739 FX_WCHAR* pstrDest = m_pData->m_String;
740 FX_WCHAR* pstrEnd = m_pData->m_String + m_pData->m_nDataLength;
741 while (pstrSource < pstrEnd) {
742 if (*pstrSource != chRemove) {
743 *pstrDest = *pstrSource;
744 pstrDest++;
745 }
746 pstrSource++;
747 }
748 *pstrDest = 0;
749 FX_STRSIZE nCount = (FX_STRSIZE)(pstrSource - pstrDest);
750 m_pData->m_nDataLength -= nCount;
751 return nCount;
752 }
753 #define FORCE_ANSI 0x10000 368 #define FORCE_ANSI 0x10000
754 #define FORCE_UNICODE 0x20000 369 #define FORCE_UNICODE 0x20000
755 #define FORCE_INT64 0x40000 370 #define FORCE_INT64 0x40000
756 void CFX_WideString::FormatV(const FX_WCHAR* lpszFormat, va_list argList) { 371
372 void CFX_WideString::FormatV(const FX_WCHAR* pFormat, va_list argList) {
757 va_list argListSave; 373 va_list argListSave;
758 #if defined(__ARMCC_VERSION) || \ 374 #if defined(__ARMCC_VERSION) || \
759 (!defined(_MSC_VER) && (_FX_CPU_ == _FX_X64_ || _FX_CPU_ == _FX_IA64_ || \ 375 (!defined(_MSC_VER) && (_FX_CPU_ == _FX_X64_ || _FX_CPU_ == _FX_IA64_ || \
760 _FX_CPU_ == _FX_ARM64_)) || \ 376 _FX_CPU_ == _FX_ARM64_)) || \
761 defined(__native_client__) 377 defined(__native_client__)
762 va_copy(argListSave, argList); 378 va_copy(argListSave, argList);
763 #else 379 #else
764 argListSave = argList; 380 argListSave = argList;
765 #endif 381 #endif
766 int nMaxLen = 0; 382 int nMaxLen = 0;
767 for (const FX_WCHAR* lpsz = lpszFormat; *lpsz != 0; lpsz++) { 383 for (const FX_WCHAR* pStr = pFormat; *pStr != 0; pStr++) {
768 if (*lpsz != '%' || *(lpsz = lpsz + 1) == '%') { 384 if (*pStr != '%' || *(pStr = pStr + 1) == '%') {
769 nMaxLen += FXSYS_wcslen(lpsz); 385 nMaxLen += FXSYS_wcslen(pStr);
770 continue; 386 continue;
771 } 387 }
772 int nItemLen = 0; 388 int nItemLen = 0;
773 int nWidth = 0; 389 int nWidth = 0;
774 for (; *lpsz != 0; lpsz++) { 390 for (; *pStr != 0; pStr++) {
775 if (*lpsz == '#') { 391 if (*pStr == '#') {
776 nMaxLen += 2; 392 nMaxLen += 2;
777 } else if (*lpsz == '*') { 393 } else if (*pStr == '*') {
778 nWidth = va_arg(argList, int); 394 nWidth = va_arg(argList, int);
779 } else if (*lpsz != '-' && *lpsz != '+' && *lpsz != '0' && *lpsz != ' ') { 395 } else if (*pStr != '-' && *pStr != '+' && *pStr != '0' && *pStr != ' ') {
780 break; 396 break;
781 } 397 }
782 } 398 }
783 if (nWidth == 0) { 399 if (nWidth == 0) {
784 nWidth = FXSYS_wtoi(lpsz); 400 nWidth = FXSYS_wtoi(pStr);
785 while (std::iswdigit(*lpsz)) 401 while (std::iswdigit(*pStr))
786 ++lpsz; 402 ++pStr;
787 } 403 }
788 if (nWidth < 0 || nWidth > 128 * 1024) { 404 if (nWidth < 0 || nWidth > 128 * 1024) {
789 lpszFormat = L"Bad width"; 405 pFormat = L"Bad width";
790 nMaxLen = 10; 406 nMaxLen = 10;
791 break; 407 break;
792 } 408 }
793 int nPrecision = 0; 409 int nPrecision = 0;
794 if (*lpsz == '.') { 410 if (*pStr == '.') {
795 lpsz++; 411 pStr++;
796 if (*lpsz == '*') { 412 if (*pStr == '*') {
797 nPrecision = va_arg(argList, int); 413 nPrecision = va_arg(argList, int);
798 lpsz++; 414 pStr++;
799 } else { 415 } else {
800 nPrecision = FXSYS_wtoi(lpsz); 416 nPrecision = FXSYS_wtoi(pStr);
801 while (std::iswdigit(*lpsz)) 417 while (std::iswdigit(*pStr))
802 ++lpsz; 418 ++pStr;
803 } 419 }
804 } 420 }
805 if (nPrecision < 0 || nPrecision > 128 * 1024) { 421 if (nPrecision < 0 || nPrecision > 128 * 1024) {
806 lpszFormat = L"Bad precision"; 422 pFormat = L"Bad precision";
807 nMaxLen = 14; 423 nMaxLen = 14;
808 break; 424 break;
809 } 425 }
810 int nModifier = 0; 426 int nModifier = 0;
811 if (*lpsz == L'I' && *(lpsz + 1) == L'6' && *(lpsz + 2) == L'4') { 427 if (*pStr == L'I' && *(pStr + 1) == L'6' && *(pStr + 2) == L'4') {
812 lpsz += 3; 428 pStr += 3;
813 nModifier = FORCE_INT64; 429 nModifier = FORCE_INT64;
814 } else { 430 } else {
815 switch (*lpsz) { 431 switch (*pStr) {
816 case 'h': 432 case 'h':
817 nModifier = FORCE_ANSI; 433 nModifier = FORCE_ANSI;
818 lpsz++; 434 pStr++;
819 break; 435 break;
820 case 'l': 436 case 'l':
821 nModifier = FORCE_UNICODE; 437 nModifier = FORCE_UNICODE;
822 lpsz++; 438 pStr++;
823 break; 439 break;
824 case 'F': 440 case 'F':
825 case 'N': 441 case 'N':
826 case 'L': 442 case 'L':
827 lpsz++; 443 pStr++;
828 break; 444 break;
829 } 445 }
830 } 446 }
831 switch (*lpsz | nModifier) { 447 switch (*pStr | nModifier) {
832 case 'c': 448 case 'c':
833 case 'C': 449 case 'C':
834 nItemLen = 2; 450 nItemLen = 2;
835 va_arg(argList, int); 451 va_arg(argList, int);
836 break; 452 break;
837 case 'c' | FORCE_ANSI: 453 case 'c' | FORCE_ANSI:
838 case 'C' | FORCE_ANSI: 454 case 'C' | FORCE_ANSI:
839 nItemLen = 2; 455 nItemLen = 2;
840 va_arg(argList, int); 456 va_arg(argList, int);
841 break; 457 break;
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
873 nItemLen = FXSYS_strlen(pstrNextArg); 489 nItemLen = FXSYS_strlen(pstrNextArg);
874 if (nItemLen < 1) { 490 if (nItemLen < 1) {
875 nItemLen = 1; 491 nItemLen = 1;
876 } 492 }
877 } else { 493 } else {
878 nItemLen = 6; 494 nItemLen = 6;
879 } 495 }
880 } break; 496 } break;
881 case 's' | FORCE_UNICODE: 497 case 's' | FORCE_UNICODE:
882 case 'S' | FORCE_UNICODE: { 498 case 'S' | FORCE_UNICODE: {
883 FX_WCHAR* pstrNextArg = va_arg(argList, FX_WCHAR*); 499 const FX_WCHAR* pstrNextArg = va_arg(argList, FX_WCHAR*);
884 if (pstrNextArg) { 500 if (pstrNextArg) {
885 nItemLen = FXSYS_wcslen(pstrNextArg); 501 nItemLen = FXSYS_wcslen(pstrNextArg);
886 if (nItemLen < 1) { 502 if (nItemLen < 1) {
887 nItemLen = 1; 503 nItemLen = 1;
888 } 504 }
889 } else { 505 } else {
890 nItemLen = 6; 506 nItemLen = 6;
891 } 507 }
892 } break; 508 } break;
893 } 509 }
894 if (nItemLen != 0) { 510 if (nItemLen != 0) {
895 if (nPrecision != 0 && nItemLen > nPrecision) { 511 if (nPrecision != 0 && nItemLen > nPrecision) {
896 nItemLen = nPrecision; 512 nItemLen = nPrecision;
897 } 513 }
898 if (nItemLen < nWidth) { 514 if (nItemLen < nWidth) {
899 nItemLen = nWidth; 515 nItemLen = nWidth;
900 } 516 }
901 } else { 517 } else {
902 switch (*lpsz) { 518 switch (*pStr) {
903 case 'd': 519 case 'd':
904 case 'i': 520 case 'i':
905 case 'u': 521 case 'u':
906 case 'x': 522 case 'x':
907 case 'X': 523 case 'X':
908 case 'o': 524 case 'o':
909 if (nModifier & FORCE_INT64) { 525 if (nModifier & FORCE_INT64) {
910 va_arg(argList, int64_t); 526 va_arg(argList, int64_t);
911 } else { 527 } else {
912 va_arg(argList, int); 528 va_arg(argList, int);
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
950 case 'n': 566 case 'n':
951 va_arg(argList, int*); 567 va_arg(argList, int*);
952 break; 568 break;
953 } 569 }
954 } 570 }
955 nMaxLen += nItemLen; 571 nMaxLen += nItemLen;
956 } 572 }
957 GetBuffer(nMaxLen); 573 GetBuffer(nMaxLen);
958 if (m_pData) { 574 if (m_pData) {
959 FXSYS_vswprintf((wchar_t*)m_pData->m_String, nMaxLen + 1, 575 FXSYS_vswprintf((wchar_t*)m_pData->m_String, nMaxLen + 1,
960 (const wchar_t*)lpszFormat, argListSave); 576 (const wchar_t*)pFormat, argListSave);
961 ReleaseBuffer(); 577 ReleaseBuffer();
962 } 578 }
963 va_end(argListSave); 579 va_end(argListSave);
964 } 580 }
965 void CFX_WideString::Format(const FX_WCHAR* lpszFormat, ...) { 581
582 void CFX_WideString::Format(const FX_WCHAR* pFormat, ...) {
966 va_list argList; 583 va_list argList;
967 va_start(argList, lpszFormat); 584 va_start(argList, pFormat);
968 FormatV(lpszFormat, argList); 585 FormatV(pFormat, argList);
969 va_end(argList); 586 va_end(argList);
970 } 587 }
588
589 FX_STRSIZE CFX_WideString::Insert(FX_STRSIZE nIndex, FX_WCHAR ch) {
590 FX_STRSIZE nNewLength = m_pData ? m_pData->m_nDataLength : 0;
591 nIndex = std::max(nIndex, 0);
592 nIndex = std::min(nIndex, nNewLength);
593 nNewLength++;
594
595 ReallocBeforeWrite(nNewLength);
596 wmemmove(m_pData->m_String + nIndex + 1, m_pData->m_String + nIndex,
597 nNewLength - nIndex);
598 m_pData->m_String[nIndex] = ch;
599 m_pData->m_nDataLength = nNewLength;
600 return nNewLength;
601 }
602
603 CFX_WideString CFX_WideString::Right(FX_STRSIZE nCount) const {
604 if (!m_pData)
605 return CFX_WideString();
606
607 nCount = std::max(nCount, 0);
608 if (nCount >= m_pData->m_nDataLength)
609 return *this;
610
611 CFX_WideString dest;
612 AllocCopy(dest, nCount, m_pData->m_nDataLength - nCount);
613 return dest;
614 }
615
616 CFX_WideString CFX_WideString::Left(FX_STRSIZE nCount) const {
617 if (!m_pData)
618 return CFX_WideString();
619
620 nCount = std::max(nCount, 0);
621 if (nCount >= m_pData->m_nDataLength)
622 return *this;
623
624 CFX_WideString dest;
625 AllocCopy(dest, nCount, 0);
626 return dest;
627 }
628
629 FX_STRSIZE CFX_WideString::Find(FX_WCHAR ch, FX_STRSIZE nStart) const {
630 if (!m_pData)
631 return -1;
632
633 if (nStart >= m_pData->m_nDataLength)
634 return -1;
635
636 const FX_WCHAR* pStr = FXSYS_wcschr(m_pData->m_String + nStart, ch);
637 return pStr ? (int)(pStr - m_pData->m_String) : -1;
638 }
639
640 FX_STRSIZE CFX_WideString::Find(const CFX_WideStringC& pSub,
641 FX_STRSIZE nStart) const {
642 if (!m_pData)
643 return -1;
644
645 FX_STRSIZE nLength = m_pData->m_nDataLength;
646 if (nStart > nLength)
647 return -1;
648
649 const FX_WCHAR* pStr =
650 FX_wcsstr(m_pData->m_String + nStart, m_pData->m_nDataLength - nStart,
651 pSub.c_str(), pSub.GetLength());
652 return pStr ? (int)(pStr - m_pData->m_String) : -1;
653 }
654
655 void CFX_WideString::MakeLower() {
656 if (!m_pData)
657 return;
658
659 ReallocBeforeWrite(m_pData->m_nDataLength);
660 FXSYS_wcslwr(m_pData->m_String);
661 }
662
663 void CFX_WideString::MakeUpper() {
664 if (!m_pData)
665 return;
666
667 ReallocBeforeWrite(m_pData->m_nDataLength);
668 FXSYS_wcsupr(m_pData->m_String);
669 }
670
671 FX_STRSIZE CFX_WideString::Remove(FX_WCHAR chRemove) {
672 if (!m_pData || m_pData->m_nDataLength < 1)
673 return 0;
674
675 ReallocBeforeWrite(m_pData->m_nDataLength);
676 FX_WCHAR* pstrSource = m_pData->m_String;
677 FX_WCHAR* pstrDest = m_pData->m_String;
678 FX_WCHAR* pstrEnd = m_pData->m_String + m_pData->m_nDataLength;
679 while (pstrSource < pstrEnd) {
680 if (*pstrSource != chRemove) {
681 *pstrDest = *pstrSource;
682 pstrDest++;
683 }
684 pstrSource++;
685 }
686 *pstrDest = 0;
687 FX_STRSIZE nCount = (FX_STRSIZE)(pstrSource - pstrDest);
688 m_pData->m_nDataLength -= nCount;
689 return nCount;
690 }
691
692 FX_STRSIZE CFX_WideString::Replace(const CFX_WideStringC& pOld,
693 const CFX_WideStringC& pNew) {
694 if (!m_pData || pOld.IsEmpty())
695 return 0;
696
697 FX_STRSIZE nSourceLen = pOld.GetLength();
698 FX_STRSIZE nReplacementLen = pNew.GetLength();
699 FX_STRSIZE nCount = 0;
700 const FX_WCHAR* pStart = m_pData->m_String;
701 FX_WCHAR* pEnd = m_pData->m_String + m_pData->m_nDataLength;
702 while (1) {
703 const FX_WCHAR* pTarget = FX_wcsstr(pStart, (FX_STRSIZE)(pEnd - pStart),
704 pOld.c_str(), nSourceLen);
705 if (!pTarget)
706 break;
707
708 nCount++;
709 pStart = pTarget + nSourceLen;
710 }
711 if (nCount == 0)
712 return 0;
713
714 FX_STRSIZE nNewLength =
715 m_pData->m_nDataLength + (nReplacementLen - nSourceLen) * nCount;
716
717 if (nNewLength == 0) {
718 clear();
719 return nCount;
720 }
721
722 CFX_RetainPtr<StringData> pNewData(StringData::Create(nNewLength));
723 pStart = m_pData->m_String;
724 FX_WCHAR* pDest = pNewData->m_String;
725 for (FX_STRSIZE i = 0; i < nCount; i++) {
726 const FX_WCHAR* pTarget = FX_wcsstr(pStart, (FX_STRSIZE)(pEnd - pStart),
727 pOld.c_str(), nSourceLen);
728 wmemcpy(pDest, pStart, pTarget - pStart);
729 pDest += pTarget - pStart;
730 wmemcpy(pDest, pNew.c_str(), pNew.GetLength());
731 pDest += pNew.GetLength();
732 pStart = pTarget + nSourceLen;
733 }
734 wmemcpy(pDest, pStart, pEnd - pStart);
735 m_pData.Swap(pNewData);
736 return nCount;
737 }
738
739 void CFX_WideString::SetAt(FX_STRSIZE nIndex, FX_WCHAR ch) {
740 if (!m_pData) {
741 return;
742 }
743 ASSERT(nIndex >= 0);
744 ASSERT(nIndex < m_pData->m_nDataLength);
745 ReallocBeforeWrite(m_pData->m_nDataLength);
746 m_pData->m_String[nIndex] = ch;
747 }
748
749 // static
750 CFX_WideString CFX_WideString::FromLocal(const CFX_ByteString& str) {
751 return FromCodePage(str, 0);
752 }
753
754 // static
755 CFX_WideString CFX_WideString::FromCodePage(const CFX_ByteString& str,
756 uint16_t codepage) {
757 return CFX_CharMap::GetWideString(codepage, str);
758 }
759
760 // static
761 CFX_WideString CFX_WideString::FromUTF8(const CFX_ByteStringC& str) {
762 if (str.IsEmpty())
763 return CFX_WideString();
764
765 CFX_UTF8Decoder decoder;
766 for (FX_STRSIZE i = 0; i < str.GetLength(); i++) {
767 decoder.Input(str[i]);
768 }
769 return decoder.GetResult();
770 }
771
772 // static
773 CFX_WideString CFX_WideString::FromUTF16LE(const unsigned short* wstr,
774 FX_STRSIZE wlen) {
775 if (!wstr || 0 == wlen) {
776 return CFX_WideString();
777 }
778
779 CFX_WideString result;
780 FX_WCHAR* buf = result.GetBuffer(wlen);
781 for (int i = 0; i < wlen; i++) {
782 buf[i] = wstr[i];
783 }
784 result.ReleaseBuffer(wlen);
785 return result;
786 }
787
788 int CFX_WideString::Compare(const FX_WCHAR* lpsz) const {
789 if (m_pData)
790 return FXSYS_wcscmp(m_pData->m_String, lpsz);
791 return (!lpsz || lpsz[0] == 0) ? 0 : -1;
792 }
793
794 int CFX_WideString::Compare(const CFX_WideString& str) const {
795 if (!m_pData) {
796 if (!str.m_pData) {
797 return 0;
798 }
799 return -1;
800 }
801 if (!str.m_pData) {
802 return 1;
803 }
804 int this_len = m_pData->m_nDataLength;
805 int that_len = str.m_pData->m_nDataLength;
806 int min_len = this_len < that_len ? this_len : that_len;
807 for (int i = 0; i < min_len; i++) {
808 if (m_pData->m_String[i] < str.m_pData->m_String[i]) {
809 return -1;
810 }
811 if (m_pData->m_String[i] > str.m_pData->m_String[i]) {
812 return 1;
813 }
814 }
815 if (this_len < that_len) {
816 return -1;
817 }
818 if (this_len > that_len) {
819 return 1;
820 }
821 return 0;
822 }
823
824 int CFX_WideString::CompareNoCase(const FX_WCHAR* lpsz) const {
825 if (!m_pData) {
826 return (!lpsz || lpsz[0] == 0) ? 0 : -1;
827 }
828 return FXSYS_wcsicmp(m_pData->m_String, lpsz);
829 }
830
831 FX_STRSIZE CFX_WideString::WStringLength(const unsigned short* str) {
832 FX_STRSIZE len = 0;
833 if (str)
834 while (str[len])
835 len++;
836 return len;
837 }
838
839 void CFX_WideString::TrimRight(const CFX_WideStringC& pTargets) {
840 if (!m_pData || pTargets.IsEmpty()) {
841 return;
842 }
843 ReallocBeforeWrite(m_pData->m_nDataLength);
844 FX_STRSIZE pos = GetLength();
845 if (pos < 1) {
846 return;
847 }
848 while (pos) {
849 if (!FXSYS_wcschr(pTargets.c_str(), m_pData->m_String[pos - 1])) {
850 break;
851 }
852 pos--;
853 }
854 if (pos < m_pData->m_nDataLength) {
855 m_pData->m_String[pos] = 0;
856 m_pData->m_nDataLength = pos;
857 }
858 }
859
860 void CFX_WideString::TrimRight(FX_WCHAR chTarget) {
861 FX_WCHAR str[2] = {chTarget, 0};
862 TrimRight(str);
863 }
864
865 void CFX_WideString::TrimRight() {
866 TrimRight(L"\x09\x0a\x0b\x0c\x0d\x20");
867 }
868
869 void CFX_WideString::TrimLeft(const CFX_WideStringC& pTargets) {
870 if (!m_pData || pTargets.IsEmpty())
871 return;
872
873 FX_STRSIZE len = GetLength();
874 if (len < 1)
875 return;
876
877 ReallocBeforeWrite(len);
878 const FX_WCHAR* lpsz = m_pData->m_String;
879 while (*lpsz != 0) {
880 if (!FXSYS_wcschr(pTargets.c_str(), *lpsz)) {
881 break;
882 }
883 lpsz++;
884 }
885 if (lpsz != m_pData->m_String) {
886 int nDataLength =
887 m_pData->m_nDataLength - (FX_STRSIZE)(lpsz - m_pData->m_String);
888 FXSYS_memmove(m_pData->m_String, lpsz,
889 (nDataLength + 1) * sizeof(FX_WCHAR));
890 m_pData->m_nDataLength = nDataLength;
891 }
892 }
893
894 void CFX_WideString::TrimLeft(FX_WCHAR chTarget) {
895 FX_WCHAR str[2] = {chTarget, 0};
896 TrimLeft(str);
897 }
898
899 void CFX_WideString::TrimLeft() {
900 TrimLeft(L"\x09\x0a\x0b\x0c\x0d\x20");
901 }
971 FX_FLOAT FX_wtof(const FX_WCHAR* str, int len) { 902 FX_FLOAT FX_wtof(const FX_WCHAR* str, int len) {
972 if (len == 0) { 903 if (len == 0) {
973 return 0.0; 904 return 0.0;
974 } 905 }
975 int cc = 0; 906 int cc = 0;
976 FX_BOOL bNegative = FALSE; 907 FX_BOOL bNegative = FALSE;
977 if (str[0] == '+') { 908 if (str[0] == '+') {
978 cc++; 909 cc++;
979 } else if (str[0] == '-') { 910 } else if (str[0] == '-') {
980 bNegative = TRUE; 911 bNegative = TRUE;
(...skipping 13 matching lines...) Expand all
994 FX_FLOAT scale = 0.1f; 925 FX_FLOAT scale = 0.1f;
995 while (cc < len) { 926 while (cc < len) {
996 fraction += scale * FXSYS_toDecimalDigit(str[cc]); 927 fraction += scale * FXSYS_toDecimalDigit(str[cc]);
997 scale *= 0.1f; 928 scale *= 0.1f;
998 cc++; 929 cc++;
999 } 930 }
1000 } 931 }
1001 fraction += (FX_FLOAT)integer; 932 fraction += (FX_FLOAT)integer;
1002 return bNegative ? -fraction : fraction; 933 return bNegative ? -fraction : fraction;
1003 } 934 }
935
1004 int CFX_WideString::GetInteger() const { 936 int CFX_WideString::GetInteger() const {
1005 return m_pData ? FXSYS_wtoi(m_pData->m_String) : 0; 937 return m_pData ? FXSYS_wtoi(m_pData->m_String) : 0;
1006 } 938 }
939
1007 FX_FLOAT CFX_WideString::GetFloat() const { 940 FX_FLOAT CFX_WideString::GetFloat() const {
1008 return m_pData ? FX_wtof(m_pData->m_String, m_pData->m_nDataLength) : 0.0f; 941 return m_pData ? FX_wtof(m_pData->m_String, m_pData->m_nDataLength) : 0.0f;
1009 } 942 }
1010 943
1011 // static 944 // static
1012 CFX_ByteString CFX_CharMap::GetByteString(uint16_t codepage, 945 CFX_ByteString CFX_CharMap::GetByteString(uint16_t codepage,
1013 const CFX_WideString& wstr) { 946 const CFX_WideString& wstr) {
1014 FXSYS_assert(IsValidCodePage(codepage)); 947 FXSYS_assert(IsValidCodePage(codepage));
1015 int src_len = wstr.GetLength(); 948 int src_len = wstr.GetLength();
1016 int dest_len = FXSYS_WideCharToMultiByte(codepage, 0, wstr.c_str(), src_len, 949 int dest_len = FXSYS_WideCharToMultiByte(codepage, 0, wstr.c_str(), src_len,
(...skipping 16 matching lines...) Expand all
1033 int dest_len = 966 int dest_len =
1034 FXSYS_MultiByteToWideChar(codepage, 0, bstr, src_len, nullptr, 0); 967 FXSYS_MultiByteToWideChar(codepage, 0, bstr, src_len, nullptr, 0);
1035 CFX_WideString wstr; 968 CFX_WideString wstr;
1036 if (dest_len) { 969 if (dest_len) {
1037 FX_WCHAR* dest_buf = wstr.GetBuffer(dest_len); 970 FX_WCHAR* dest_buf = wstr.GetBuffer(dest_len);
1038 FXSYS_MultiByteToWideChar(codepage, 0, bstr, src_len, dest_buf, dest_len); 971 FXSYS_MultiByteToWideChar(codepage, 0, bstr, src_len, dest_buf, dest_len);
1039 wstr.ReleaseBuffer(dest_len); 972 wstr.ReleaseBuffer(dest_len);
1040 } 973 }
1041 return wstr; 974 return wstr;
1042 } 975 }
OLDNEW
« no previous file with comments | « core/fxcrt/fx_basic_bstring.cpp ('k') | core/fxcrt/fx_basic_wstring_unittest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698