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