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