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

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

Issue 1810823002: Use CFX_RetainPtr to ref count CFX_ByteString (Closed) Base URL: https://pdfium.googlesource.com/pdfium.git@retain_ptr
Patch Set: Add asserts, comments, min(max()). 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 | « no previous file | core/fxcrt/fx_basic_bstring_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 <cctype> 9 #include <cctype>
10 10
(...skipping 25 matching lines...) Expand all
36 } 36 }
37 if ((flags & FXFORMAT_SIGNED) && i < 0) { 37 if ((flags & FXFORMAT_SIGNED) && i < 0) {
38 buf1[buf_pos--] = '-'; 38 buf1[buf_pos--] = '-';
39 } 39 }
40 int len = 31 - buf_pos; 40 int len = 31 - buf_pos;
41 for (int ii = 0; ii < len; ii++) { 41 for (int ii = 0; ii < len; ii++) {
42 buf[ii] = buf1[ii + buf_pos + 1]; 42 buf[ii] = buf1[ii + buf_pos + 1];
43 } 43 }
44 return len; 44 return len;
45 } 45 }
46
46 CFX_ByteString CFX_ByteString::FormatInteger(int i, uint32_t flags) { 47 CFX_ByteString CFX_ByteString::FormatInteger(int i, uint32_t flags) {
47 char buf[32]; 48 char buf[32];
48 return CFX_ByteStringC(buf, _Buffer_itoa(buf, i, flags)); 49 return CFX_ByteStringC(buf, _Buffer_itoa(buf, i, flags));
49 } 50 }
50 51
51 // static 52 // static
52 CFX_ByteString::StringData* CFX_ByteString::StringData::Create(int nLen) { 53 CFX_ByteString::StringData* CFX_ByteString::StringData::Create(
53 // |nLen| is currently declared as in |int|. TODO(palmer): It should be 54 FX_STRSIZE nLen) {
54 // a |size_t|, or at least unsigned. 55 FXSYS_assert(nLen > 0);
55 if (nLen == 0 || nLen < 0) {
56 return NULL;
57 }
58 56
59 // Fixed portion of header plus a NUL char not included in m_nAllocLength. 57 // Fixed portion of header plus a NUL char not included in m_nAllocLength.
60 // sizeof(FX_CHAR) is always 1, used for consistency with CFX_Widestring. 58 // sizeof(FX_CHAR) is always 1, used for consistency with CFX_Widestring.
61 int overhead = offsetof(StringData, m_String) + sizeof(FX_CHAR); 59 int overhead = offsetof(StringData, m_String) + sizeof(FX_CHAR);
62 pdfium::base::CheckedNumeric<int> nSize = nLen; 60 pdfium::base::CheckedNumeric<int> nSize = nLen;
63 nSize += overhead; 61 nSize += overhead;
64 62
65 // Now round to an 8-byte boundary. We'd expect that this is the minimum 63 // Now round to an 8-byte boundary. We'd expect that this is the minimum
66 // granularity of any of the underlying allocators, so there may be cases 64 // granularity of any of the underlying allocators, so there may be cases
67 // where we can save a re-alloc when adding a few characters to a string 65 // where we can save a re-alloc when adding a few characters to a string
68 // by using this otherwise wasted space. 66 // by using this otherwise wasted space.
69 nSize += 7; 67 nSize += 7;
70 int totalSize = nSize.ValueOrDie() & ~7; 68 int totalSize = nSize.ValueOrDie() & ~7;
71 int usableSize = totalSize - overhead; 69 int usableSize = totalSize - overhead;
72 FXSYS_assert(usableSize >= nLen); 70 FXSYS_assert(usableSize >= nLen);
73 71
74 void* pData = FX_Alloc(uint8_t, totalSize); 72 void* pData = FX_Alloc(uint8_t, totalSize);
75 return new (pData) StringData(nLen, usableSize); 73 return new (pData) StringData(nLen, usableSize);
76 } 74 }
77 CFX_ByteString::~CFX_ByteString() { 75
78 if (m_pData) { 76 CFX_ByteString::StringData* CFX_ByteString::StringData::Create(
79 m_pData->Release(); 77 const StringData& other) {
80 } 78 StringData* result = Create(other.m_nDataLength);
81 } 79 result->CopyContents(other);
82 CFX_ByteString::CFX_ByteString(const FX_CHAR* lpsz, FX_STRSIZE nLen) { 80 return result;
83 if (nLen < 0) { 81 }
84 nLen = lpsz ? FXSYS_strlen(lpsz) : 0; 82
85 } 83 CFX_ByteString::StringData* CFX_ByteString::StringData::Create(
86 if (nLen) { 84 const FX_CHAR* pStr,
87 m_pData = StringData::Create(nLen); 85 FX_STRSIZE nLen) {
88 if (m_pData) { 86 StringData* result = Create(nLen);
89 FXSYS_memcpy(m_pData->m_String, lpsz, nLen); 87 result->CopyContents(pStr, nLen);
90 } 88 return result;
91 } else { 89 }
92 m_pData = NULL; 90
93 } 91 CFX_ByteString::StringData::StringData(FX_STRSIZE dataLen, FX_STRSIZE allocLen)
94 } 92 : m_nRefs(0), m_nDataLength(dataLen), m_nAllocLength(allocLen) {
95 CFX_ByteString::CFX_ByteString(const uint8_t* lpsz, FX_STRSIZE nLen) { 93 FXSYS_assert(dataLen >= 0);
94 FXSYS_assert(dataLen <= allocLen);
95 m_String[dataLen] = 0;
96 }
97
98 void CFX_ByteString::StringData::CopyContents(const StringData& other) {
99 FXSYS_assert(other.m_nDataLength <= m_nAllocLength);
100 FXSYS_memcpy(m_String, other.m_String, other.m_nDataLength + 1);
101 }
102
103 void CFX_ByteString::StringData::CopyContents(const FX_CHAR* pStr,
104 FX_STRSIZE nLen) {
105 FXSYS_assert(nLen >= 0 && nLen <= m_nAllocLength);
106 FXSYS_memcpy(m_String, pStr, nLen);
107 m_String[nLen] = 0;
108 }
109
110 void CFX_ByteString::StringData::CopyContentsAt(FX_STRSIZE offset,
111 const FX_CHAR* pStr,
112 FX_STRSIZE nLen) {
113 FXSYS_assert(offset >= 0 && nLen >= 0 && offset + nLen <= m_nAllocLength);
114 FXSYS_memcpy(m_String + offset, pStr, nLen);
115 m_String[offset + nLen] = 0;
116 }
117
118 CFX_ByteString::CFX_ByteString(const FX_CHAR* pStr, FX_STRSIZE nLen) {
119 if (nLen < 0)
120 nLen = pStr ? FXSYS_strlen(pStr) : 0;
121
122 if (nLen)
123 m_pData.Reset(StringData::Create(pStr, nLen));
124 }
125
126 CFX_ByteString::CFX_ByteString(const uint8_t* pStr, FX_STRSIZE nLen) {
96 if (nLen > 0) { 127 if (nLen > 0) {
97 m_pData = StringData::Create(nLen); 128 m_pData.Reset(
98 if (m_pData) { 129 StringData::Create(reinterpret_cast<const FX_CHAR*>(pStr), nLen));
99 FXSYS_memcpy(m_pData->m_String, lpsz, nLen); 130 }
100 } 131 }
101 } else { 132
102 m_pData = NULL;
103 }
104 }
105 CFX_ByteString::CFX_ByteString(char ch) { 133 CFX_ByteString::CFX_ByteString(char ch) {
106 m_pData = StringData::Create(1); 134 m_pData.Reset(StringData::Create(1));
107 if (m_pData) { 135 m_pData->m_String[0] = ch;
108 m_pData->m_String[0] = ch; 136 }
109 } 137
110 }
111 CFX_ByteString::CFX_ByteString(const CFX_ByteString& stringSrc) {
112 if (!stringSrc.m_pData) {
113 m_pData = NULL;
114 return;
115 }
116 if (stringSrc.m_pData->m_nRefs >= 0) {
117 m_pData = stringSrc.m_pData;
118 m_pData->Retain();
119 } else {
120 m_pData = NULL;
121 *this = stringSrc;
122 }
123 }
124 CFX_ByteString::CFX_ByteString(const CFX_ByteStringC& stringSrc) { 138 CFX_ByteString::CFX_ByteString(const CFX_ByteStringC& stringSrc) {
125 if (stringSrc.IsEmpty()) { 139 if (!stringSrc.IsEmpty()) {
126 m_pData = NULL; 140 m_pData.Reset(
127 return; 141 StringData::Create(stringSrc.GetCStr(), stringSrc.GetLength()));
128 } 142 }
129 m_pData = NULL; 143 }
130 *this = stringSrc; 144
131 }
132 CFX_ByteString::CFX_ByteString(const CFX_ByteStringC& str1, 145 CFX_ByteString::CFX_ByteString(const CFX_ByteStringC& str1,
133 const CFX_ByteStringC& str2) { 146 const CFX_ByteStringC& str2) {
134 m_pData = NULL;
135 int nNewLen = str1.GetLength() + str2.GetLength(); 147 int nNewLen = str1.GetLength() + str2.GetLength();
136 if (nNewLen == 0) { 148 if (nNewLen == 0)
137 return; 149 return;
138 } 150
139 m_pData = StringData::Create(nNewLen); 151 m_pData.Reset(StringData::Create(nNewLen));
140 if (m_pData) { 152 m_pData->CopyContents(str1.GetCStr(), str1.GetLength());
141 FXSYS_memcpy(m_pData->m_String, str1.GetCStr(), str1.GetLength()); 153 m_pData->CopyContentsAt(str1.GetLength(), str2.GetCStr(), str2.GetLength());
142 FXSYS_memcpy(m_pData->m_String + str1.GetLength(), str2.GetCStr(), 154 }
143 str2.GetLength()); 155
144 } 156 CFX_ByteString::~CFX_ByteString() {}
145 } 157
146 const CFX_ByteString& CFX_ByteString::operator=(const FX_CHAR* lpsz) { 158 const CFX_ByteString& CFX_ByteString::operator=(const FX_CHAR* pStr) {
147 if (!lpsz || lpsz[0] == 0) { 159 if (!pStr || !pStr[0])
148 Empty(); 160 clear();
149 } else { 161 else
150 AssignCopy(FXSYS_strlen(lpsz), lpsz); 162 AssignCopy(pStr, FXSYS_strlen(pStr));
151 } 163
152 return *this; 164 return *this;
153 } 165 }
166
154 const CFX_ByteString& CFX_ByteString::operator=(const CFX_ByteStringC& str) { 167 const CFX_ByteString& CFX_ByteString::operator=(const CFX_ByteStringC& str) {
155 if (str.IsEmpty()) { 168 if (str.IsEmpty())
156 Empty(); 169 clear();
157 } else { 170 else
158 AssignCopy(str.GetLength(), str.GetCStr()); 171 AssignCopy(str.GetCStr(), str.GetLength());
159 } 172
160 return *this; 173 return *this;
161 } 174 }
175
162 const CFX_ByteString& CFX_ByteString::operator=( 176 const CFX_ByteString& CFX_ByteString::operator=(
163 const CFX_ByteString& stringSrc) { 177 const CFX_ByteString& stringSrc) {
164 if (m_pData == stringSrc.m_pData) { 178 if (m_pData != stringSrc.m_pData)
165 return *this;
166 }
167 if (stringSrc.IsEmpty()) {
168 Empty();
169 } else if ((m_pData && m_pData->m_nRefs < 0) ||
170 (stringSrc.m_pData && stringSrc.m_pData->m_nRefs < 0)) {
171 AssignCopy(stringSrc.m_pData->m_nDataLength, stringSrc.m_pData->m_String);
172 } else {
173 Empty();
174 m_pData = stringSrc.m_pData; 179 m_pData = stringSrc.m_pData;
175 if (m_pData) { 180
176 m_pData->Retain(); 181 return *this;
177 } 182 }
178 } 183
179 return *this;
180 }
181 const CFX_ByteString& CFX_ByteString::operator=(const CFX_BinaryBuf& buf) { 184 const CFX_ByteString& CFX_ByteString::operator=(const CFX_BinaryBuf& buf) {
182 Load(buf.GetBuffer(), buf.GetSize()); 185 Load(buf.GetBuffer(), buf.GetSize());
183 return *this; 186 return *this;
184 } 187 }
188
185 void CFX_ByteString::Load(const uint8_t* buf, FX_STRSIZE len) { 189 void CFX_ByteString::Load(const uint8_t* buf, FX_STRSIZE len) {
186 Empty(); 190 if (!len) {
187 if (len) { 191 clear();
188 m_pData = StringData::Create(len); 192 return;
189 if (m_pData) { 193 }
190 FXSYS_memcpy(m_pData->m_String, buf, len); 194
191 } 195 m_pData.Reset(StringData::Create(reinterpret_cast<const FX_CHAR*>(buf), len));
192 } else { 196 }
193 m_pData = NULL; 197
194 } 198 const CFX_ByteString& CFX_ByteString::operator+=(const FX_CHAR* pStr) {
195 } 199 if (pStr)
196 const CFX_ByteString& CFX_ByteString::operator+=(const FX_CHAR* lpsz) { 200 Concat(pStr, FXSYS_strlen(pStr));
197 if (lpsz) { 201
198 ConcatInPlace(FXSYS_strlen(lpsz), lpsz); 202 return *this;
199 } 203 }
200 return *this; 204
201 }
202 const CFX_ByteString& CFX_ByteString::operator+=(char ch) { 205 const CFX_ByteString& CFX_ByteString::operator+=(char ch) {
203 ConcatInPlace(1, &ch); 206 Concat(&ch, 1);
204 return *this; 207 return *this;
205 } 208 }
209
206 const CFX_ByteString& CFX_ByteString::operator+=(const CFX_ByteString& str) { 210 const CFX_ByteString& CFX_ByteString::operator+=(const CFX_ByteString& str) {
207 if (!str.m_pData) { 211 if (str.m_pData)
208 return *this; 212 Concat(str.m_pData->m_String, str.m_pData->m_nDataLength);
209 } 213
210 ConcatInPlace(str.m_pData->m_nDataLength, str.m_pData->m_String); 214 return *this;
211 return *this; 215 }
212 } 216
213 const CFX_ByteString& CFX_ByteString::operator+=(const CFX_ByteStringC& str) { 217 const CFX_ByteString& CFX_ByteString::operator+=(const CFX_ByteStringC& str) {
214 if (str.IsEmpty()) { 218 if (!str.IsEmpty())
215 return *this; 219 Concat(str.GetCStr(), str.GetLength());
216 } 220
217 ConcatInPlace(str.GetLength(), str.GetCStr()); 221 return *this;
218 return *this; 222 }
219 } 223
220 bool CFX_ByteString::Equal(const char* ptr) const { 224 bool CFX_ByteString::Equal(const char* ptr) const {
221 if (!m_pData) { 225 if (!m_pData)
222 return !ptr || ptr[0] == '\0'; 226 return !ptr || ptr[0] == '\0';
223 } 227
224 if (!ptr) { 228 if (!ptr)
225 return m_pData->m_nDataLength == 0; 229 return m_pData->m_nDataLength == 0;
226 } 230
227 return FXSYS_strlen(ptr) == m_pData->m_nDataLength && 231 return FXSYS_strlen(ptr) == m_pData->m_nDataLength &&
228 FXSYS_memcmp(ptr, m_pData->m_String, m_pData->m_nDataLength) == 0; 232 FXSYS_memcmp(ptr, m_pData->m_String, m_pData->m_nDataLength) == 0;
229 } 233 }
234
230 bool CFX_ByteString::Equal(const CFX_ByteStringC& str) const { 235 bool CFX_ByteString::Equal(const CFX_ByteStringC& str) const {
231 if (!m_pData) { 236 if (!m_pData)
232 return str.IsEmpty(); 237 return str.IsEmpty();
233 } 238
234 return m_pData->m_nDataLength == str.GetLength() && 239 return m_pData->m_nDataLength == str.GetLength() &&
235 FXSYS_memcmp(m_pData->m_String, str.GetCStr(), str.GetLength()) == 0; 240 FXSYS_memcmp(m_pData->m_String, str.GetCStr(), str.GetLength()) == 0;
236 } 241 }
242
237 bool CFX_ByteString::Equal(const CFX_ByteString& other) const { 243 bool CFX_ByteString::Equal(const CFX_ByteString& other) const {
238 if (IsEmpty()) { 244 if (IsEmpty())
239 return other.IsEmpty(); 245 return other.IsEmpty();
240 } 246
241 if (other.IsEmpty()) { 247 if (other.IsEmpty())
242 return false; 248 return false;
243 } 249
244 return other.m_pData->m_nDataLength == m_pData->m_nDataLength && 250 return other.m_pData->m_nDataLength == m_pData->m_nDataLength &&
245 FXSYS_memcmp(other.m_pData->m_String, m_pData->m_String, 251 FXSYS_memcmp(other.m_pData->m_String, m_pData->m_String,
246 m_pData->m_nDataLength) == 0; 252 m_pData->m_nDataLength) == 0;
247 } 253 }
248 void CFX_ByteString::Empty() { 254
249 if (m_pData) {
250 m_pData->Release();
251 m_pData = NULL;
252 }
253 }
254 bool CFX_ByteString::EqualNoCase(const CFX_ByteStringC& str) const { 255 bool CFX_ByteString::EqualNoCase(const CFX_ByteStringC& str) const {
255 if (!m_pData) { 256 if (!m_pData)
256 return str.IsEmpty(); 257 return str.IsEmpty();
257 } 258
258 FX_STRSIZE len = str.GetLength(); 259 FX_STRSIZE len = str.GetLength();
259 if (m_pData->m_nDataLength != len) { 260 if (m_pData->m_nDataLength != len)
260 return false; 261 return false;
261 } 262
262 const uint8_t* pThis = (const uint8_t*)m_pData->m_String; 263 const uint8_t* pThis = (const uint8_t*)m_pData->m_String;
263 const uint8_t* pThat = str.GetPtr(); 264 const uint8_t* pThat = str.GetPtr();
264 for (FX_STRSIZE i = 0; i < len; i++) { 265 for (FX_STRSIZE i = 0; i < len; i++) {
265 if ((*pThis) != (*pThat)) { 266 if ((*pThis) != (*pThat)) {
266 uint8_t bThis = *pThis; 267 uint8_t bThis = *pThis;
267 if (bThis >= 'A' && bThis <= 'Z') { 268 if (bThis >= 'A' && bThis <= 'Z')
268 bThis += 'a' - 'A'; 269 bThis += 'a' - 'A';
269 } 270
270 uint8_t bThat = *pThat; 271 uint8_t bThat = *pThat;
271 if (bThat >= 'A' && bThat <= 'Z') { 272 if (bThat >= 'A' && bThat <= 'Z')
272 bThat += 'a' - 'A'; 273 bThat += 'a' - 'A';
273 } 274
274 if (bThis != bThat) { 275 if (bThis != bThat)
275 return false; 276 return false;
276 }
277 } 277 }
278 pThis++; 278 pThis++;
279 pThat++; 279 pThat++;
280 } 280 }
281 return true; 281 return true;
282 } 282 }
283 void CFX_ByteString::AssignCopy(FX_STRSIZE nSrcLen, 283
284 const FX_CHAR* lpszSrcData) { 284 void CFX_ByteString::AssignCopy(const FX_CHAR* pSrcData, FX_STRSIZE nSrcLen) {
285 AllocBeforeWrite(nSrcLen); 285 AllocBeforeWrite(nSrcLen);
286 FXSYS_memcpy(m_pData->m_String, lpszSrcData, nSrcLen); 286 m_pData->CopyContents(pSrcData, nSrcLen);
287 m_pData->m_nDataLength = nSrcLen; 287 m_pData->m_nDataLength = nSrcLen;
288 m_pData->m_String[nSrcLen] = 0; 288 }
289 } 289
290 void CFX_ByteString::CopyBeforeWrite() { 290 void CFX_ByteString::CopyBeforeWrite() {
291 if (!m_pData || m_pData->m_nRefs <= 1) { 291 if (!m_pData || m_pData->CanOperateInPlace(m_pData->m_nDataLength))
292 return; 292 return;
293 } 293
294 StringData* pData = m_pData; 294 if (!m_pData->m_nDataLength) {
295 m_pData->Release(); 295 clear();
296 FX_STRSIZE nDataLength = pData->m_nDataLength; 296 return;
297 m_pData = StringData::Create(nDataLength); 297 }
298 if (m_pData) { 298
299 FXSYS_memcpy(m_pData->m_String, pData->m_String, nDataLength + 1); 299 CFX_RetainPtr<StringData> pData(StringData::Create(*m_pData));
300 } 300 m_pData.Swap(pData);
301 } 301 }
302
302 void CFX_ByteString::AllocBeforeWrite(FX_STRSIZE nLen) { 303 void CFX_ByteString::AllocBeforeWrite(FX_STRSIZE nLen) {
303 if (m_pData && m_pData->m_nRefs <= 1 && m_pData->m_nAllocLength >= nLen) { 304 if (m_pData && m_pData->CanOperateInPlace(nLen))
304 return; 305 return;
305 } 306
306 Empty(); 307 if (!nLen) {
307 m_pData = StringData::Create(nLen); 308 clear();
308 } 309 return;
310 }
311
312 m_pData.Reset(StringData::Create(nLen));
313 }
314
309 void CFX_ByteString::ReleaseBuffer(FX_STRSIZE nNewLength) { 315 void CFX_ByteString::ReleaseBuffer(FX_STRSIZE nNewLength) {
310 if (!m_pData) { 316 if (!m_pData)
311 return; 317 return;
312 } 318
319 if (nNewLength == -1)
320 nNewLength = FXSYS_strlen(m_pData->m_String);
321
322 if (nNewLength == 0) {
323 clear();
324 return;
325 }
326
327 FXSYS_assert(nNewLength <= m_pData->m_nAllocLength);
313 CopyBeforeWrite(); 328 CopyBeforeWrite();
314 if (nNewLength == -1) {
315 nNewLength = FXSYS_strlen((const FX_CHAR*)m_pData->m_String);
316 }
317 if (nNewLength == 0) {
318 Empty();
319 return;
320 }
321 FXSYS_assert(nNewLength <= m_pData->m_nAllocLength);
322 m_pData->m_nDataLength = nNewLength; 329 m_pData->m_nDataLength = nNewLength;
323 m_pData->m_String[nNewLength] = 0; 330 m_pData->m_String[nNewLength] = 0;
324 } 331 }
332
325 void CFX_ByteString::Reserve(FX_STRSIZE len) { 333 void CFX_ByteString::Reserve(FX_STRSIZE len) {
326 GetBuffer(len); 334 GetBuffer(len);
327 ReleaseBuffer(GetLength()); 335 ReleaseBuffer(GetLength());
328 } 336 }
337
329 FX_CHAR* CFX_ByteString::GetBuffer(FX_STRSIZE nMinBufLength) { 338 FX_CHAR* CFX_ByteString::GetBuffer(FX_STRSIZE nMinBufLength) {
330 if (!m_pData && nMinBufLength == 0) {
331 return NULL;
332 }
333 if (m_pData && m_pData->m_nRefs <= 1 &&
334 m_pData->m_nAllocLength >= nMinBufLength) {
335 return m_pData->m_String;
336 }
337 if (!m_pData) { 339 if (!m_pData) {
338 m_pData = StringData::Create(nMinBufLength); 340 if (nMinBufLength == 0)
339 if (!m_pData) { 341 return nullptr;
340 return NULL; 342
341 } 343 m_pData.Reset(StringData::Create(nMinBufLength));
342 m_pData->m_nDataLength = 0; 344 m_pData->m_nDataLength = 0;
343 m_pData->m_String[0] = 0; 345 m_pData->m_String[0] = 0;
344 return m_pData->m_String; 346 return m_pData->m_String;
345 } 347 }
346 StringData* pOldData = m_pData; 348
347 FX_STRSIZE nOldLen = pOldData->m_nDataLength; 349 if (m_pData->CanOperateInPlace(nMinBufLength))
348 if (nMinBufLength < nOldLen) { 350 return m_pData->m_String;
349 nMinBufLength = nOldLen; 351
350 } 352 nMinBufLength = std::max(nMinBufLength, m_pData->m_nDataLength);
351 m_pData = StringData::Create(nMinBufLength); 353 if (nMinBufLength == 0)
352 if (!m_pData) { 354 return nullptr;
353 return NULL; 355
354 } 356 CFX_RetainPtr<StringData> pNewData(StringData::Create(nMinBufLength));
355 FXSYS_memcpy(m_pData->m_String, pOldData->m_String, (nOldLen + 1)); 357 pNewData->CopyContents(*m_pData);
356 m_pData->m_nDataLength = nOldLen; 358 pNewData->m_nDataLength = m_pData->m_nDataLength;
357 pOldData->Release(); 359 m_pData.Swap(pNewData);
358 return m_pData->m_String; 360 return m_pData->m_String;
359 } 361 }
362
360 FX_STRSIZE CFX_ByteString::Delete(FX_STRSIZE nIndex, FX_STRSIZE nCount) { 363 FX_STRSIZE CFX_ByteString::Delete(FX_STRSIZE nIndex, FX_STRSIZE nCount) {
361 if (!m_pData) { 364 if (!m_pData)
362 return 0; 365 return 0;
363 } 366
364 if (nIndex < 0) { 367 if (nIndex < 0)
365 nIndex = 0; 368 nIndex = 0;
366 } 369
367 FX_STRSIZE nOldLength = m_pData->m_nDataLength; 370 FX_STRSIZE nOldLength = m_pData->m_nDataLength;
368 if (nCount > 0 && nIndex < nOldLength) { 371 if (nCount > 0 && nIndex < nOldLength) {
369 FX_STRSIZE mLength = nIndex + nCount; 372 FX_STRSIZE mLength = nIndex + nCount;
370 if (mLength >= nOldLength) { 373 if (mLength >= nOldLength) {
371 m_pData->m_nDataLength = nIndex; 374 m_pData->m_nDataLength = nIndex;
372 return m_pData->m_nDataLength; 375 return m_pData->m_nDataLength;
373 } 376 }
374 CopyBeforeWrite(); 377 CopyBeforeWrite();
375 int nBytesToCopy = nOldLength - mLength + 1; 378 int nBytesToCopy = nOldLength - mLength + 1;
376 FXSYS_memmove(m_pData->m_String + nIndex, m_pData->m_String + mLength, 379 FXSYS_memmove(m_pData->m_String + nIndex, m_pData->m_String + mLength,
377 nBytesToCopy); 380 nBytesToCopy);
378 m_pData->m_nDataLength = nOldLength - nCount; 381 m_pData->m_nDataLength = nOldLength - nCount;
379 } 382 }
380 return m_pData->m_nDataLength; 383 return m_pData->m_nDataLength;
381 } 384 }
382 void CFX_ByteString::ConcatInPlace(FX_STRSIZE nSrcLen, 385
383 const FX_CHAR* lpszSrcData) { 386 void CFX_ByteString::Concat(const FX_CHAR* pSrcData, FX_STRSIZE nSrcLen) {
384 if (nSrcLen == 0 || !lpszSrcData) { 387 if (!pSrcData || nSrcLen <= 0)
388 return;
389
390 if (!m_pData) {
391 m_pData.Reset(StringData::Create(pSrcData, nSrcLen));
385 return; 392 return;
386 } 393 }
387 if (!m_pData) { 394
388 m_pData = StringData::Create(nSrcLen); 395 if (m_pData->CanOperateInPlace(m_pData->m_nDataLength + nSrcLen)) {
389 if (!m_pData) { 396 m_pData->CopyContentsAt(m_pData->m_nDataLength, pSrcData, nSrcLen);
390 return; 397 m_pData->m_nDataLength += nSrcLen;
391 }
392 FXSYS_memcpy(m_pData->m_String, lpszSrcData, nSrcLen);
393 return; 398 return;
394 } 399 }
395 if (m_pData->m_nRefs > 1 || 400
396 m_pData->m_nDataLength + nSrcLen > m_pData->m_nAllocLength) { 401 CFX_RetainPtr<StringData> pNewData(
397 ConcatCopy(m_pData->m_nDataLength, m_pData->m_String, nSrcLen, lpszSrcData); 402 StringData::Create(m_pData->m_nDataLength + nSrcLen));
398 } else { 403 pNewData->CopyContents(*m_pData);
399 FXSYS_memcpy(m_pData->m_String + m_pData->m_nDataLength, lpszSrcData, 404 pNewData->CopyContentsAt(m_pData->m_nDataLength, pSrcData, nSrcLen);
400 nSrcLen); 405 m_pData.Swap(pNewData);
401 m_pData->m_nDataLength += nSrcLen;
402 m_pData->m_String[m_pData->m_nDataLength] = 0;
403 }
404 } 406 }
405 void CFX_ByteString::ConcatCopy(FX_STRSIZE nSrc1Len, 407
406 const FX_CHAR* lpszSrc1Data,
407 FX_STRSIZE nSrc2Len,
408 const FX_CHAR* lpszSrc2Data) {
409 int nNewLen = nSrc1Len + nSrc2Len;
410 if (nNewLen <= 0) {
411 return;
412 }
413 // Don't release until done copying, might be one of the arguments.
414 StringData* pOldData = m_pData;
415 m_pData = StringData::Create(nNewLen);
416 if (m_pData) {
417 memcpy(m_pData->m_String, lpszSrc1Data, nSrc1Len);
418 memcpy(m_pData->m_String + nSrc1Len, lpszSrc2Data, nSrc2Len);
419 }
420 pOldData->Release();
421 }
422 CFX_ByteString CFX_ByteString::Mid(FX_STRSIZE nFirst) const { 408 CFX_ByteString CFX_ByteString::Mid(FX_STRSIZE nFirst) const {
423 if (!m_pData) {
424 return CFX_ByteString();
425 }
426 return Mid(nFirst, m_pData->m_nDataLength - nFirst); 409 return Mid(nFirst, m_pData->m_nDataLength - nFirst);
427 } 410 }
411
428 CFX_ByteString CFX_ByteString::Mid(FX_STRSIZE nFirst, FX_STRSIZE nCount) const { 412 CFX_ByteString CFX_ByteString::Mid(FX_STRSIZE nFirst, FX_STRSIZE nCount) const {
429 if (nFirst < 0) { 413 if (!m_pData)
430 nFirst = 0; 414 return CFX_ByteString();
431 } 415
432 if (nCount < 0) { 416 nFirst = std::min(std::max(nFirst, 0), m_pData->m_nDataLength);
433 nCount = 0; 417 nCount = std::min(std::max(nCount, 0), m_pData->m_nDataLength - nFirst);
434 } 418 if (nCount == 0)
435 if (nFirst + nCount > m_pData->m_nDataLength) { 419 return CFX_ByteString();
436 nCount = m_pData->m_nDataLength - nFirst; 420
437 } 421 if (nFirst == 0 && nFirst + nCount == m_pData->m_nDataLength)
438 if (nFirst > m_pData->m_nDataLength) {
439 nCount = 0;
440 }
441 if (nFirst == 0 && nFirst + nCount == m_pData->m_nDataLength) {
442 return *this; 422 return *this;
443 } 423
444 CFX_ByteString dest; 424 CFX_ByteString dest;
445 AllocCopy(dest, nCount, nFirst); 425 AllocCopy(dest, nCount, nFirst);
446 return dest; 426 return dest;
447 } 427 }
428
448 void CFX_ByteString::AllocCopy(CFX_ByteString& dest, 429 void CFX_ByteString::AllocCopy(CFX_ByteString& dest,
449 FX_STRSIZE nCopyLen, 430 FX_STRSIZE nCopyLen,
450 FX_STRSIZE nCopyIndex) const { 431 FX_STRSIZE nCopyIndex) const {
451 // |FX_STRSIZE| is currently typedef'd as in |int|. TODO(palmer): It 432 if (nCopyLen <= 0)
452 // should be a |size_t|, or at least unsigned.
453 if (nCopyLen == 0 || nCopyLen < 0) {
454 return; 433 return;
455 } 434
456 ASSERT(!dest.m_pData); 435 CFX_RetainPtr<StringData> pNewData(
457 dest.m_pData = StringData::Create(nCopyLen); 436 StringData::Create(m_pData->m_String + nCopyIndex, nCopyLen));
458 if (dest.m_pData) { 437 dest.m_pData.Swap(pNewData);
459 FXSYS_memcpy(dest.m_pData->m_String, m_pData->m_String + nCopyIndex,
460 nCopyLen);
461 }
462 } 438 }
439
463 #define FORCE_ANSI 0x10000 440 #define FORCE_ANSI 0x10000
464 #define FORCE_UNICODE 0x20000 441 #define FORCE_UNICODE 0x20000
465 #define FORCE_INT64 0x40000 442 #define FORCE_INT64 0x40000
466 void CFX_ByteString::FormatV(const FX_CHAR* lpszFormat, va_list argList) { 443
444 void CFX_ByteString::FormatV(const FX_CHAR* pFormat, va_list argList) {
467 va_list argListSave; 445 va_list argListSave;
468 #if defined(__ARMCC_VERSION) || \ 446 #if defined(__ARMCC_VERSION) || \
469 (!defined(_MSC_VER) && (_FX_CPU_ == _FX_X64_ || _FX_CPU_ == _FX_IA64_ || \ 447 (!defined(_MSC_VER) && (_FX_CPU_ == _FX_X64_ || _FX_CPU_ == _FX_IA64_ || \
470 _FX_CPU_ == _FX_ARM64_)) || \ 448 _FX_CPU_ == _FX_ARM64_)) || \
471 defined(__native_client__) 449 defined(__native_client__)
472 va_copy(argListSave, argList); 450 va_copy(argListSave, argList);
473 #else 451 #else
474 argListSave = argList; 452 argListSave = argList;
475 #endif 453 #endif
476 int nMaxLen = 0; 454 int nMaxLen = 0;
477 for (const FX_CHAR* lpsz = lpszFormat; *lpsz != 0; lpsz++) { 455 for (const FX_CHAR* pStr = pFormat; *pStr != 0; pStr++) {
478 if (*lpsz != '%' || *(lpsz = lpsz + 1) == '%') { 456 if (*pStr != '%' || *(pStr = pStr + 1) == '%') {
479 nMaxLen += FXSYS_strlen(lpsz); 457 nMaxLen += FXSYS_strlen(pStr);
480 continue; 458 continue;
481 } 459 }
482 int nItemLen = 0; 460 int nItemLen = 0;
483 int nWidth = 0; 461 int nWidth = 0;
484 for (; *lpsz != 0; lpsz++) { 462 for (; *pStr != 0; pStr++) {
485 if (*lpsz == '#') { 463 if (*pStr == '#') {
486 nMaxLen += 2; 464 nMaxLen += 2;
487 } else if (*lpsz == '*') { 465 } else if (*pStr == '*') {
488 nWidth = va_arg(argList, int); 466 nWidth = va_arg(argList, int);
489 } else if (*lpsz != '-' && *lpsz != '+' && *lpsz != '0' && *lpsz != ' ') { 467 } else if (*pStr != '-' && *pStr != '+' && *pStr != '0' && *pStr != ' ') {
490 break; 468 break;
491 } 469 }
492 } 470 }
493 if (nWidth == 0) { 471 if (nWidth == 0) {
494 nWidth = FXSYS_atoi(lpsz); 472 nWidth = FXSYS_atoi(pStr);
495 while (std::isdigit(*lpsz)) 473 while (std::isdigit(*pStr))
496 lpsz++; 474 pStr++;
497 } 475 }
498 if (nWidth < 0 || nWidth > 128 * 1024) { 476 if (nWidth < 0 || nWidth > 128 * 1024) {
499 lpszFormat = "Bad width"; 477 pFormat = "Bad width";
500 nMaxLen = 10; 478 nMaxLen = 10;
501 break; 479 break;
502 } 480 }
503 int nPrecision = 0; 481 int nPrecision = 0;
504 if (*lpsz == '.') { 482 if (*pStr == '.') {
505 lpsz++; 483 pStr++;
506 if (*lpsz == '*') { 484 if (*pStr == '*') {
507 nPrecision = va_arg(argList, int); 485 nPrecision = va_arg(argList, int);
508 lpsz++; 486 pStr++;
509 } else { 487 } else {
510 nPrecision = FXSYS_atoi(lpsz); 488 nPrecision = FXSYS_atoi(pStr);
511 while (std::isdigit(*lpsz)) 489 while (std::isdigit(*pStr))
512 lpsz++; 490 pStr++;
513 } 491 }
514 } 492 }
515 if (nPrecision < 0 || nPrecision > 128 * 1024) { 493 if (nPrecision < 0 || nPrecision > 128 * 1024) {
516 lpszFormat = "Bad precision"; 494 pFormat = "Bad precision";
517 nMaxLen = 14; 495 nMaxLen = 14;
518 break; 496 break;
519 } 497 }
520 int nModifier = 0; 498 int nModifier = 0;
521 if (FXSYS_strncmp(lpsz, "I64", 3) == 0) { 499 if (FXSYS_strncmp(pStr, "I64", 3) == 0) {
522 lpsz += 3; 500 pStr += 3;
523 nModifier = FORCE_INT64; 501 nModifier = FORCE_INT64;
524 } else { 502 } else {
525 switch (*lpsz) { 503 switch (*pStr) {
526 case 'h': 504 case 'h':
527 nModifier = FORCE_ANSI; 505 nModifier = FORCE_ANSI;
528 lpsz++; 506 pStr++;
529 break; 507 break;
530 case 'l': 508 case 'l':
531 nModifier = FORCE_UNICODE; 509 nModifier = FORCE_UNICODE;
532 lpsz++; 510 pStr++;
533 break; 511 break;
534 case 'F': 512 case 'F':
535 case 'N': 513 case 'N':
536 case 'L': 514 case 'L':
537 lpsz++; 515 pStr++;
538 break; 516 break;
539 } 517 }
540 } 518 }
541 switch (*lpsz | nModifier) { 519 switch (*pStr | nModifier) {
542 case 'c': 520 case 'c':
543 case 'C': 521 case 'C':
544 nItemLen = 2; 522 nItemLen = 2;
545 va_arg(argList, int); 523 va_arg(argList, int);
546 break; 524 break;
547 case 'c' | FORCE_ANSI: 525 case 'c' | FORCE_ANSI:
548 case 'C' | FORCE_ANSI: 526 case 'C' | FORCE_ANSI:
549 nItemLen = 2; 527 nItemLen = 2;
550 va_arg(argList, int); 528 va_arg(argList, int);
551 break; 529 break;
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
602 } break; 580 } break;
603 } 581 }
604 if (nItemLen != 0) { 582 if (nItemLen != 0) {
605 if (nPrecision != 0 && nItemLen > nPrecision) { 583 if (nPrecision != 0 && nItemLen > nPrecision) {
606 nItemLen = nPrecision; 584 nItemLen = nPrecision;
607 } 585 }
608 if (nItemLen < nWidth) { 586 if (nItemLen < nWidth) {
609 nItemLen = nWidth; 587 nItemLen = nWidth;
610 } 588 }
611 } else { 589 } else {
612 switch (*lpsz) { 590 switch (*pStr) {
613 case 'd': 591 case 'd':
614 case 'i': 592 case 'i':
615 case 'u': 593 case 'u':
616 case 'x': 594 case 'x':
617 case 'X': 595 case 'X':
618 case 'o': 596 case 'o':
619 if (nModifier & FORCE_INT64) { 597 if (nModifier & FORCE_INT64) {
620 va_arg(argList, int64_t); 598 va_arg(argList, int64_t);
621 } else { 599 } else {
622 va_arg(argList, int); 600 va_arg(argList, int);
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
661 va_arg(argList, int*); 639 va_arg(argList, int*);
662 break; 640 break;
663 } 641 }
664 } 642 }
665 nMaxLen += nItemLen; 643 nMaxLen += nItemLen;
666 } 644 }
667 nMaxLen += 32; // Fudge factor. 645 nMaxLen += 32; // Fudge factor.
668 GetBuffer(nMaxLen); 646 GetBuffer(nMaxLen);
669 if (m_pData) { 647 if (m_pData) {
670 memset(m_pData->m_String, 0, nMaxLen); 648 memset(m_pData->m_String, 0, nMaxLen);
671 FXSYS_vsnprintf(m_pData->m_String, nMaxLen - 1, lpszFormat, argListSave); 649 FXSYS_vsnprintf(m_pData->m_String, nMaxLen - 1, pFormat, argListSave);
672 ReleaseBuffer(); 650 ReleaseBuffer();
673 } 651 }
674 va_end(argListSave); 652 va_end(argListSave);
675 } 653 }
676 void CFX_ByteString::Format(const FX_CHAR* lpszFormat, ...) { 654
655 void CFX_ByteString::Format(const FX_CHAR* pFormat, ...) {
677 va_list argList; 656 va_list argList;
678 va_start(argList, lpszFormat); 657 va_start(argList, pFormat);
679 FormatV(lpszFormat, argList); 658 FormatV(pFormat, argList);
680 va_end(argList); 659 va_end(argList);
681 } 660 }
661
682 FX_STRSIZE CFX_ByteString::Insert(FX_STRSIZE nIndex, FX_CHAR ch) { 662 FX_STRSIZE CFX_ByteString::Insert(FX_STRSIZE nIndex, FX_CHAR ch) {
663 FX_STRSIZE nNewLength = m_pData ? m_pData->m_nDataLength : 0;
664 nIndex = std::max(nIndex, 0);
665 nIndex = std::min(nIndex, nNewLength);
666 nNewLength++;
667
683 CopyBeforeWrite(); 668 CopyBeforeWrite();
684 if (nIndex < 0) { 669 if (!m_pData || m_pData->m_nAllocLength < nNewLength) {
685 nIndex = 0; 670 CFX_RetainPtr<StringData> pNewData(StringData::Create(nNewLength));
671 pNewData->CopyContents(*m_pData);
672 m_pData.Swap(pNewData);
686 } 673 }
687 FX_STRSIZE nNewLength = m_pData ? m_pData->m_nDataLength : 0; 674
688 if (nIndex > nNewLength) {
689 nIndex = nNewLength;
690 }
691 nNewLength++;
692 if (!m_pData || m_pData->m_nAllocLength < nNewLength) {
693 StringData* pOldData = m_pData;
694 const FX_CHAR* pstr = m_pData->m_String;
695 m_pData = StringData::Create(nNewLength);
696 if (!m_pData) {
697 return 0;
698 }
699 if (pOldData) {
700 FXSYS_memmove(m_pData->m_String, pstr, (pOldData->m_nDataLength + 1));
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, 675 FXSYS_memmove(m_pData->m_String + nIndex + 1, m_pData->m_String + nIndex,
707 (nNewLength - nIndex)); 676 nNewLength - nIndex);
708 m_pData->m_String[nIndex] = ch; 677 m_pData->m_String[nIndex] = ch;
709 m_pData->m_nDataLength = nNewLength; 678 m_pData->m_nDataLength = nNewLength;
710 return nNewLength; 679 return nNewLength;
711 } 680 }
681
712 CFX_ByteString CFX_ByteString::Right(FX_STRSIZE nCount) const { 682 CFX_ByteString CFX_ByteString::Right(FX_STRSIZE nCount) const {
713 if (!m_pData) { 683 if (!m_pData)
714 return CFX_ByteString(); 684 return CFX_ByteString();
715 } 685
716 if (nCount < 0) { 686 nCount = std::max(nCount, 0);
717 nCount = 0; 687 if (nCount >= m_pData->m_nDataLength)
718 }
719 if (nCount >= m_pData->m_nDataLength) {
720 return *this; 688 return *this;
721 } 689
722 CFX_ByteString dest; 690 CFX_ByteString dest;
723 AllocCopy(dest, nCount, m_pData->m_nDataLength - nCount); 691 AllocCopy(dest, nCount, m_pData->m_nDataLength - nCount);
724 return dest; 692 return dest;
725 } 693 }
694
726 CFX_ByteString CFX_ByteString::Left(FX_STRSIZE nCount) const { 695 CFX_ByteString CFX_ByteString::Left(FX_STRSIZE nCount) const {
727 if (!m_pData) { 696 if (!m_pData)
728 return CFX_ByteString(); 697 return CFX_ByteString();
729 } 698
730 if (nCount < 0) { 699 nCount = std::max(nCount, 0);
731 nCount = 0; 700 if (nCount >= m_pData->m_nDataLength)
732 }
733 if (nCount >= m_pData->m_nDataLength) {
734 return *this; 701 return *this;
735 } 702
736 CFX_ByteString dest; 703 CFX_ByteString dest;
737 AllocCopy(dest, nCount, 0); 704 AllocCopy(dest, nCount, 0);
738 return dest; 705 return dest;
739 } 706 }
707
740 FX_STRSIZE CFX_ByteString::Find(FX_CHAR ch, FX_STRSIZE nStart) const { 708 FX_STRSIZE CFX_ByteString::Find(FX_CHAR ch, FX_STRSIZE nStart) const {
741 if (!m_pData) { 709 if (!m_pData)
742 return -1; 710 return -1;
743 } 711
712 if (nStart >= m_pData->m_nDataLength)
713 return -1;
714
715 const FX_CHAR* pStr = FXSYS_strchr(m_pData->m_String + nStart, ch);
716 return pStr ? (int)(pStr - m_pData->m_String) : -1;
717 }
718
719 FX_STRSIZE CFX_ByteString::ReverseFind(FX_CHAR ch) const {
720 if (!m_pData)
721 return -1;
722
744 FX_STRSIZE nLength = m_pData->m_nDataLength; 723 FX_STRSIZE nLength = m_pData->m_nDataLength;
745 if (nStart >= nLength) { 724 while (nLength--) {
746 return -1; 725 if (m_pData->m_String[nLength] == ch)
747 } 726 return nLength;
748 const FX_CHAR* lpsz = FXSYS_strchr(m_pData->m_String + nStart, ch);
749 return lpsz ? (int)(lpsz - m_pData->m_String) : -1;
750 }
751 FX_STRSIZE CFX_ByteString::ReverseFind(FX_CHAR ch) const {
752 if (!m_pData) {
753 return -1;
754 }
755 FX_STRSIZE nLength = m_pData->m_nDataLength;
756 while (nLength) {
757 if (m_pData->m_String[nLength - 1] == ch) {
758 return nLength - 1;
759 }
760 nLength--;
761 } 727 }
762 return -1; 728 return -1;
763 } 729 }
730
764 const FX_CHAR* FX_strstr(const FX_CHAR* str1, 731 const FX_CHAR* FX_strstr(const FX_CHAR* str1,
765 int len1, 732 int len1,
766 const FX_CHAR* str2, 733 const FX_CHAR* str2,
767 int len2) { 734 int len2) {
768 if (len2 > len1 || len2 == 0) { 735 if (len2 > len1 || len2 == 0) {
769 return NULL; 736 return nullptr;
770 } 737 }
771 const FX_CHAR* end_ptr = str1 + len1 - len2; 738 const FX_CHAR* end_ptr = str1 + len1 - len2;
772 while (str1 <= end_ptr) { 739 while (str1 <= end_ptr) {
773 int i = 0; 740 int i = 0;
774 while (1) { 741 while (1) {
775 if (str1[i] != str2[i]) { 742 if (str1[i] != str2[i]) {
776 break; 743 break;
777 } 744 }
778 i++; 745 i++;
779 if (i == len2) { 746 if (i == len2) {
780 return str1; 747 return str1;
781 } 748 }
782 } 749 }
783 str1++; 750 str1++;
784 } 751 }
785 return NULL; 752 return nullptr;
786 } 753 }
787 FX_STRSIZE CFX_ByteString::Find(const CFX_ByteStringC& lpszSub, 754
755 FX_STRSIZE CFX_ByteString::Find(const CFX_ByteStringC& pSub,
788 FX_STRSIZE nStart) const { 756 FX_STRSIZE nStart) const {
789 if (!m_pData) { 757 if (!m_pData)
790 return -1; 758 return -1;
791 } 759
792 FX_STRSIZE nLength = m_pData->m_nDataLength; 760 FX_STRSIZE nLength = m_pData->m_nDataLength;
793 if (nStart > nLength) { 761 if (nStart > nLength)
794 return -1; 762 return -1;
795 } 763
796 const FX_CHAR* lpsz = 764 const FX_CHAR* pStr =
797 FX_strstr(m_pData->m_String + nStart, m_pData->m_nDataLength - nStart, 765 FX_strstr(m_pData->m_String + nStart, m_pData->m_nDataLength - nStart,
798 lpszSub.GetCStr(), lpszSub.GetLength()); 766 pSub.GetCStr(), pSub.GetLength());
799 return lpsz ? (int)(lpsz - m_pData->m_String) : -1; 767 return pStr ? (int)(pStr - m_pData->m_String) : -1;
800 } 768 }
769
801 void CFX_ByteString::MakeLower() { 770 void CFX_ByteString::MakeLower() {
802 if (!m_pData) { 771 if (!m_pData)
803 return; 772 return;
804 } 773
805 CopyBeforeWrite(); 774 CopyBeforeWrite();
806 if (GetLength() < 1) { 775 if (GetLength() < 1)
807 return; 776 return;
808 } 777
809 FXSYS_strlwr(m_pData->m_String); 778 FXSYS_strlwr(m_pData->m_String);
810 } 779 }
780
811 void CFX_ByteString::MakeUpper() { 781 void CFX_ByteString::MakeUpper() {
812 if (!m_pData) { 782 if (!m_pData)
813 return; 783 return;
814 } 784
815 CopyBeforeWrite(); 785 CopyBeforeWrite();
816 if (GetLength() < 1) { 786 if (GetLength() < 1)
817 return; 787 return;
818 } 788
819 FXSYS_strupr(m_pData->m_String); 789 FXSYS_strupr(m_pData->m_String);
820 } 790 }
791
821 FX_STRSIZE CFX_ByteString::Remove(FX_CHAR chRemove) { 792 FX_STRSIZE CFX_ByteString::Remove(FX_CHAR chRemove) {
822 if (!m_pData) { 793 if (!m_pData) {
823 return 0; 794 return 0;
824 } 795 }
825 CopyBeforeWrite(); 796 CopyBeforeWrite();
826 if (GetLength() < 1) { 797 if (GetLength() < 1) {
827 return 0; 798 return 0;
828 } 799 }
829 FX_CHAR* pstrSource = m_pData->m_String; 800 FX_CHAR* pstrSource = m_pData->m_String;
830 FX_CHAR* pstrDest = m_pData->m_String; 801 FX_CHAR* pstrDest = m_pData->m_String;
831 FX_CHAR* pstrEnd = m_pData->m_String + m_pData->m_nDataLength; 802 FX_CHAR* pstrEnd = m_pData->m_String + m_pData->m_nDataLength;
832 while (pstrSource < pstrEnd) { 803 while (pstrSource < pstrEnd) {
833 if (*pstrSource != chRemove) { 804 if (*pstrSource != chRemove) {
834 *pstrDest = *pstrSource; 805 *pstrDest = *pstrSource;
835 pstrDest++; 806 pstrDest++;
836 } 807 }
837 pstrSource++; 808 pstrSource++;
838 } 809 }
839 *pstrDest = 0; 810 *pstrDest = 0;
840 FX_STRSIZE nCount = (FX_STRSIZE)(pstrSource - pstrDest); 811 FX_STRSIZE nCount = (FX_STRSIZE)(pstrSource - pstrDest);
841 m_pData->m_nDataLength -= nCount; 812 m_pData->m_nDataLength -= nCount;
842 return nCount; 813 return nCount;
843 } 814 }
844 FX_STRSIZE CFX_ByteString::Replace(const CFX_ByteStringC& lpszOld, 815
845 const CFX_ByteStringC& lpszNew) { 816 FX_STRSIZE CFX_ByteString::Replace(const CFX_ByteStringC& pOld,
846 if (!m_pData) { 817 const CFX_ByteStringC& pNew) {
818 if (!m_pData || pOld.IsEmpty())
847 return 0; 819 return 0;
848 } 820
849 if (lpszOld.IsEmpty()) { 821 FX_STRSIZE nSourceLen = pOld.GetLength();
850 return 0; 822 FX_STRSIZE nReplacementLen = pNew.GetLength();
851 }
852 FX_STRSIZE nSourceLen = lpszOld.GetLength();
853 FX_STRSIZE nReplacementLen = lpszNew.GetLength();
854 FX_STRSIZE nCount = 0; 823 FX_STRSIZE nCount = 0;
855 const FX_CHAR* pStart = m_pData->m_String; 824 const FX_CHAR* pStart = m_pData->m_String;
856 FX_CHAR* pEnd = m_pData->m_String + m_pData->m_nDataLength; 825 FX_CHAR* pEnd = m_pData->m_String + m_pData->m_nDataLength;
857 while (1) { 826 while (1) {
858 const FX_CHAR* pTarget = FX_strstr(pStart, (FX_STRSIZE)(pEnd - pStart), 827 const FX_CHAR* pTarget = FX_strstr(pStart, (FX_STRSIZE)(pEnd - pStart),
859 lpszOld.GetCStr(), nSourceLen); 828 pOld.GetCStr(), nSourceLen);
860 if (!pTarget) { 829 if (!pTarget)
861 break; 830 break;
862 } 831
863 nCount++; 832 nCount++;
864 pStart = pTarget + nSourceLen; 833 pStart = pTarget + nSourceLen;
865 } 834 }
866 if (nCount == 0) { 835 if (nCount == 0)
867 return 0; 836 return 0;
868 } 837
869 FX_STRSIZE nNewLength = 838 FX_STRSIZE nNewLength =
870 m_pData->m_nDataLength + (nReplacementLen - nSourceLen) * nCount; 839 m_pData->m_nDataLength + (nReplacementLen - nSourceLen) * nCount;
840
871 if (nNewLength == 0) { 841 if (nNewLength == 0) {
872 Empty(); 842 clear();
873 return nCount; 843 return nCount;
874 } 844 }
875 StringData* pNewData = StringData::Create(nNewLength); 845
876 if (!pNewData) { 846 CFX_RetainPtr<StringData> pNewData(StringData::Create(nNewLength));
877 return 0;
878 }
879 pStart = m_pData->m_String; 847 pStart = m_pData->m_String;
880 FX_CHAR* pDest = pNewData->m_String; 848 FX_CHAR* pDest = pNewData->m_String;
881 for (FX_STRSIZE i = 0; i < nCount; i++) { 849 for (FX_STRSIZE i = 0; i < nCount; i++) {
882 const FX_CHAR* pTarget = FX_strstr(pStart, (FX_STRSIZE)(pEnd - pStart), 850 const FX_CHAR* pTarget = FX_strstr(pStart, (FX_STRSIZE)(pEnd - pStart),
883 lpszOld.GetCStr(), nSourceLen); 851 pOld.GetCStr(), nSourceLen);
884 FXSYS_memcpy(pDest, pStart, pTarget - pStart); 852 FXSYS_memcpy(pDest, pStart, pTarget - pStart);
885 pDest += pTarget - pStart; 853 pDest += pTarget - pStart;
886 FXSYS_memcpy(pDest, lpszNew.GetCStr(), lpszNew.GetLength()); 854 FXSYS_memcpy(pDest, pNew.GetCStr(), pNew.GetLength());
887 pDest += lpszNew.GetLength(); 855 pDest += pNew.GetLength();
888 pStart = pTarget + nSourceLen; 856 pStart = pTarget + nSourceLen;
889 } 857 }
890 FXSYS_memcpy(pDest, pStart, pEnd - pStart); 858 FXSYS_memcpy(pDest, pStart, pEnd - pStart);
891 m_pData->Release(); 859 m_pData.Swap(pNewData);
892 m_pData = pNewData;
893 return nCount; 860 return nCount;
894 } 861 }
862
895 void CFX_ByteString::SetAt(FX_STRSIZE nIndex, FX_CHAR ch) { 863 void CFX_ByteString::SetAt(FX_STRSIZE nIndex, FX_CHAR ch) {
896 if (!m_pData) { 864 if (!m_pData) {
897 return; 865 return;
898 } 866 }
899 FXSYS_assert(nIndex >= 0); 867 FXSYS_assert(nIndex >= 0);
900 FXSYS_assert(nIndex < m_pData->m_nDataLength); 868 FXSYS_assert(nIndex < m_pData->m_nDataLength);
901 CopyBeforeWrite(); 869 CopyBeforeWrite();
902 m_pData->m_String[nIndex] = ch; 870 m_pData->m_String[nIndex] = ch;
903 } 871 }
872
904 CFX_WideString CFX_ByteString::UTF8Decode() const { 873 CFX_WideString CFX_ByteString::UTF8Decode() const {
905 CFX_UTF8Decoder decoder; 874 CFX_UTF8Decoder decoder;
906 for (FX_STRSIZE i = 0; i < GetLength(); i++) { 875 for (FX_STRSIZE i = 0; i < GetLength(); i++) {
907 decoder.Input((uint8_t)m_pData->m_String[i]); 876 decoder.Input((uint8_t)m_pData->m_String[i]);
908 } 877 }
909 return decoder.GetResult(); 878 return decoder.GetResult();
910 } 879 }
911 880
912 // static 881 // static
913 CFX_ByteString CFX_ByteString::FromUnicode(const FX_WCHAR* str, 882 CFX_ByteString CFX_ByteString::FromUnicode(const FX_WCHAR* str,
(...skipping 23 matching lines...) Expand all
937 } 906 }
938 } 907 }
939 if (this_len < that_len) { 908 if (this_len < that_len) {
940 return -1; 909 return -1;
941 } 910 }
942 if (this_len > that_len) { 911 if (this_len > that_len) {
943 return 1; 912 return 1;
944 } 913 }
945 return 0; 914 return 0;
946 } 915 }
947 void CFX_ByteString::TrimRight(const CFX_ByteStringC& lpszTargets) { 916 void CFX_ByteString::TrimRight(const CFX_ByteStringC& pTargets) {
948 if (!m_pData || lpszTargets.IsEmpty()) { 917 if (!m_pData || pTargets.IsEmpty()) {
949 return; 918 return;
950 } 919 }
951 CopyBeforeWrite(); 920 CopyBeforeWrite();
952 FX_STRSIZE pos = GetLength(); 921 FX_STRSIZE pos = GetLength();
953 if (pos < 1) { 922 if (pos < 1) {
954 return; 923 return;
955 } 924 }
956 while (pos) { 925 while (pos) {
957 FX_STRSIZE i = 0; 926 FX_STRSIZE i = 0;
958 while (i < lpszTargets.GetLength() && 927 while (i < pTargets.GetLength() &&
959 lpszTargets[i] != m_pData->m_String[pos - 1]) { 928 pTargets[i] != m_pData->m_String[pos - 1]) {
960 i++; 929 i++;
961 } 930 }
962 if (i == lpszTargets.GetLength()) { 931 if (i == pTargets.GetLength()) {
963 break; 932 break;
964 } 933 }
965 pos--; 934 pos--;
966 } 935 }
967 if (pos < m_pData->m_nDataLength) { 936 if (pos < m_pData->m_nDataLength) {
968 m_pData->m_String[pos] = 0; 937 m_pData->m_String[pos] = 0;
969 m_pData->m_nDataLength = pos; 938 m_pData->m_nDataLength = pos;
970 } 939 }
971 } 940 }
972 void CFX_ByteString::TrimRight(FX_CHAR chTarget) { 941 void CFX_ByteString::TrimRight(FX_CHAR chTarget) {
973 TrimRight(CFX_ByteStringC(chTarget)); 942 TrimRight(CFX_ByteStringC(chTarget));
974 } 943 }
975 void CFX_ByteString::TrimRight() { 944 void CFX_ByteString::TrimRight() {
976 TrimRight("\x09\x0a\x0b\x0c\x0d\x20"); 945 TrimRight("\x09\x0a\x0b\x0c\x0d\x20");
977 } 946 }
978 void CFX_ByteString::TrimLeft(const CFX_ByteStringC& lpszTargets) { 947 void CFX_ByteString::TrimLeft(const CFX_ByteStringC& pTargets) {
979 if (!m_pData) { 948 if (!m_pData) {
980 return; 949 return;
981 } 950 }
982 if (lpszTargets.IsEmpty()) { 951 if (pTargets.IsEmpty()) {
983 return; 952 return;
984 } 953 }
985 CopyBeforeWrite(); 954 CopyBeforeWrite();
986 FX_STRSIZE len = GetLength(); 955 FX_STRSIZE len = GetLength();
987 if (len < 1) { 956 if (len < 1) {
988 return; 957 return;
989 } 958 }
990 FX_STRSIZE pos = 0; 959 FX_STRSIZE pos = 0;
991 while (pos < len) { 960 while (pos < len) {
992 FX_STRSIZE i = 0; 961 FX_STRSIZE i = 0;
993 while (i < lpszTargets.GetLength() && 962 while (i < pTargets.GetLength() && pTargets[i] != m_pData->m_String[pos]) {
994 lpszTargets[i] != m_pData->m_String[pos]) {
995 i++; 963 i++;
996 } 964 }
997 if (i == lpszTargets.GetLength()) { 965 if (i == pTargets.GetLength()) {
998 break; 966 break;
999 } 967 }
1000 pos++; 968 pos++;
1001 } 969 }
1002 if (pos) { 970 if (pos) {
1003 FX_STRSIZE nDataLength = len - pos; 971 FX_STRSIZE nDataLength = len - pos;
1004 FXSYS_memmove(m_pData->m_String, m_pData->m_String + pos, 972 FXSYS_memmove(m_pData->m_String, m_pData->m_String + pos,
1005 (nDataLength + 1) * sizeof(FX_CHAR)); 973 (nDataLength + 1) * sizeof(FX_CHAR));
1006 m_pData->m_nDataLength = nDataLength; 974 m_pData->m_nDataLength = nDataLength;
1007 } 975 }
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
1079 fraction %= scale; 1047 fraction %= scale;
1080 scale /= 10; 1048 scale /= 10;
1081 } 1049 }
1082 return buf_size; 1050 return buf_size;
1083 } 1051 }
1084 CFX_ByteString CFX_ByteString::FormatFloat(FX_FLOAT d, int precision) { 1052 CFX_ByteString CFX_ByteString::FormatFloat(FX_FLOAT d, int precision) {
1085 FX_CHAR buf[32]; 1053 FX_CHAR buf[32];
1086 FX_STRSIZE len = FX_ftoa(d, buf); 1054 FX_STRSIZE len = FX_ftoa(d, buf);
1087 return CFX_ByteString(buf, len); 1055 return CFX_ByteString(buf, len);
1088 } 1056 }
OLDNEW
« no previous file with comments | « no previous file | core/fxcrt/fx_basic_bstring_unittest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698