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