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