| 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 |