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