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