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