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