fx_string.h revision ee451cb395940862dad63c85adfe8f2fd55e864c
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_
9class CFX_ByteStringC;
10class CFX_ByteString;
11class CFX_WideStringC;
12class CFX_WideString;
13struct CFX_CharMap;
14class CFX_BinaryBuf;
15typedef int FX_STRSIZE;
16class CFX_ByteStringL;
17class CFX_WideStringL;
18class CFX_ByteStringC : public CFX_Object
19{
20public:
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    }
136protected:
137
138    FX_LPCBYTE		m_Ptr;
139
140    FX_STRSIZE		m_Length;
141private:
142
143    void*			operator new (size_t) throw()
144    {
145        return NULL;
146    }
147};
148typedef const CFX_ByteStringC& FX_BSTR;
149#define FX_BSTRC(str) CFX_ByteStringC(str, sizeof str-1)
150struct 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};
160class CFX_ByteString : public CFX_Object
161{
162public:
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);
340protected:
341
342    struct CFX_StringData*	m_pData;
343    void					AllocCopy(CFX_ByteString& dest, FX_STRSIZE nCopyLen, FX_STRSIZE nCopyIndex, FX_STRSIZE nExtraLen) 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};
350inline CFX_ByteStringC::CFX_ByteStringC(const CFX_ByteString& src)
351{
352    m_Ptr = (FX_LPCBYTE)src;
353    m_Length = src.GetLength();
354}
355inline 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
362inline CFX_ByteString operator + (FX_BSTR str1, FX_BSTR str2)
363{
364    return CFX_ByteString(str1, str2);
365}
366inline CFX_ByteString operator + (FX_BSTR str1, FX_LPCSTR str2)
367{
368    return CFX_ByteString(str1, str2);
369}
370inline CFX_ByteString operator + (FX_LPCSTR str1, FX_BSTR str2)
371{
372    return CFX_ByteString(str1, str2);
373}
374inline CFX_ByteString operator + (FX_BSTR str1, FX_CHAR ch)
375{
376    return CFX_ByteString(str1, CFX_ByteStringC(ch));
377}
378inline CFX_ByteString operator + (FX_CHAR ch, FX_BSTR str2)
379{
380    return CFX_ByteString(ch, str2);
381}
382inline CFX_ByteString operator + (const CFX_ByteString& str1, const CFX_ByteString& str2)
383{
384    return CFX_ByteString(str1, str2);
385}
386inline CFX_ByteString operator + (const CFX_ByteString& str1, FX_CHAR ch)
387{
388    return CFX_ByteString(str1, CFX_ByteStringC(ch));
389}
390inline CFX_ByteString operator + (FX_CHAR ch, const CFX_ByteString& str2)
391{
392    return CFX_ByteString(ch, str2);
393}
394inline CFX_ByteString operator + (const CFX_ByteString& str1, FX_LPCSTR str2)
395{
396    return CFX_ByteString(str1, str2);
397}
398inline CFX_ByteString operator + (FX_LPCSTR str1, const CFX_ByteString& str2)
399{
400    return CFX_ByteString(str1, str2);
401}
402inline CFX_ByteString operator + (const CFX_ByteString& str1, FX_BSTR str2)
403{
404    return CFX_ByteString(str1, str2);
405}
406inline CFX_ByteString operator + (FX_BSTR str1, const CFX_ByteString& str2)
407{
408    return CFX_ByteString(str1, str2);
409}
410class CFX_StringBufBase : public CFX_Object
411{
412public:
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    }
450protected:
451
452    FX_STRSIZE	m_Limit;
453
454    FX_STRSIZE	m_Size;
455};
456template<FX_STRSIZE limit>
457class CFX_StringBufTemplate : public CFX_StringBufBase
458{
459public:
460
461    CFX_StringBufTemplate() : CFX_StringBufBase(limit) {}
462
463    FX_CHAR		m_Buffer[limit];
464};
465typedef CFX_StringBufTemplate<256> CFX_StringBuf256;
466class CFX_WideStringC : public CFX_Object
467{
468public:
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    }
587protected:
588
589    FX_LPCWSTR		m_Ptr;
590
591    FX_STRSIZE		m_Length;
592private:
593
594    void*			operator new (size_t) throw()
595    {
596        return NULL;
597    }
598};
599typedef const CFX_WideStringC&	FX_WSTR;
600#define FX_WSTRC(wstr) CFX_WideStringC((FX_LPCWSTR)wstr, sizeof(wstr) / sizeof(FX_WCHAR) - 1)
601struct 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};
611class CFX_WideString : public CFX_Object
612{
613public:
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);
750protected:
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, FX_STRSIZE nExtraLen) const;
760};
761inline CFX_WideStringC::CFX_WideStringC(const CFX_WideString& src)
762{
763    m_Ptr = (FX_LPCWSTR)src;
764    m_Length = src.GetLength();
765}
766inline 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
773inline CFX_WideString operator + (const CFX_WideStringC& str1, const CFX_WideStringC& str2)
774{
775    return CFX_WideString(str1, str2);
776}
777inline CFX_WideString operator + (const CFX_WideStringC& str1, FX_LPCWSTR str2)
778{
779    return CFX_WideString(str1, str2);
780}
781inline CFX_WideString operator + (FX_LPCWSTR str1, const CFX_WideStringC& str2)
782{
783    return CFX_WideString(str1, str2);
784}
785inline CFX_WideString operator + (const CFX_WideStringC& str1, FX_WCHAR ch)
786{
787    return CFX_WideString(str1, CFX_WideStringC(ch));
788}
789inline CFX_WideString operator + (FX_WCHAR ch, const CFX_WideStringC& str2)
790{
791    return CFX_WideString(ch, str2);
792}
793inline CFX_WideString operator + (const CFX_WideString& str1, const CFX_WideString& str2)
794{
795    return CFX_WideString(str1, str2);
796}
797inline CFX_WideString operator + (const CFX_WideString& str1, FX_WCHAR ch)
798{
799    return CFX_WideString(str1, CFX_WideStringC(ch));
800}
801inline CFX_WideString operator + (FX_WCHAR ch, const CFX_WideString& str2)
802{
803    return CFX_WideString(ch, str2);
804}
805inline CFX_WideString operator + (const CFX_WideString& str1, FX_LPCWSTR str2)
806{
807    return CFX_WideString(str1, str2);
808}
809inline CFX_WideString operator + (FX_LPCWSTR str1, const CFX_WideString& str2)
810{
811    return CFX_WideString(str1, str2);
812}
813inline CFX_WideString operator + (const CFX_WideString& str1, const CFX_WideStringC& str2)
814{
815    return CFX_WideString(str1, str2);
816}
817inline CFX_WideString operator + (const CFX_WideStringC& str1, const CFX_WideString& str2)
818{
819    return CFX_WideString(str1, str2);
820}
821
822bool operator==(const CFX_WideString& s1, const CFX_WideString& s2);
823bool operator==(const CFX_WideString& s1, const CFX_WideStringC& s2);
824bool operator==(const CFX_WideStringC& s1, const CFX_WideString& s2);
825bool operator== (const CFX_WideString& s1, FX_LPCWSTR s2);
826bool operator==(FX_LPCWSTR s1, const CFX_WideString& s2);
827bool operator!=(const CFX_WideString& s1, const CFX_WideString& s2);
828bool operator!=(const CFX_WideString& s1, const CFX_WideStringC& s2);
829bool operator!=(const CFX_WideStringC& s1, const CFX_WideString& s2);
830bool operator!= (const CFX_WideString& s1, FX_LPCWSTR s2);
831bool operator!=(FX_LPCWSTR s1, const CFX_WideString& s2);
832FX_FLOAT FX_atof(FX_BSTR str);
833void FX_atonum(FX_BSTR str, FX_BOOL& bInteger, void* pData);
834FX_STRSIZE FX_ftoa(FX_FLOAT f, FX_LPSTR buf);
835CFX_ByteString	FX_UTF8Encode(FX_LPCWSTR pwsStr, FX_STRSIZE len);
836inline CFX_ByteString	FX_UTF8Encode(FX_WSTR wsStr)
837{
838    return FX_UTF8Encode(wsStr.GetPtr(), wsStr.GetLength());
839}
840inline CFX_ByteString	FX_UTF8Encode(const CFX_WideString &wsStr)
841{
842    return FX_UTF8Encode((FX_LPCWSTR)wsStr, wsStr.GetLength());
843}
844class CFX_ByteStringL : public CFX_ByteStringC
845{
846public:
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};
855class CFX_WideStringL : public CFX_WideStringC
856{
857public:
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};
869void	FX_UTF8Encode(FX_LPCWSTR pwsStr, FX_STRSIZE len, CFX_ByteStringL &utf8Str, IFX_Allocator* pAllocator = NULL);
870#endif
871