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     void                                        ReleaseBuffer(FX_STRSIZE len = -1);
324
325     CFX_ByteString                      Mid(FX_STRSIZE first) const;
326
327     CFX_ByteString                      Mid(FX_STRSIZE first, FX_STRSIZE count) const;
328
329     CFX_ByteString                      Left(FX_STRSIZE count) const;
330
331     CFX_ByteString                      Right(FX_STRSIZE count) const;
332
333     FX_STRSIZE                          Find(FX_BSTR lpszSub, FX_STRSIZE start = 0) const;
334
335     FX_STRSIZE                          Find(FX_CHAR ch, FX_STRSIZE start = 0) const;
336
337     FX_STRSIZE                          ReverseFind(FX_CHAR ch) const;
338
339     void                                        MakeLower();
340
341     void                                        MakeUpper();
342
343     void                                        TrimRight();
344
345     void                                        TrimRight(FX_CHAR chTarget);
346
347     void                                        TrimRight(FX_BSTR lpszTargets);
348
349     void                                        TrimLeft();
350
351     void                                        TrimLeft(FX_CHAR chTarget);
352
353     void                                        TrimLeft(FX_BSTR lpszTargets);
354
355     FX_STRSIZE                          Replace(FX_BSTR lpszOld, FX_BSTR lpszNew);
356
357     FX_STRSIZE                          Remove(FX_CHAR ch);
358
359     CFX_WideString                      UTF8Decode() const;
360
361     void                                        ConvertFrom(const CFX_WideString& str, CFX_CharMap* pCharMap = NULL);
362
363     FX_DWORD                            GetID(FX_STRSIZE start_pos = 0) const;
364
365 #define FXFORMAT_SIGNED                 1
366 #define FXFORMAT_HEX                    2
367 #define FXFORMAT_CAPITAL                4
368
369     static CFX_ByteString       FormatInteger(int i, FX_DWORD flags = 0);
370
371     static CFX_ByteString       FormatFloat(FX_FLOAT f, int precision = 0);
372 protected:
373
374     struct CFX_StringData*      m_pData;
375     void                                        AllocCopy(CFX_ByteString& dest, FX_STRSIZE nCopyLen, FX_STRSIZE nCopyIndex) const;
376     void                                        AssignCopy(FX_STRSIZE nSrcLen, FX_LPCSTR lpszSrcData);
377     void                                        ConcatCopy(FX_STRSIZE nSrc1Len, FX_LPCSTR lpszSrc1Data, FX_STRSIZE nSrc2Len, FX_LPCSTR lpszSrc2Data);
378     void                                        ConcatInPlace(FX_STRSIZE nSrcLen, FX_LPCSTR lpszSrcData);
379     void                                        CopyBeforeWrite();
380     void                                        AllocBeforeWrite(FX_STRSIZE nLen);
381 };
382 inline CFX_ByteStringC::CFX_ByteStringC(const CFX_ByteString& src)
383 {
384     m_Ptr = (FX_LPCBYTE)src;
385     m_Length = src.GetLength();
386 }
387 inline CFX_ByteStringC& CFX_ByteStringC::operator = (const CFX_ByteString& src)
388 {
389     m_Ptr = (FX_LPCBYTE)src;
390     m_Length = src.GetLength();
391     return *this;
392 }
393
394 inline CFX_ByteString operator + (FX_BSTR str1, FX_BSTR str2)
395 {
396     return CFX_ByteString(str1, str2);
397 }
398 inline CFX_ByteString operator + (FX_BSTR str1, FX_LPCSTR str2)
399 {
400     return CFX_ByteString(str1, str2);
401 }
402 inline CFX_ByteString operator + (FX_LPCSTR str1, FX_BSTR str2)
403 {
404     return CFX_ByteString(str1, str2);
405 }
406 inline CFX_ByteString operator + (FX_BSTR str1, FX_CHAR ch)
407 {
408     return CFX_ByteString(str1, CFX_ByteStringC(ch));
409 }
410 inline CFX_ByteString operator + (FX_CHAR ch, FX_BSTR str2)
411 {
412     return CFX_ByteString(ch, str2);
413 }
414 inline CFX_ByteString operator + (const CFX_ByteString& str1, const CFX_ByteString& str2)
415 {
416     return CFX_ByteString(str1, str2);
417 }
418 inline CFX_ByteString operator + (const CFX_ByteString& str1, FX_CHAR ch)
419 {
420     return CFX_ByteString(str1, CFX_ByteStringC(ch));
421 }
422 inline CFX_ByteString operator + (FX_CHAR ch, const CFX_ByteString& str2)
423 {
424     return CFX_ByteString(ch, str2);
425 }
426 inline CFX_ByteString operator + (const CFX_ByteString& str1, FX_LPCSTR str2)
427 {
428     return CFX_ByteString(str1, str2);
429 }
430 inline CFX_ByteString operator + (FX_LPCSTR str1, const CFX_ByteString& str2)
431 {
432     return CFX_ByteString(str1, str2);
433 }
434 inline CFX_ByteString operator + (const CFX_ByteString& str1, FX_BSTR str2)
435 {
436     return CFX_ByteString(str1, str2);
437 }
438 inline CFX_ByteString operator + (FX_BSTR str1, const CFX_ByteString& str2)
439 {
440     return CFX_ByteString(str1, str2);
441 }
442 class CFX_WideStringC
443 {
444 public:
445     typedef FX_WCHAR value_type;
446
447     CFX_WideStringC()
448     {
449         m_Ptr = NULL;
450         m_Length = 0;
451     }
452
453     CFX_WideStringC(FX_LPCWSTR ptr)
454     {
455         m_Ptr = ptr;
456         m_Length = ptr ? (FX_STRSIZE)FXSYS_wcslen(ptr) : 0;
457     }
458
459     CFX_WideStringC(FX_WCHAR& ch)
460     {
461         m_Ptr = &ch;
462         m_Length = 1;
463     }
464
465     CFX_WideStringC(FX_LPCWSTR ptr, FX_STRSIZE len)
466     {
467         m_Ptr = ptr;
468         if (len == -1) {
469             m_Length = (FX_STRSIZE)FXSYS_wcslen(ptr);
470         } else {
471             m_Length = len;
472         }
473     }
474
475     CFX_WideStringC(const CFX_WideStringC& src)
476     {
477         m_Ptr = src.m_Ptr;
478         m_Length = src.m_Length;
479     }
480
481     CFX_WideStringC(const CFX_WideString& src);
482
483     CFX_WideStringC& operator = (FX_LPCWSTR src)
484     {
485         m_Ptr = src;
486         m_Length = (FX_STRSIZE)FXSYS_wcslen(src);
487         return *this;
488     }
489
490     CFX_WideStringC& operator = (const CFX_WideStringC& src)
491     {
492         m_Ptr = src.m_Ptr;
493         m_Length = src.m_Length;
494         return *this;
495     }
496
497     CFX_WideStringC& operator = (const CFX_WideString& src);
498
499     bool                        operator == (const CFX_WideStringC& str) const
500     {
501         return  str.m_Length == m_Length && FXSYS_memcmp32(str.m_Ptr, m_Ptr, m_Length * sizeof(FX_WCHAR)) == 0;
502     }
503
504     bool                        operator != (const CFX_WideStringC& str) const
505     {
506         return  str.m_Length != m_Length || FXSYS_memcmp32(str.m_Ptr, m_Ptr, m_Length * sizeof(FX_WCHAR)) != 0;
507     }
508
509     FX_LPCWSTR          GetPtr() const
510     {
511         return m_Ptr;
512     }
513
514     FX_STRSIZE          GetLength() const
515     {
516         return m_Length;
517     }
518
519     bool                        IsEmpty() const
520     {
521         return m_Length == 0;
522     }
523
524     FX_WCHAR            GetAt(FX_STRSIZE index) const
525     {
526         return m_Ptr[index];
527     }
528
529     CFX_WideStringC     Left(FX_STRSIZE count) const
530     {
531         if (count < 1) {
532             return CFX_WideStringC();
533         }
534         if (count > m_Length) {
535             count = m_Length;
536         }
537         return CFX_WideStringC(m_Ptr, count);
538     }
539
540     CFX_WideStringC     Mid(FX_STRSIZE index, FX_STRSIZE count = -1) const
541     {
542         if (index < 0) {
543             index = 0;
544         }
545         if (index > m_Length) {
546             return CFX_WideStringC();
547         }
548         if (count < 0 || count > m_Length - index) {
549             count = m_Length - index;
550         }
551         return CFX_WideStringC(m_Ptr + index, count);
552     }
553
554     CFX_WideStringC     Right(FX_STRSIZE count) const
555     {
556         if (count < 1) {
557             return CFX_WideStringC();
558         }
559         if (count > m_Length) {
560             count = m_Length;
561         }
562         return CFX_WideStringC(m_Ptr + m_Length - count, count);
563     }
564
565     const FX_WCHAR& operator[] (size_t index) const
566     {
567         return m_Ptr[index];
568     }
569
570     bool operator< (const CFX_WideStringC& that) const
571     {
572         int result = wmemcmp(m_Ptr, that.m_Ptr, std::min(m_Length, that.m_Length));
573         return result < 0 || (result == 0 && m_Length < that.m_Length);
574      }
575
576 protected:
577     FX_LPCWSTR          m_Ptr;
578     FX_STRSIZE          m_Length;
579
580 private:
581     void*                       operator new (size_t) throw()
582     {
583         return NULL;
584     }
585 };
586 typedef const CFX_WideStringC&  FX_WSTR;
587 #define FX_WSTRC(wstr) CFX_WideStringC(wstr, FX_ArraySize(wstr) - 1)
588 struct CFX_StringDataW {
589
590     long                m_nRefs;
591
592     FX_STRSIZE  m_nDataLength;
593
594     FX_STRSIZE  m_nAllocLength;
595
596     FX_WCHAR    m_String[1];
597 };
598 class CFX_WideString 
599 {
600 public:
601     typedef FX_WCHAR value_type;
602
603     CFX_WideString()
604     {
605         m_pData = NULL;
606     }
607
608     CFX_WideString(const CFX_WideString& str);
609
610     CFX_WideString(FX_LPCWSTR ptr, FX_STRSIZE len = -1)
611     {
612         InitStr(ptr, len);
613     }
614
615     CFX_WideString(FX_WCHAR ch);
616
617     CFX_WideString(const CFX_WideStringC& str);
618
619     CFX_WideString(const CFX_WideStringC& str1, const CFX_WideStringC& str2);
620
621     ~CFX_WideString();
622
623     static CFX_WideString       FromLocal(const char* str, FX_STRSIZE len = -1);
624
625     static CFX_WideString       FromUTF8(const char* str, FX_STRSIZE len);
626
627     static CFX_WideString       FromUTF16LE(const unsigned short* str, FX_STRSIZE len);
628
629     static FX_STRSIZE       WStringLength(const unsigned short* str);
630
631     // Explicit conversion to raw string
632     FX_LPCWSTR c_str() const
633     {
634         return m_pData ? m_pData->m_String : L"";
635     }
636
637     // Implicit conversion to C-style wide string -- deprecated
638     operator FX_LPCWSTR() const
639     {
640         return m_pData ? m_pData->m_String : L"";
641     }
642
643     void                                        Empty();
644
645
646     FX_BOOL                                     IsEmpty() const
647     {
648         return !GetLength();
649     }
650
651     FX_STRSIZE                          GetLength() const
652     {
653         return m_pData ? m_pData->m_nDataLength : 0;
654     }
655
656     const CFX_WideString&       operator = (FX_LPCWSTR str);
657
658     const CFX_WideString&       operator =(const CFX_WideString& stringSrc);
659
660     const CFX_WideString&       operator =(const CFX_WideStringC& stringSrc);
661
662     const CFX_WideString&       operator += (FX_LPCWSTR str);
663
664     const CFX_WideString&       operator += (FX_WCHAR ch);
665
666     const CFX_WideString&       operator += (const CFX_WideString& str);
667
668     const CFX_WideString&       operator += (const CFX_WideStringC& str);
669
670     bool operator< (const CFX_WideString& str) const {
671         int result = wmemcmp(c_str(), str.c_str(), std::min(GetLength(), str.GetLength()));
672         return result < 0 || (result == 0 && GetLength() < str.GetLength());
673     }
674
675     FX_WCHAR                            GetAt(FX_STRSIZE nIndex) const
676     {
677         return m_pData ? m_pData->m_String[nIndex] : 0;
678     }
679
680     FX_WCHAR                            operator[](FX_STRSIZE nIndex) const
681     {
682         return m_pData ? m_pData->m_String[nIndex] : 0;
683     }
684
685     void                                        SetAt(FX_STRSIZE nIndex, FX_WCHAR ch);
686
687     int                                         Compare(FX_LPCWSTR str) const;
688
689     int                                         Compare(const CFX_WideString& str) const;
690
691     int                                         CompareNoCase(FX_LPCWSTR str) const;
692
693     bool                                        Equal(const CFX_WideStringC& str) const;
694
695     CFX_WideString                      Mid(FX_STRSIZE first) const;
696
697     CFX_WideString                      Mid(FX_STRSIZE first, FX_STRSIZE count) const;
698
699     CFX_WideString                      Left(FX_STRSIZE count) const;
700
701     CFX_WideString                      Right(FX_STRSIZE count) const;
702
703     FX_STRSIZE                          Insert(FX_STRSIZE index, FX_WCHAR ch);
704
705     FX_STRSIZE                          Delete(FX_STRSIZE index, FX_STRSIZE count = 1);
706
707     void                                        Format(FX_LPCWSTR lpszFormat, ... );
708
709     void                                        FormatV(FX_LPCWSTR lpszFormat, va_list argList);
710
711     void                                        MakeLower();
712
713     void                                        MakeUpper();
714
715     void                                        TrimRight();
716
717     void                                        TrimRight(FX_WCHAR chTarget);
718
719     void                                        TrimRight(FX_LPCWSTR lpszTargets);
720
721     void                                        TrimLeft();
722
723     void                                        TrimLeft(FX_WCHAR chTarget);
724
725     void                                        TrimLeft(FX_LPCWSTR lpszTargets);
726
727     void                                        Reserve(FX_STRSIZE len);
728
729     FX_LPWSTR                           GetBuffer(FX_STRSIZE len);
730
731     void                                        ReleaseBuffer(FX_STRSIZE len = -1);
732
733     int                                         GetInteger() const;
734
735     FX_FLOAT                            GetFloat() const;
736
737     FX_STRSIZE                          Find(FX_LPCWSTR lpszSub, FX_STRSIZE start = 0) const;
738
739     FX_STRSIZE                          Find(FX_WCHAR ch, FX_STRSIZE start = 0) const;
740
741     FX_STRSIZE                          Replace(FX_LPCWSTR lpszOld, FX_LPCWSTR lpszNew);
742
743     FX_STRSIZE                          Remove(FX_WCHAR ch);
744
745     CFX_ByteString                      UTF8Encode() const;
746
747     CFX_ByteString                      UTF16LE_Encode() const;
748
749     void                                        ConvertFrom(const CFX_ByteString& str, CFX_CharMap* pCharMap = NULL);
750 protected:
751     void                                        InitStr(FX_LPCWSTR ptr, int len);
752
753     CFX_StringDataW*            m_pData;
754     void                                        CopyBeforeWrite();
755     void                                        AllocBeforeWrite(FX_STRSIZE nLen);
756     void                                        ConcatInPlace(FX_STRSIZE nSrcLen, FX_LPCWSTR lpszSrcData);
757     void                                        ConcatCopy(FX_STRSIZE nSrc1Len, FX_LPCWSTR lpszSrc1Data, FX_STRSIZE nSrc2Len, FX_LPCWSTR lpszSrc2Data);
758     void                                        AssignCopy(FX_STRSIZE nSrcLen, FX_LPCWSTR lpszSrcData);
759     void                                        AllocCopy(CFX_WideString& dest, FX_STRSIZE nCopyLen, FX_STRSIZE nCopyIndex) const;
760 };
761 inline CFX_WideStringC::CFX_WideStringC(const CFX_WideString& src)
762 {
763     m_Ptr = src.c_str();
764     m_Length = src.GetLength();
765 }
766 inline CFX_WideStringC& CFX_WideStringC::operator = (const CFX_WideString& src)
767 {
768     m_Ptr = src.c_str();
769     m_Length = src.GetLength();
770     return *this;
771 }
772
773 inline CFX_WideString operator + (const CFX_WideStringC& str1, const CFX_WideStringC& str2)
774 {
775     return CFX_WideString(str1, str2);
776 }
777 inline CFX_WideString operator + (const CFX_WideStringC& str1, FX_LPCWSTR str2)
778 {
779     return CFX_WideString(str1, str2);
780 }
781 inline CFX_WideString operator + (FX_LPCWSTR str1, const CFX_WideStringC& str2)
782 {
783     return CFX_WideString(str1, str2);
784 }
785 inline CFX_WideString operator + (const CFX_WideStringC& str1, FX_WCHAR ch)
786 {
787     return CFX_WideString(str1, CFX_WideStringC(ch));
788 }
789 inline CFX_WideString operator + (FX_WCHAR ch, const CFX_WideStringC& str2)
790 {
791     return CFX_WideString(ch, str2);
792 }
793 inline CFX_WideString operator + (const CFX_WideString& str1, const CFX_WideString& str2)
794 {
795     return CFX_WideString(str1, str2);
796 }
797 inline CFX_WideString operator + (const CFX_WideString& str1, FX_WCHAR ch)
798 {
799     return CFX_WideString(str1, CFX_WideStringC(ch));
800 }
801 inline CFX_WideString operator + (FX_WCHAR ch, const CFX_WideString& str2)
802 {
803     return CFX_WideString(ch, str2);
804 }
805 inline CFX_WideString operator + (const CFX_WideString& str1, FX_LPCWSTR str2)
806 {
807     return CFX_WideString(str1, str2);
808 }
809 inline CFX_WideString operator + (FX_LPCWSTR str1, const CFX_WideString& str2)
810 {
811     return CFX_WideString(str1, str2);
812 }
813 inline CFX_WideString operator + (const CFX_WideString& str1, const CFX_WideStringC& str2)
814 {
815     return CFX_WideString(str1, str2);
816 }
817 inline CFX_WideString operator + (const CFX_WideStringC& str1, const CFX_WideString& str2)
818 {
819     return CFX_WideString(str1, str2);
820 }
821
822 bool operator==(const CFX_WideString& s1, const CFX_WideString& s2);
823 bool operator==(const CFX_WideString& s1, const CFX_WideStringC& s2);
824 bool operator==(const CFX_WideStringC& s1, const CFX_WideString& s2);
825 bool operator== (const CFX_WideString& s1, FX_LPCWSTR s2);
826 bool operator==(FX_LPCWSTR s1, const CFX_WideString& s2);
827 bool operator!=(const CFX_WideString& s1, const CFX_WideString& s2);
828 bool operator!=(const CFX_WideString& s1, const CFX_WideStringC& s2);
829 bool operator!=(const CFX_WideStringC& s1, const CFX_WideString& s2);
830 bool operator!= (const CFX_WideString& s1, FX_LPCWSTR s2);
831 bool operator!=(FX_LPCWSTR s1, const CFX_WideString& s2);
832 FX_FLOAT FX_atof(FX_BSTR str);
833 void FX_atonum(FX_BSTR str, FX_BOOL& bInteger, void* pData);
834 FX_STRSIZE FX_ftoa(FX_FLOAT f, FX_LPSTR buf);
835 CFX_ByteString  FX_UTF8Encode(FX_LPCWSTR pwsStr, FX_STRSIZE len);
836 inline CFX_ByteString   FX_UTF8Encode(FX_WSTR wsStr)
837 {
838     return FX_UTF8Encode(wsStr.GetPtr(), wsStr.GetLength());
839 }
840 inline CFX_ByteString   FX_UTF8Encode(const CFX_WideString &wsStr)
841 {
842     return FX_UTF8Encode(wsStr.c_str(), wsStr.GetLength());
843 }
844 #endif