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