7e02101def420ccc392b74835ee1c1c6f43847e0
[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((FX_LPCWSTR)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 = -1);
638
639     static CFX_WideString       FromUTF16LE(const unsigned short* str, FX_STRSIZE len = -1);
640
641     operator FX_LPCWSTR() const
642     {
643         return m_pData ? m_pData->m_String : (FX_WCHAR*)L"";
644     }
645
646     void                                        Empty();
647
648
649     FX_BOOL                                     IsEmpty() const
650     {
651         return !GetLength();
652     }
653
654     FX_STRSIZE                          GetLength() const
655     {
656         return m_pData ? m_pData->m_nDataLength : 0;
657     }
658
659     const CFX_WideString&       operator = (FX_LPCWSTR str);
660
661     const CFX_WideString&       operator =(const CFX_WideString& stringSrc);
662
663     const CFX_WideString&       operator =(const CFX_WideStringC& stringSrc);
664
665     const CFX_WideString&       operator += (FX_LPCWSTR str);
666
667     const CFX_WideString&       operator += (FX_WCHAR ch);
668
669     const CFX_WideString&       operator += (const CFX_WideString& str);
670
671     const CFX_WideString&       operator += (const CFX_WideStringC& str);
672
673     FX_WCHAR                            GetAt(FX_STRSIZE nIndex) const
674     {
675         return m_pData ? m_pData->m_String[nIndex] : 0;
676     }
677
678     FX_WCHAR                            operator[](FX_STRSIZE nIndex) const
679     {
680         return m_pData ? m_pData->m_String[nIndex] : 0;
681     }
682
683     void                                        SetAt(FX_STRSIZE nIndex, FX_WCHAR ch);
684
685     int                                         Compare(FX_LPCWSTR str) const;
686
687     int                                         Compare(const CFX_WideString& str) const;
688
689     int                                         CompareNoCase(FX_LPCWSTR str) const;
690
691     bool                                        Equal(const CFX_WideStringC& str) const;
692
693     CFX_WideString                      Mid(FX_STRSIZE first) const;
694
695     CFX_WideString                      Mid(FX_STRSIZE first, FX_STRSIZE count) const;
696
697     CFX_WideString                      Left(FX_STRSIZE count) const;
698
699     CFX_WideString                      Right(FX_STRSIZE count) const;
700
701     FX_STRSIZE                          Insert(FX_STRSIZE index, FX_WCHAR ch);
702
703     FX_STRSIZE                          Delete(FX_STRSIZE index, FX_STRSIZE count = 1);
704
705     void                                        Format(FX_LPCWSTR lpszFormat, ... );
706
707     void                                        FormatV(FX_LPCWSTR lpszFormat, va_list argList);
708
709     void                                        MakeLower();
710
711     void                                        MakeUpper();
712
713     void                                        TrimRight();
714
715     void                                        TrimRight(FX_WCHAR chTarget);
716
717     void                                        TrimRight(FX_LPCWSTR lpszTargets);
718
719     void                                        TrimLeft();
720
721     void                                        TrimLeft(FX_WCHAR chTarget);
722
723     void                                        TrimLeft(FX_LPCWSTR lpszTargets);
724
725     void                                        Reserve(FX_STRSIZE len);
726
727     FX_LPWSTR                           GetBuffer(FX_STRSIZE len);
728
729     FX_LPWSTR                           LockBuffer();
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(FX_BOOL bTerminate = TRUE) 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 = (FX_LPCWSTR)src;
764     m_Length = src.GetLength();
765 }
766 inline CFX_WideStringC& CFX_WideStringC::operator = (const CFX_WideString& src)
767 {
768     m_Ptr = (FX_LPCWSTR)src;
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((FX_LPCWSTR)wsStr, wsStr.GetLength());
843 }
844 class CFX_ByteStringL : public CFX_ByteStringC
845 {
846 public:
847     CFX_ByteStringL() : CFX_ByteStringC() {}
848     ~CFX_ByteStringL() {}
849
850     void                Empty(IFX_Allocator* pAllocator);
851     FX_LPSTR    AllocBuffer(FX_STRSIZE length, IFX_Allocator* pAllocator);
852
853     void                Set(FX_BSTR src, IFX_Allocator* pAllocator);
854 };
855 class CFX_WideStringL : public CFX_WideStringC
856 {
857 public:
858     CFX_WideStringL() : CFX_WideStringC() {}
859     ~CFX_WideStringL() {}
860
861     void                Empty(IFX_Allocator* pAllocator);
862     void                Set(FX_WSTR src, IFX_Allocator* pAllocator);
863
864     int                 GetInteger() const;
865     FX_FLOAT    GetFloat() const;
866
867     void                TrimRight(FX_LPCWSTR lpszTargets);
868 };
869 void    FX_UTF8Encode(FX_LPCWSTR pwsStr, FX_STRSIZE len, CFX_ByteStringL &utf8Str, IFX_Allocator* pAllocator = NULL);
870 #endif