• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2014 PDFium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6 
7 #ifndef CORE_INCLUDE_FXCRT_FX_STRING_H_
8 #define CORE_INCLUDE_FXCRT_FX_STRING_H_
9 
10 #include <stdint.h>  // For intptr_t.
11 #include <algorithm>
12 
13 #include "fx_memory.h"
14 #include "fx_system.h"
15 
16 class CFX_BinaryBuf;
17 class CFX_ByteString;
18 class CFX_WideString;
19 struct CFX_CharMap;
20 
21 // An immutable string with caller-provided storage which must outlive the
22 // string itself.
23 class CFX_ByteStringC {
24  public:
25   typedef FX_CHAR value_type;
26 
CFX_ByteStringC()27   CFX_ByteStringC() {
28     m_Ptr = NULL;
29     m_Length = 0;
30   }
31 
CFX_ByteStringC(const uint8_t * ptr,FX_STRSIZE size)32   CFX_ByteStringC(const uint8_t* ptr, FX_STRSIZE size) {
33     m_Ptr = ptr;
34     m_Length = size;
35   }
36 
CFX_ByteStringC(const FX_CHAR * ptr)37   CFX_ByteStringC(const FX_CHAR* ptr) {
38     m_Ptr = (const uint8_t*)ptr;
39     m_Length = ptr ? FXSYS_strlen(ptr) : 0;
40   }
41 
42   // |ch| must be an lvalue that outlives the the CFX_ByteStringC. However,
43   // the use of char rvalues are not caught at compile time.  They are
44   // implicitly promoted to CFX_ByteString (see below) and then the
45   // CFX_ByteStringC is constructed from the CFX_ByteString via the alternate
46   // constructor below. The CFX_ByteString then typically goes out of scope
47   // and |m_Ptr| may be left pointing to invalid memory. Beware.
48   // TODO(tsepez): Mark single-argument string constructors as explicit.
CFX_ByteStringC(FX_CHAR & ch)49   CFX_ByteStringC(FX_CHAR& ch) {
50     m_Ptr = (const uint8_t*)&ch;
51     m_Length = 1;
52   }
53 
CFX_ByteStringC(const FX_CHAR * ptr,FX_STRSIZE len)54   CFX_ByteStringC(const FX_CHAR* ptr, FX_STRSIZE len) {
55     m_Ptr = (const uint8_t*)ptr;
56     m_Length = (len == -1) ? FXSYS_strlen(ptr) : len;
57   }
58 
CFX_ByteStringC(const CFX_ByteStringC & src)59   CFX_ByteStringC(const CFX_ByteStringC& src) {
60     m_Ptr = src.m_Ptr;
61     m_Length = src.m_Length;
62   }
63 
64   CFX_ByteStringC(const CFX_ByteString& src);
65 
66   CFX_ByteStringC& operator=(const FX_CHAR* src) {
67     m_Ptr = (const uint8_t*)src;
68     m_Length = m_Ptr ? FXSYS_strlen(src) : 0;
69     return *this;
70   }
71 
72   CFX_ByteStringC& operator=(const CFX_ByteStringC& src) {
73     m_Ptr = src.m_Ptr;
74     m_Length = src.m_Length;
75     return *this;
76   }
77 
78   CFX_ByteStringC& operator=(const CFX_ByteString& src);
79 
80   bool operator==(const char* ptr) const {
81     return FXSYS_strlen(ptr) == m_Length &&
82            FXSYS_memcmp(ptr, m_Ptr, m_Length) == 0;
83   }
84   bool operator==(const CFX_ByteStringC& other) const {
85     return other.m_Length == m_Length &&
86            FXSYS_memcmp(other.m_Ptr, m_Ptr, m_Length) == 0;
87   }
88   bool operator!=(const char* ptr) const { return !(*this == ptr); }
89   bool operator!=(const CFX_ByteStringC& other) const {
90     return !(*this == other);
91   }
92 
93   FX_DWORD GetID(FX_STRSIZE start_pos = 0) const;
94 
GetPtr()95   const uint8_t* GetPtr() const { return m_Ptr; }
96 
GetCStr()97   const FX_CHAR* GetCStr() const { return (const FX_CHAR*)m_Ptr; }
98 
GetLength()99   FX_STRSIZE GetLength() const { return m_Length; }
100 
IsEmpty()101   bool IsEmpty() const { return m_Length == 0; }
102 
GetAt(FX_STRSIZE index)103   uint8_t GetAt(FX_STRSIZE index) const { return m_Ptr[index]; }
104 
105   CFX_ByteStringC Mid(FX_STRSIZE index, FX_STRSIZE count = -1) const {
106     if (index < 0) {
107       index = 0;
108     }
109     if (index > m_Length) {
110       return CFX_ByteStringC();
111     }
112     if (count < 0 || count > m_Length - index) {
113       count = m_Length - index;
114     }
115     return CFX_ByteStringC(m_Ptr + index, count);
116   }
117 
118   const uint8_t& operator[](size_t index) const { return m_Ptr[index]; }
119 
120   bool operator<(const CFX_ByteStringC& that) const {
121     int result = memcmp(m_Ptr, that.m_Ptr, std::min(m_Length, that.m_Length));
122     return result < 0 || (result == 0 && m_Length < that.m_Length);
123   }
124 
125  protected:
126   const uint8_t* m_Ptr;
127   FX_STRSIZE m_Length;
128 
129  private:
new(size_t)130   void* operator new(size_t) throw() { return NULL; }
131 };
132 inline bool operator==(const char* lhs, const CFX_ByteStringC& rhs) {
133   return rhs == lhs;
134 }
135 inline bool operator!=(const char* lhs, const CFX_ByteStringC& rhs) {
136   return rhs != lhs;
137 }
138 #define FXBSTR_ID(c1, c2, c3, c4) ((c1 << 24) | (c2 << 16) | (c3 << 8) | (c4))
139 
140 // A mutable string with shared buffers using copy-on-write semantics that
141 // avoids the cost of std::string's iterator stability guarantees.
142 class CFX_ByteString {
143  public:
144   typedef FX_CHAR value_type;
145 
CFX_ByteString()146   CFX_ByteString() : m_pData(nullptr) {}
147 
148   // Copy constructor.
149   CFX_ByteString(const CFX_ByteString& str);
150 
151   // Move constructor.
CFX_ByteString(CFX_ByteString && other)152   inline CFX_ByteString(CFX_ByteString&& other) {
153     m_pData = other.m_pData;
154     other.m_pData = nullptr;
155   }
156 
157   CFX_ByteString(char ch);
CFX_ByteString(const FX_CHAR * ptr)158   CFX_ByteString(const FX_CHAR* ptr)
159       : CFX_ByteString(ptr, ptr ? FXSYS_strlen(ptr) : 0) {}
160 
161   CFX_ByteString(const FX_CHAR* ptr, FX_STRSIZE len);
162   CFX_ByteString(const uint8_t* ptr, FX_STRSIZE len);
163 
164   CFX_ByteString(const CFX_ByteStringC& bstrc);
165   CFX_ByteString(const CFX_ByteStringC& bstrc1, const CFX_ByteStringC& bstrc2);
166 
167   ~CFX_ByteString();
168 
169   static CFX_ByteString FromUnicode(const FX_WCHAR* ptr, FX_STRSIZE len = -1);
170 
171   static CFX_ByteString FromUnicode(const CFX_WideString& str);
172 
173   // Explicit conversion to raw string
c_str()174   const FX_CHAR* c_str() const { return m_pData ? m_pData->m_String : ""; }
175 
176   // Implicit conversion to C-style string -- deprecated
177   operator const FX_CHAR*() const { return m_pData ? m_pData->m_String : ""; }
178 
179   operator const uint8_t*() const {
180     return m_pData ? (const uint8_t*)m_pData->m_String : NULL;
181   }
182 
GetLength()183   FX_STRSIZE GetLength() const { return m_pData ? m_pData->m_nDataLength : 0; }
184 
IsEmpty()185   bool IsEmpty() const { return !GetLength(); }
186 
187   int Compare(const CFX_ByteStringC& str) const;
188 
189   bool Equal(const char* ptr) const;
190   bool Equal(const CFX_ByteStringC& str) const;
191   bool Equal(const CFX_ByteString& other) const;
192 
193   bool EqualNoCase(const CFX_ByteStringC& str) const;
194 
195   bool operator==(const char* ptr) const { return Equal(ptr); }
196   bool operator==(const CFX_ByteStringC& str) const { return Equal(str); }
197   bool operator==(const CFX_ByteString& other) const { return Equal(other); }
198 
199   bool operator!=(const char* ptr) const { return !(*this == ptr); }
200   bool operator!=(const CFX_ByteStringC& str) const { return !(*this == str); }
201   bool operator!=(const CFX_ByteString& other) const {
202     return !(*this == other);
203   }
204 
205   bool operator<(const CFX_ByteString& str) const {
206     int result = FXSYS_memcmp(c_str(), str.c_str(),
207                               std::min(GetLength(), str.GetLength()));
208     return result < 0 || (result == 0 && GetLength() < str.GetLength());
209   }
210 
211   void Empty();
212 
213   const CFX_ByteString& operator=(const FX_CHAR* str);
214 
215   const CFX_ByteString& operator=(const CFX_ByteStringC& bstrc);
216 
217   const CFX_ByteString& operator=(const CFX_ByteString& stringSrc);
218 
219   const CFX_ByteString& operator=(const CFX_BinaryBuf& buf);
220 
221   void Load(const uint8_t* str, FX_STRSIZE len);
222 
223   const CFX_ByteString& operator+=(FX_CHAR ch);
224 
225   const CFX_ByteString& operator+=(const FX_CHAR* str);
226 
227   const CFX_ByteString& operator+=(const CFX_ByteString& str);
228 
229   const CFX_ByteString& operator+=(const CFX_ByteStringC& bstrc);
230 
GetAt(FX_STRSIZE nIndex)231   uint8_t GetAt(FX_STRSIZE nIndex) const {
232     return m_pData ? m_pData->m_String[nIndex] : 0;
233   }
234 
235   uint8_t operator[](FX_STRSIZE nIndex) const {
236     return m_pData ? m_pData->m_String[nIndex] : 0;
237   }
238 
239   void SetAt(FX_STRSIZE nIndex, FX_CHAR ch);
240 
241   FX_STRSIZE Insert(FX_STRSIZE index, FX_CHAR ch);
242 
243   FX_STRSIZE Delete(FX_STRSIZE index, FX_STRSIZE count = 1);
244 
245   void Format(const FX_CHAR* lpszFormat, ...);
246 
247   void FormatV(const FX_CHAR* lpszFormat, va_list argList);
248 
249   void Reserve(FX_STRSIZE len);
250 
251   FX_CHAR* GetBuffer(FX_STRSIZE len);
252 
253   void ReleaseBuffer(FX_STRSIZE len = -1);
254 
255   CFX_ByteString Mid(FX_STRSIZE first) const;
256 
257   CFX_ByteString Mid(FX_STRSIZE first, FX_STRSIZE count) const;
258 
259   CFX_ByteString Left(FX_STRSIZE count) const;
260 
261   CFX_ByteString Right(FX_STRSIZE count) const;
262 
263   FX_STRSIZE Find(const CFX_ByteStringC& lpszSub, FX_STRSIZE start = 0) const;
264 
265   FX_STRSIZE Find(FX_CHAR ch, FX_STRSIZE start = 0) const;
266 
267   FX_STRSIZE ReverseFind(FX_CHAR ch) const;
268 
269   void MakeLower();
270 
271   void MakeUpper();
272 
273   void TrimRight();
274 
275   void TrimRight(FX_CHAR chTarget);
276 
277   void TrimRight(const CFX_ByteStringC& lpszTargets);
278 
279   void TrimLeft();
280 
281   void TrimLeft(FX_CHAR chTarget);
282 
283   void TrimLeft(const CFX_ByteStringC& lpszTargets);
284 
285   FX_STRSIZE Replace(const CFX_ByteStringC& lpszOld,
286                      const CFX_ByteStringC& lpszNew);
287 
288   FX_STRSIZE Remove(FX_CHAR ch);
289 
290   CFX_WideString UTF8Decode() const;
291 
292   void ConvertFrom(const CFX_WideString& str, CFX_CharMap* pCharMap = NULL);
293 
294   FX_DWORD GetID(FX_STRSIZE start_pos = 0) const;
295 
296 #define FXFORMAT_SIGNED 1
297 #define FXFORMAT_HEX 2
298 #define FXFORMAT_CAPITAL 4
299 
300   static CFX_ByteString FormatInteger(int i, FX_DWORD flags = 0);
301   static CFX_ByteString FormatFloat(FX_FLOAT f, int precision = 0);
302 
303  protected:
304   // To ensure ref counts do not overflow, consider the worst possible case:
305   // the entire address space contains nothing but pointers to this object.
306   // Since the count increments with each new pointer, the largest value is
307   // the number of pointers that can fit into the address space. The size of
308   // the address space itself is a good upper bound on it; we need not go
309   // larger.
310   class StringData {
311    public:
312     static StringData* Create(int nLen);
Retain()313     void Retain() { ++m_nRefs; }
Release()314     void Release() {
315       if (--m_nRefs <= 0)
316         FX_Free(this);
317     }
318 
319     intptr_t m_nRefs;  // Would prefer ssize_t, but no windows support.
320     FX_STRSIZE m_nDataLength;
321     FX_STRSIZE m_nAllocLength;
322     FX_CHAR m_String[1];
323 
324    private:
StringData(FX_STRSIZE dataLen,FX_STRSIZE allocLen)325     StringData(FX_STRSIZE dataLen, FX_STRSIZE allocLen)
326         : m_nRefs(1), m_nDataLength(dataLen), m_nAllocLength(allocLen) {
327       FXSYS_assert(dataLen >= 0);
328       FXSYS_assert(allocLen >= 0);
329       FXSYS_assert(dataLen <= allocLen);
330       m_String[dataLen] = 0;
331     }
332     ~StringData() = delete;
333   };
334 
335   void AllocCopy(CFX_ByteString& dest,
336                  FX_STRSIZE nCopyLen,
337                  FX_STRSIZE nCopyIndex) const;
338   void AssignCopy(FX_STRSIZE nSrcLen, const FX_CHAR* lpszSrcData);
339   void ConcatCopy(FX_STRSIZE nSrc1Len,
340                   const FX_CHAR* lpszSrc1Data,
341                   FX_STRSIZE nSrc2Len,
342                   const FX_CHAR* lpszSrc2Data);
343   void ConcatInPlace(FX_STRSIZE nSrcLen, const FX_CHAR* lpszSrcData);
344   void CopyBeforeWrite();
345   void AllocBeforeWrite(FX_STRSIZE nLen);
346 
347   StringData* m_pData;
348   friend class fxcrt_ByteStringConcatInPlace_Test;
349 };
CFX_ByteStringC(const CFX_ByteString & src)350 inline CFX_ByteStringC::CFX_ByteStringC(const CFX_ByteString& src) {
351   m_Ptr = (const uint8_t*)src;
352   m_Length = src.GetLength();
353 }
354 inline CFX_ByteStringC& CFX_ByteStringC::operator=(const CFX_ByteString& src) {
355   m_Ptr = (const uint8_t*)src;
356   m_Length = src.GetLength();
357   return *this;
358 }
359 
360 inline bool operator==(const char* lhs, const CFX_ByteString& rhs) {
361   return rhs == lhs;
362 }
363 inline bool operator==(const CFX_ByteStringC& lhs, const CFX_ByteString& rhs) {
364   return rhs == lhs;
365 }
366 inline bool operator!=(const char* lhs, const CFX_ByteString& rhs) {
367   return rhs != lhs;
368 }
369 inline bool operator!=(const CFX_ByteStringC& lhs, const CFX_ByteString& rhs) {
370   return rhs != lhs;
371 }
372 
373 inline CFX_ByteString operator+(const CFX_ByteStringC& str1,
374                                 const CFX_ByteStringC& str2) {
375   return CFX_ByteString(str1, str2);
376 }
377 inline CFX_ByteString operator+(const CFX_ByteStringC& str1,
378                                 const FX_CHAR* str2) {
379   return CFX_ByteString(str1, str2);
380 }
381 inline CFX_ByteString operator+(const FX_CHAR* str1,
382                                 const CFX_ByteStringC& str2) {
383   return CFX_ByteString(str1, str2);
384 }
385 inline CFX_ByteString operator+(const CFX_ByteStringC& str1, FX_CHAR ch) {
386   return CFX_ByteString(str1, CFX_ByteStringC(ch));
387 }
388 inline CFX_ByteString operator+(FX_CHAR ch, const CFX_ByteStringC& str2) {
389   return CFX_ByteString(ch, str2);
390 }
391 inline CFX_ByteString operator+(const CFX_ByteString& str1,
392                                 const CFX_ByteString& str2) {
393   return CFX_ByteString(str1, str2);
394 }
395 inline CFX_ByteString operator+(const CFX_ByteString& str1, FX_CHAR ch) {
396   return CFX_ByteString(str1, CFX_ByteStringC(ch));
397 }
398 inline CFX_ByteString operator+(FX_CHAR ch, const CFX_ByteString& str2) {
399   return CFX_ByteString(ch, str2);
400 }
401 inline CFX_ByteString operator+(const CFX_ByteString& str1,
402                                 const FX_CHAR* str2) {
403   return CFX_ByteString(str1, str2);
404 }
405 inline CFX_ByteString operator+(const FX_CHAR* str1,
406                                 const CFX_ByteString& str2) {
407   return CFX_ByteString(str1, str2);
408 }
409 inline CFX_ByteString operator+(const CFX_ByteString& str1,
410                                 const CFX_ByteStringC& str2) {
411   return CFX_ByteString(str1, str2);
412 }
413 inline CFX_ByteString operator+(const CFX_ByteStringC& str1,
414                                 const CFX_ByteString& str2) {
415   return CFX_ByteString(str1, str2);
416 }
417 class CFX_WideStringC {
418  public:
419   typedef FX_WCHAR value_type;
420 
CFX_WideStringC()421   CFX_WideStringC() {
422     m_Ptr = NULL;
423     m_Length = 0;
424   }
425 
CFX_WideStringC(const FX_WCHAR * ptr)426   CFX_WideStringC(const FX_WCHAR* ptr) {
427     m_Ptr = ptr;
428     m_Length = ptr ? FXSYS_wcslen(ptr) : 0;
429   }
430 
CFX_WideStringC(FX_WCHAR & ch)431   CFX_WideStringC(FX_WCHAR& ch) {
432     m_Ptr = &ch;
433     m_Length = 1;
434   }
435 
CFX_WideStringC(const FX_WCHAR * ptr,FX_STRSIZE len)436   CFX_WideStringC(const FX_WCHAR* ptr, FX_STRSIZE len) {
437     m_Ptr = ptr;
438     m_Length = (len == -1) ? FXSYS_wcslen(ptr) : len;
439   }
440 
CFX_WideStringC(const CFX_WideStringC & src)441   CFX_WideStringC(const CFX_WideStringC& src) {
442     m_Ptr = src.m_Ptr;
443     m_Length = src.m_Length;
444   }
445 
446   CFX_WideStringC(const CFX_WideString& src);
447 
448   CFX_WideStringC& operator=(const FX_WCHAR* src) {
449     m_Ptr = src;
450     m_Length = FXSYS_wcslen(src);
451     return *this;
452   }
453 
454   CFX_WideStringC& operator=(const CFX_WideStringC& src) {
455     m_Ptr = src.m_Ptr;
456     m_Length = src.m_Length;
457     return *this;
458   }
459 
460   CFX_WideStringC& operator=(const CFX_WideString& src);
461 
462   bool operator==(const wchar_t* ptr) const {
463     return FXSYS_wcslen(ptr) == m_Length && wmemcmp(ptr, m_Ptr, m_Length) == 0;
464   }
465   bool operator==(const CFX_WideStringC& str) const {
466     return str.m_Length == m_Length && wmemcmp(str.m_Ptr, m_Ptr, m_Length) == 0;
467   }
468   bool operator!=(const wchar_t* ptr) const { return !(*this == ptr); }
469   bool operator!=(const CFX_WideStringC& str) const { return !(*this == str); }
470 
GetPtr()471   const FX_WCHAR* GetPtr() const { return m_Ptr; }
472 
GetLength()473   FX_STRSIZE GetLength() const { return m_Length; }
474 
IsEmpty()475   bool IsEmpty() const { return m_Length == 0; }
476 
GetAt(FX_STRSIZE index)477   FX_WCHAR GetAt(FX_STRSIZE index) const { return m_Ptr[index]; }
478 
Left(FX_STRSIZE count)479   CFX_WideStringC Left(FX_STRSIZE count) const {
480     if (count < 1) {
481       return CFX_WideStringC();
482     }
483     if (count > m_Length) {
484       count = m_Length;
485     }
486     return CFX_WideStringC(m_Ptr, count);
487   }
488 
489   CFX_WideStringC Mid(FX_STRSIZE index, FX_STRSIZE count = -1) const {
490     if (index < 0) {
491       index = 0;
492     }
493     if (index > m_Length) {
494       return CFX_WideStringC();
495     }
496     if (count < 0 || count > m_Length - index) {
497       count = m_Length - index;
498     }
499     return CFX_WideStringC(m_Ptr + index, count);
500   }
501 
Right(FX_STRSIZE count)502   CFX_WideStringC Right(FX_STRSIZE count) const {
503     if (count < 1) {
504       return CFX_WideStringC();
505     }
506     if (count > m_Length) {
507       count = m_Length;
508     }
509     return CFX_WideStringC(m_Ptr + m_Length - count, count);
510   }
511 
512   const FX_WCHAR& operator[](size_t index) const { return m_Ptr[index]; }
513 
514   bool operator<(const CFX_WideStringC& that) const {
515     int result = wmemcmp(m_Ptr, that.m_Ptr, std::min(m_Length, that.m_Length));
516     return result < 0 || (result == 0 && m_Length < that.m_Length);
517   }
518 
519  protected:
520   const FX_WCHAR* m_Ptr;
521   FX_STRSIZE m_Length;
522 
523  private:
new(size_t)524   void* operator new(size_t) throw() { return NULL; }
525 };
526 inline bool operator==(const wchar_t* lhs, const CFX_WideStringC& rhs) {
527   return rhs == lhs;
528 }
529 inline bool operator!=(const wchar_t* lhs, const CFX_WideStringC& rhs) {
530   return rhs != lhs;
531 }
532 #define FX_WSTRC(wstr) CFX_WideStringC(wstr, FX_ArraySize(wstr) - 1)
533 
534 // A mutable string with shared buffers using copy-on-write semantics that
535 // avoids the cost of std::string's iterator stability guarantees.
536 class CFX_WideString {
537  public:
538   typedef FX_WCHAR value_type;
539 
CFX_WideString()540   CFX_WideString() : m_pData(nullptr) {}
541 
542   // Copy constructor.
543   CFX_WideString(const CFX_WideString& str);
544 
545   // Move constructor.
CFX_WideString(CFX_WideString && other)546   inline CFX_WideString(CFX_WideString&& other) {
547     m_pData = other.m_pData;
548     other.m_pData = nullptr;
549   }
550 
CFX_WideString(const FX_WCHAR * ptr)551   CFX_WideString(const FX_WCHAR* ptr)
552       : CFX_WideString(ptr, ptr ? FXSYS_wcslen(ptr) : 0) {}
553 
554   CFX_WideString(const FX_WCHAR* ptr, FX_STRSIZE len);
555 
556   CFX_WideString(FX_WCHAR ch);
557 
558   CFX_WideString(const CFX_WideStringC& str);
559 
560   CFX_WideString(const CFX_WideStringC& str1, const CFX_WideStringC& str2);
561 
562   ~CFX_WideString();
563 
564   static CFX_WideString FromLocal(const char* str, FX_STRSIZE len = -1);
565 
566   static CFX_WideString FromUTF8(const char* str, FX_STRSIZE len);
567 
568   static CFX_WideString FromUTF16LE(const unsigned short* str, FX_STRSIZE len);
569 
570   static FX_STRSIZE WStringLength(const unsigned short* str);
571 
572   // Explicit conversion to raw string
c_str()573   const FX_WCHAR* c_str() const { return m_pData ? m_pData->m_String : L""; }
574 
575   // Implicit conversion to C-style wide string -- deprecated
576   operator const FX_WCHAR*() const { return m_pData ? m_pData->m_String : L""; }
577 
578   void Empty();
579 
IsEmpty()580   FX_BOOL IsEmpty() const { return !GetLength(); }
581 
GetLength()582   FX_STRSIZE GetLength() const { return m_pData ? m_pData->m_nDataLength : 0; }
583 
584   const CFX_WideString& operator=(const FX_WCHAR* str);
585 
586   const CFX_WideString& operator=(const CFX_WideString& stringSrc);
587 
588   const CFX_WideString& operator=(const CFX_WideStringC& stringSrc);
589 
590   const CFX_WideString& operator+=(const FX_WCHAR* str);
591 
592   const CFX_WideString& operator+=(FX_WCHAR ch);
593 
594   const CFX_WideString& operator+=(const CFX_WideString& str);
595 
596   const CFX_WideString& operator+=(const CFX_WideStringC& str);
597 
598   bool operator==(const wchar_t* ptr) const { return Equal(ptr); }
599   bool operator==(const CFX_WideStringC& str) const { return Equal(str); }
600   bool operator==(const CFX_WideString& other) const { return Equal(other); }
601 
602   bool operator!=(const wchar_t* ptr) const { return !(*this == ptr); }
603   bool operator!=(const CFX_WideStringC& str) const { return !(*this == str); }
604   bool operator!=(const CFX_WideString& other) const {
605     return !(*this == other);
606   }
607 
608   bool operator<(const CFX_WideString& str) const {
609     int result =
610         wmemcmp(c_str(), str.c_str(), std::min(GetLength(), str.GetLength()));
611     return result < 0 || (result == 0 && GetLength() < str.GetLength());
612   }
613 
GetAt(FX_STRSIZE nIndex)614   FX_WCHAR GetAt(FX_STRSIZE nIndex) const {
615     return m_pData ? m_pData->m_String[nIndex] : 0;
616   }
617 
618   FX_WCHAR operator[](FX_STRSIZE nIndex) const {
619     return m_pData ? m_pData->m_String[nIndex] : 0;
620   }
621 
622   void SetAt(FX_STRSIZE nIndex, FX_WCHAR ch);
623 
624   int Compare(const FX_WCHAR* str) const;
625 
626   int Compare(const CFX_WideString& str) const;
627 
628   int CompareNoCase(const FX_WCHAR* str) const;
629 
630   bool Equal(const wchar_t* ptr) const;
631   bool Equal(const CFX_WideStringC& str) const;
632   bool Equal(const CFX_WideString& other) const;
633 
634   CFX_WideString Mid(FX_STRSIZE first) const;
635 
636   CFX_WideString Mid(FX_STRSIZE first, FX_STRSIZE count) const;
637 
638   CFX_WideString Left(FX_STRSIZE count) const;
639 
640   CFX_WideString Right(FX_STRSIZE count) const;
641 
642   FX_STRSIZE Insert(FX_STRSIZE index, FX_WCHAR ch);
643 
644   FX_STRSIZE Delete(FX_STRSIZE index, FX_STRSIZE count = 1);
645 
646   void Format(const FX_WCHAR* lpszFormat, ...);
647 
648   void FormatV(const FX_WCHAR* lpszFormat, va_list argList);
649 
650   void MakeLower();
651 
652   void MakeUpper();
653 
654   void TrimRight();
655 
656   void TrimRight(FX_WCHAR chTarget);
657 
658   void TrimRight(const FX_WCHAR* lpszTargets);
659 
660   void TrimLeft();
661 
662   void TrimLeft(FX_WCHAR chTarget);
663 
664   void TrimLeft(const FX_WCHAR* lpszTargets);
665 
666   void Reserve(FX_STRSIZE len);
667 
668   FX_WCHAR* GetBuffer(FX_STRSIZE len);
669 
670   void ReleaseBuffer(FX_STRSIZE len = -1);
671 
672   int GetInteger() const;
673 
674   FX_FLOAT GetFloat() const;
675 
676   FX_STRSIZE Find(const FX_WCHAR* lpszSub, FX_STRSIZE start = 0) const;
677 
678   FX_STRSIZE Find(FX_WCHAR ch, FX_STRSIZE start = 0) const;
679 
680   FX_STRSIZE Replace(const FX_WCHAR* lpszOld, const FX_WCHAR* lpszNew);
681 
682   FX_STRSIZE Remove(FX_WCHAR ch);
683 
684   CFX_ByteString UTF8Encode() const;
685 
686   CFX_ByteString UTF16LE_Encode() const;
687 
688   void ConvertFrom(const CFX_ByteString& str, CFX_CharMap* pCharMap = NULL);
689 
690  protected:
691   class StringData {
692    public:
693     static StringData* Create(int nLen);
Retain()694     void Retain() { ++m_nRefs; }
Release()695     void Release() {
696       if (--m_nRefs <= 0)
697         FX_Free(this);
698     }
699 
700     intptr_t m_nRefs;  // Would prefer ssize_t, but no windows support.
701     FX_STRSIZE m_nDataLength;
702     FX_STRSIZE m_nAllocLength;
703     FX_WCHAR m_String[1];
704 
705    private:
StringData(FX_STRSIZE dataLen,FX_STRSIZE allocLen)706     StringData(FX_STRSIZE dataLen, FX_STRSIZE allocLen)
707         : m_nRefs(1), m_nDataLength(dataLen), m_nAllocLength(allocLen) {
708       FXSYS_assert(dataLen >= 0);
709       FXSYS_assert(allocLen >= 0);
710       FXSYS_assert(dataLen <= allocLen);
711       m_String[dataLen] = 0;
712     }
713     ~StringData() = delete;
714   };
715 
716   void CopyBeforeWrite();
717   void AllocBeforeWrite(FX_STRSIZE nLen);
718   void ConcatInPlace(FX_STRSIZE nSrcLen, const FX_WCHAR* lpszSrcData);
719   void ConcatCopy(FX_STRSIZE nSrc1Len,
720                   const FX_WCHAR* lpszSrc1Data,
721                   FX_STRSIZE nSrc2Len,
722                   const FX_WCHAR* lpszSrc2Data);
723   void AssignCopy(FX_STRSIZE nSrcLen, const FX_WCHAR* lpszSrcData);
724   void AllocCopy(CFX_WideString& dest,
725                  FX_STRSIZE nCopyLen,
726                  FX_STRSIZE nCopyIndex) const;
727 
728   StringData* m_pData;
729   friend class fxcrt_WideStringConcatInPlace_Test;
730 };
CFX_WideStringC(const CFX_WideString & src)731 inline CFX_WideStringC::CFX_WideStringC(const CFX_WideString& src) {
732   m_Ptr = src.c_str();
733   m_Length = src.GetLength();
734 }
735 inline CFX_WideStringC& CFX_WideStringC::operator=(const CFX_WideString& src) {
736   m_Ptr = src.c_str();
737   m_Length = src.GetLength();
738   return *this;
739 }
740 
741 inline CFX_WideString operator+(const CFX_WideStringC& str1,
742                                 const CFX_WideStringC& str2) {
743   return CFX_WideString(str1, str2);
744 }
745 inline CFX_WideString operator+(const CFX_WideStringC& str1,
746                                 const FX_WCHAR* str2) {
747   return CFX_WideString(str1, str2);
748 }
749 inline CFX_WideString operator+(const FX_WCHAR* str1,
750                                 const CFX_WideStringC& str2) {
751   return CFX_WideString(str1, str2);
752 }
753 inline CFX_WideString operator+(const CFX_WideStringC& str1, FX_WCHAR ch) {
754   return CFX_WideString(str1, CFX_WideStringC(ch));
755 }
756 inline CFX_WideString operator+(FX_WCHAR ch, const CFX_WideStringC& str2) {
757   return CFX_WideString(ch, str2);
758 }
759 inline CFX_WideString operator+(const CFX_WideString& str1,
760                                 const CFX_WideString& str2) {
761   return CFX_WideString(str1, str2);
762 }
763 inline CFX_WideString operator+(const CFX_WideString& str1, FX_WCHAR ch) {
764   return CFX_WideString(str1, CFX_WideStringC(ch));
765 }
766 inline CFX_WideString operator+(FX_WCHAR ch, const CFX_WideString& str2) {
767   return CFX_WideString(ch, str2);
768 }
769 inline CFX_WideString operator+(const CFX_WideString& str1,
770                                 const FX_WCHAR* str2) {
771   return CFX_WideString(str1, str2);
772 }
773 inline CFX_WideString operator+(const FX_WCHAR* str1,
774                                 const CFX_WideString& str2) {
775   return CFX_WideString(str1, str2);
776 }
777 inline CFX_WideString operator+(const CFX_WideString& str1,
778                                 const CFX_WideStringC& str2) {
779   return CFX_WideString(str1, str2);
780 }
781 inline CFX_WideString operator+(const CFX_WideStringC& str1,
782                                 const CFX_WideString& str2) {
783   return CFX_WideString(str1, str2);
784 }
785 inline bool operator==(const wchar_t* lhs, const CFX_WideString& rhs) {
786   return rhs == lhs;
787 }
788 inline bool operator==(const CFX_WideStringC& lhs, const CFX_WideString& rhs) {
789   return rhs == lhs;
790 }
791 inline bool operator!=(const wchar_t* lhs, const CFX_WideString& rhs) {
792   return rhs != lhs;
793 }
794 inline bool operator!=(const CFX_WideStringC& lhs, const CFX_WideString& rhs) {
795   return rhs != lhs;
796 }
797 FX_FLOAT FX_atof(const CFX_ByteStringC& str);
798 void FX_atonum(const CFX_ByteStringC& str, FX_BOOL& bInteger, void* pData);
799 FX_STRSIZE FX_ftoa(FX_FLOAT f, FX_CHAR* buf);
800 CFX_ByteString FX_UTF8Encode(const FX_WCHAR* pwsStr, FX_STRSIZE len);
FX_UTF8Encode(const CFX_WideStringC & wsStr)801 inline CFX_ByteString FX_UTF8Encode(const CFX_WideStringC& wsStr) {
802   return FX_UTF8Encode(wsStr.GetPtr(), wsStr.GetLength());
803 }
FX_UTF8Encode(const CFX_WideString & wsStr)804 inline CFX_ByteString FX_UTF8Encode(const CFX_WideString& wsStr) {
805   return FX_UTF8Encode(wsStr.c_str(), wsStr.GetLength());
806 }
807 
808 #endif  // CORE_INCLUDE_FXCRT_FX_STRING_H_
809