Initial commit.
[pdfium.git] / core / src / fxcrt / fx_basic_wstring.cpp
1 // Copyright 2014 PDFium Authors. All rights reserved.\r
2 // Use of this source code is governed by a BSD-style license that can be\r
3 // found in the LICENSE file.\r
4  \r
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com\r
6 \r
7 #include "../../include/fxcrt/fx_basic.h"\r
8 static CFX_StringDataW* FX_AllocStringW(int nLen)\r
9 {\r
10     if (nLen == 0) {\r
11         return NULL;\r
12     }\r
13     CFX_StringDataW* pData = (CFX_StringDataW*)FX_Alloc(FX_BYTE, sizeof(long) * 3 + (nLen + 1) * sizeof(FX_WCHAR));\r
14     if (!pData) {\r
15         return NULL;\r
16     }\r
17     pData->m_nAllocLength = nLen;\r
18     pData->m_nDataLength = nLen;\r
19     pData->m_nRefs = 1;\r
20     pData->m_String[nLen] = 0;\r
21     return pData;\r
22 }\r
23 static void FX_ReleaseStringW(CFX_StringDataW* pData)\r
24 {\r
25     if (pData == NULL) {\r
26         return;\r
27     }\r
28     pData->m_nRefs --;\r
29     if (pData->m_nRefs <= 0) {\r
30         FX_Free(pData);\r
31     }\r
32 }\r
33 CFX_WideString::~CFX_WideString()\r
34 {\r
35     if (m_pData == NULL) {\r
36         return;\r
37     }\r
38     m_pData->m_nRefs --;\r
39     if (m_pData->m_nRefs < 1) {\r
40         FX_Free(m_pData);\r
41     }\r
42 }\r
43 void CFX_WideString::InitStr(FX_LPCWSTR lpsz, FX_STRSIZE nLen)\r
44 {\r
45     if (nLen < 0) {\r
46         nLen = lpsz ? (FX_STRSIZE)FXSYS_wcslen(lpsz) : 0;\r
47     }\r
48     if (nLen) {\r
49         m_pData = FX_AllocStringW(nLen);\r
50         if (!m_pData) {\r
51             return;\r
52         }\r
53         FXSYS_memcpy32(m_pData->m_String, lpsz, nLen * sizeof(FX_WCHAR));\r
54     } else {\r
55         m_pData = NULL;\r
56     }\r
57 }\r
58 CFX_WideString::CFX_WideString(const CFX_WideString& stringSrc)\r
59 {\r
60     if (stringSrc.m_pData == NULL) {\r
61         m_pData = NULL;\r
62         return;\r
63     }\r
64     if (stringSrc.m_pData->m_nRefs >= 0) {\r
65         m_pData = stringSrc.m_pData;\r
66         m_pData->m_nRefs ++;\r
67     } else {\r
68         m_pData = NULL;\r
69         *this = stringSrc;\r
70     }\r
71 }\r
72 CFX_WideString::CFX_WideString(FX_WCHAR ch)\r
73 {\r
74     m_pData = FX_AllocStringW(1);\r
75     if (m_pData) {\r
76         m_pData->m_String[0] = ch;\r
77     }\r
78 }\r
79 CFX_WideString::CFX_WideString(const CFX_WideStringC& str)\r
80 {\r
81     if (str.IsEmpty()) {\r
82         m_pData = NULL;\r
83         return;\r
84     }\r
85     m_pData = FX_AllocStringW(str.GetLength());\r
86     if (m_pData) {\r
87         FXSYS_memcpy32(m_pData->m_String, str.GetPtr(), str.GetLength()*sizeof(FX_WCHAR));\r
88     }\r
89 }\r
90 CFX_WideString::CFX_WideString(const CFX_WideStringC& str1, const CFX_WideStringC& str2)\r
91 {\r
92     m_pData = NULL;\r
93     int nNewLen = str1.GetLength() + str2.GetLength();\r
94     if (nNewLen == 0) {\r
95         return;\r
96     }\r
97     m_pData = FX_AllocStringW(nNewLen);\r
98     if (m_pData) {\r
99         FXSYS_memcpy32(m_pData->m_String, str1.GetPtr(), str1.GetLength()*sizeof(FX_WCHAR));\r
100         FXSYS_memcpy32(m_pData->m_String + str1.GetLength(), str2.GetPtr(), str2.GetLength()*sizeof(FX_WCHAR));\r
101     }\r
102 }\r
103 void CFX_WideString::ReleaseBuffer(FX_STRSIZE nNewLength)\r
104 {\r
105     if (m_pData == NULL) {\r
106         return;\r
107     }\r
108     CopyBeforeWrite();\r
109     if (nNewLength == -1) {\r
110         nNewLength = m_pData ? (FX_STRSIZE)FXSYS_wcslen(m_pData->m_String) : 0;\r
111     }\r
112     if (nNewLength == 0) {\r
113         Empty();\r
114         return;\r
115     }\r
116     FXSYS_assert(nNewLength <= m_pData->m_nAllocLength);\r
117     m_pData->m_nDataLength = nNewLength;\r
118     m_pData->m_String[nNewLength] = 0;\r
119 }\r
120 const CFX_WideString& CFX_WideString::operator=(FX_LPCWSTR lpsz)\r
121 {\r
122     if (lpsz == NULL || lpsz[0] == 0) {\r
123         Empty();\r
124     } else {\r
125         AssignCopy((FX_STRSIZE)FXSYS_wcslen(lpsz), lpsz);\r
126     }\r
127     return *this;\r
128 }\r
129 const CFX_WideString& CFX_WideString::operator=(const CFX_WideStringC& stringSrc)\r
130 {\r
131     if (stringSrc.IsEmpty()) {\r
132         Empty();\r
133     } else {\r
134         AssignCopy(stringSrc.GetLength(), stringSrc.GetPtr());\r
135     }\r
136     return *this;\r
137 }\r
138 const CFX_WideString& CFX_WideString::operator=(const CFX_WideString& stringSrc)\r
139 {\r
140     if (m_pData == stringSrc.m_pData) {\r
141         return *this;\r
142     }\r
143     if (stringSrc.IsEmpty()) {\r
144         Empty();\r
145     } else if ((m_pData && m_pData->m_nRefs < 0) ||\r
146                (stringSrc.m_pData && stringSrc.m_pData->m_nRefs < 0)) {\r
147         AssignCopy(stringSrc.m_pData->m_nDataLength, stringSrc.m_pData->m_String);\r
148     } else {\r
149         Empty();\r
150         m_pData = stringSrc.m_pData;\r
151         if (m_pData) {\r
152             m_pData->m_nRefs ++;\r
153         }\r
154     }\r
155     return *this;\r
156 }\r
157 const CFX_WideString& CFX_WideString::operator+=(FX_WCHAR ch)\r
158 {\r
159     ConcatInPlace(1, &ch);\r
160     return *this;\r
161 }\r
162 const CFX_WideString& CFX_WideString::operator+=(FX_LPCWSTR lpsz)\r
163 {\r
164     if (lpsz) {\r
165         ConcatInPlace((FX_STRSIZE)FXSYS_wcslen(lpsz), lpsz);\r
166     }\r
167     return *this;\r
168 }\r
169 const CFX_WideString& CFX_WideString::operator+=(const CFX_WideString& string)\r
170 {\r
171     if (string.m_pData == NULL) {\r
172         return *this;\r
173     }\r
174     ConcatInPlace(string.m_pData->m_nDataLength, string.m_pData->m_String);\r
175     return *this;\r
176 }\r
177 const CFX_WideString& CFX_WideString::operator+=(const CFX_WideStringC& string)\r
178 {\r
179     if (string.IsEmpty()) {\r
180         return *this;\r
181     }\r
182     ConcatInPlace(string.GetLength(), string.GetPtr());\r
183     return *this;\r
184 }\r
185 bool operator==(const CFX_WideString& s1, FX_LPCWSTR s2)\r
186 {\r
187     return s1.Equal(s2);\r
188 }\r
189 bool operator==(FX_LPCWSTR s1, const CFX_WideString& s2)\r
190 {\r
191     return s2.Equal(s1);\r
192 }\r
193 bool operator==(const CFX_WideString& s1, const CFX_WideString& s2)\r
194 {\r
195     return s1.Equal(s2);\r
196 }\r
197 bool operator==(const CFX_WideString& s1, const CFX_WideStringC& s2)\r
198 {\r
199     return s1.Equal(s2);\r
200 }\r
201 bool operator==(const CFX_WideStringC& s1, const CFX_WideString& s2)\r
202 {\r
203     return s2.Equal(s1);\r
204 }\r
205 bool operator != (const CFX_WideString& s1, FX_LPCWSTR s2)\r
206 {\r
207     return !s1.Equal(s2);\r
208 }\r
209 bool operator!=(const CFX_WideString& s1, const CFX_WideString& s2)\r
210 {\r
211     return !s1.Equal(s2);\r
212 }\r
213 bool operator!=(const CFX_WideString& s1, const CFX_WideStringC& s2)\r
214 {\r
215     return !s1.Equal(s2);\r
216 }\r
217 bool operator!=(const CFX_WideStringC& s1, const CFX_WideString& s2)\r
218 {\r
219     return !s2.Equal(s1);\r
220 }\r
221 bool CFX_WideString::Equal(const CFX_WideStringC& str) const\r
222 {\r
223     if (m_pData == NULL) {\r
224         return str.IsEmpty();\r
225     }\r
226     return str.GetLength() == m_pData->m_nDataLength &&\r
227            FXSYS_memcmp32(str.GetPtr(), m_pData->m_String, m_pData->m_nDataLength * sizeof(FX_WCHAR)) == 0;\r
228 }\r
229 void CFX_WideString::Empty()\r
230 {\r
231     if (m_pData == NULL) {\r
232         return;\r
233     }\r
234     if (m_pData->m_nRefs > 1) {\r
235         m_pData->m_nRefs --;\r
236     } else {\r
237         FX_Free(m_pData);\r
238     }\r
239     m_pData = NULL;\r
240 }\r
241 void CFX_WideString::ConcatInPlace(FX_STRSIZE nSrcLen, FX_LPCWSTR lpszSrcData)\r
242 {\r
243     if (nSrcLen == 0 || lpszSrcData == NULL) {\r
244         return;\r
245     }\r
246     if (m_pData == NULL) {\r
247         m_pData = FX_AllocStringW(nSrcLen);\r
248         if (m_pData) {\r
249             FXSYS_memcpy32(m_pData->m_String, lpszSrcData, nSrcLen * sizeof(FX_WCHAR));\r
250         }\r
251         return;\r
252     }\r
253     if (m_pData->m_nRefs > 1 || m_pData->m_nDataLength + nSrcLen > m_pData->m_nAllocLength) {\r
254         CFX_StringDataW* pOldData = m_pData;\r
255         ConcatCopy(m_pData->m_nDataLength, m_pData->m_String, nSrcLen, lpszSrcData);\r
256         FX_ReleaseStringW(pOldData);\r
257     } else {\r
258         FXSYS_memcpy32(m_pData->m_String + m_pData->m_nDataLength, lpszSrcData, nSrcLen * sizeof(FX_WCHAR));\r
259         m_pData->m_nDataLength += nSrcLen;\r
260         m_pData->m_String[m_pData->m_nDataLength] = 0;\r
261     }\r
262 }\r
263 void CFX_WideString::ConcatCopy(FX_STRSIZE nSrc1Len, FX_LPCWSTR lpszSrc1Data,\r
264                                 FX_STRSIZE nSrc2Len, FX_LPCWSTR lpszSrc2Data)\r
265 {\r
266     FX_STRSIZE nNewLen = nSrc1Len + nSrc2Len;\r
267     if (nNewLen == 0) {\r
268         return;\r
269     }\r
270     m_pData = FX_AllocStringW(nNewLen);\r
271     if (m_pData) {\r
272         FXSYS_memcpy32(m_pData->m_String, lpszSrc1Data, nSrc1Len * sizeof(FX_WCHAR));\r
273         FXSYS_memcpy32(m_pData->m_String + nSrc1Len, lpszSrc2Data, nSrc2Len * sizeof(FX_WCHAR));\r
274     }\r
275 }\r
276 void CFX_WideString::CopyBeforeWrite()\r
277 {\r
278     if (m_pData == NULL || m_pData->m_nRefs <= 1) {\r
279         return;\r
280     }\r
281     CFX_StringDataW* pData = m_pData;\r
282     m_pData->m_nRefs --;\r
283     FX_STRSIZE nDataLength = pData->m_nDataLength;\r
284     m_pData = FX_AllocStringW(nDataLength);\r
285     if (m_pData != NULL) {\r
286         FXSYS_memcpy32(m_pData->m_String, pData->m_String, (nDataLength + 1) * sizeof(FX_WCHAR));\r
287     }\r
288 }\r
289 void CFX_WideString::AllocBeforeWrite(FX_STRSIZE nLen)\r
290 {\r
291     if (m_pData && m_pData->m_nRefs <= 1 && m_pData->m_nAllocLength >= nLen) {\r
292         return;\r
293     }\r
294     Empty();\r
295     m_pData = FX_AllocStringW(nLen);\r
296 }\r
297 void CFX_WideString::AssignCopy(FX_STRSIZE nSrcLen, FX_LPCWSTR lpszSrcData)\r
298 {\r
299     AllocBeforeWrite(nSrcLen);\r
300     FXSYS_memcpy32(m_pData->m_String, lpszSrcData, nSrcLen * sizeof(FX_WCHAR));\r
301     m_pData->m_nDataLength = nSrcLen;\r
302     m_pData->m_String[nSrcLen] = 0;\r
303 }\r
304 int CFX_WideString::Compare(FX_LPCWSTR lpsz) const\r
305 {\r
306     if (m_pData == NULL) {\r
307         return (lpsz == NULL || lpsz[0] == 0) ? 0 : -1;\r
308     }\r
309     return FXSYS_wcscmp(m_pData->m_String, lpsz);\r
310 }\r
311 CFX_ByteString CFX_WideString::UTF8Encode() const\r
312 {\r
313     return FX_UTF8Encode(*this);\r
314 }\r
315 CFX_ByteString CFX_WideString::UTF16LE_Encode(FX_BOOL bTerminate) const\r
316 {\r
317     if (m_pData == NULL) {\r
318         return bTerminate ? CFX_ByteString(FX_BSTRC("\0\0")) : CFX_ByteString();\r
319     }\r
320     int len = m_pData->m_nDataLength;\r
321     CFX_ByteString result;\r
322     FX_LPSTR buffer = result.GetBuffer(len * 2 + (bTerminate ? 2 : 0));\r
323     for (int i = 0; i < len; i ++) {\r
324         buffer[i * 2] = m_pData->m_String[i] & 0xff;\r
325         buffer[i * 2 + 1] = m_pData->m_String[i] >> 8;\r
326     }\r
327     if (bTerminate) {\r
328         buffer[len * 2] = 0;\r
329         buffer[len * 2 + 1] = 0;\r
330         result.ReleaseBuffer(len * 2 + 2);\r
331     } else {\r
332         result.ReleaseBuffer(len * 2);\r
333     }\r
334     return result;\r
335 }\r
336 void CFX_WideString::ConvertFrom(const CFX_ByteString& str, CFX_CharMap* pCharMap)\r
337 {\r
338     if (pCharMap == NULL) {\r
339         pCharMap = CFX_CharMap::GetDefaultMapper();\r
340     }\r
341     *this = pCharMap->m_GetWideString(pCharMap, str);\r
342 }\r
343 void CFX_WideString::Reserve(FX_STRSIZE len)\r
344 {\r
345     GetBuffer(len);\r
346     ReleaseBuffer(GetLength());\r
347 }\r
348 FX_LPWSTR CFX_WideString::GetBuffer(FX_STRSIZE nMinBufLength)\r
349 {\r
350     if (m_pData == NULL && nMinBufLength == 0) {\r
351         return NULL;\r
352     }\r
353     if (m_pData && m_pData->m_nRefs <= 1 && m_pData->m_nAllocLength >= nMinBufLength) {\r
354         return m_pData->m_String;\r
355     }\r
356     if (m_pData == NULL) {\r
357         m_pData = FX_AllocStringW(nMinBufLength);\r
358         if (!m_pData) {\r
359             return NULL;\r
360         }\r
361         m_pData->m_nDataLength = 0;\r
362         m_pData->m_String[0] = 0;\r
363         return m_pData->m_String;\r
364     }\r
365     CFX_StringDataW* pOldData = m_pData;\r
366     FX_STRSIZE nOldLen = pOldData->m_nDataLength;\r
367     if (nMinBufLength < nOldLen) {\r
368         nMinBufLength = nOldLen;\r
369     }\r
370     m_pData = FX_AllocStringW(nMinBufLength);\r
371     if (!m_pData) {\r
372         return NULL;\r
373     }\r
374     FXSYS_memcpy32(m_pData->m_String, pOldData->m_String, (nOldLen + 1)*sizeof(FX_WCHAR));\r
375     m_pData->m_nDataLength = nOldLen;\r
376     pOldData->m_nRefs --;\r
377     if (pOldData->m_nRefs <= 0) {\r
378         FX_Free(pOldData);\r
379     }\r
380     return m_pData->m_String;\r
381 }\r
382 CFX_WideString CFX_WideString::FromLocal(const char* str, FX_STRSIZE len)\r
383 {\r
384     CFX_WideString result;\r
385     result.ConvertFrom(CFX_ByteString(str, len));\r
386     return result;\r
387 }\r
388 CFX_WideString CFX_WideString::FromUTF8(const char* str, FX_STRSIZE len)\r
389 {\r
390     if (!str) {\r
391         return CFX_WideString();\r
392     }\r
393     if (len < 0) {\r
394         len = 0;\r
395         while (str[len]) {\r
396             len ++;\r
397         }\r
398     }\r
399     CFX_UTF8Decoder decoder;\r
400     for (FX_STRSIZE i = 0; i < len; i ++) {\r
401         decoder.Input(str[i]);\r
402     }\r
403     return decoder.GetResult();\r
404 }\r
405 CFX_WideString CFX_WideString::FromUTF16LE(const unsigned short* wstr, FX_STRSIZE wlen)\r
406 {\r
407     if (!wstr || !wlen) {\r
408         return CFX_WideString();\r
409     }\r
410     if (wlen < 0) {\r
411         wlen = 0;\r
412         while (wstr[wlen]) {\r
413             wlen ++;\r
414         }\r
415     }\r
416     CFX_WideString result;\r
417     FX_WCHAR* buf = result.GetBuffer(wlen);\r
418     for (int i = 0; i < wlen; i ++) {\r
419         buf[i] = wstr[i];\r
420     }\r
421     result.ReleaseBuffer(wlen);\r
422     return result;\r
423 }\r
424 void CFX_WideString::AllocCopy(CFX_WideString& dest, FX_STRSIZE nCopyLen, FX_STRSIZE nCopyIndex,\r
425                                FX_STRSIZE nExtraLen) const\r
426 {\r
427     FX_STRSIZE nNewLen = nCopyLen + nExtraLen;\r
428     if (nNewLen == 0) {\r
429         return;\r
430     }\r
431     ASSERT(dest.m_pData == NULL);\r
432     dest.m_pData = FX_AllocStringW(nNewLen);\r
433     if (dest.m_pData) {\r
434         FXSYS_memcpy32(dest.m_pData->m_String, m_pData->m_String + nCopyIndex, nCopyLen * sizeof(FX_WCHAR));\r
435     }\r
436 }\r
437 CFX_WideString CFX_WideString::Left(FX_STRSIZE nCount) const\r
438 {\r
439     if (m_pData == NULL) {\r
440         return CFX_WideString();\r
441     }\r
442     if (nCount < 0) {\r
443         nCount = 0;\r
444     }\r
445     if (nCount >= m_pData->m_nDataLength) {\r
446         return *this;\r
447     }\r
448     CFX_WideString dest;\r
449     AllocCopy(dest, nCount, 0, 0);\r
450     return dest;\r
451 }\r
452 CFX_WideString CFX_WideString::Mid(FX_STRSIZE nFirst) const\r
453 {\r
454     return Mid(nFirst, m_pData->m_nDataLength - nFirst);\r
455 }\r
456 CFX_WideString CFX_WideString::Mid(FX_STRSIZE nFirst, FX_STRSIZE nCount) const\r
457 {\r
458     if (m_pData == NULL) {\r
459         return CFX_WideString();\r
460     }\r
461     if (nFirst < 0) {\r
462         nFirst = 0;\r
463     }\r
464     if (nCount < 0) {\r
465         nCount = 0;\r
466     }\r
467     if (nFirst + nCount > m_pData->m_nDataLength) {\r
468         nCount = m_pData->m_nDataLength - nFirst;\r
469     }\r
470     if (nFirst > m_pData->m_nDataLength) {\r
471         nCount = 0;\r
472     }\r
473     if (nFirst == 0 && nFirst + nCount == m_pData->m_nDataLength) {\r
474         return *this;\r
475     }\r
476     CFX_WideString dest;\r
477     AllocCopy(dest, nCount, nFirst, 0);\r
478     return dest;\r
479 }\r
480 CFX_WideString CFX_WideString::Right(FX_STRSIZE nCount) const\r
481 {\r
482     if (m_pData == NULL) {\r
483         return CFX_WideString();\r
484     }\r
485     if (nCount < 0) {\r
486         nCount = 0;\r
487     }\r
488     if (nCount >= m_pData->m_nDataLength) {\r
489         return *this;\r
490     }\r
491     CFX_WideString dest;\r
492     AllocCopy(dest, nCount, m_pData->m_nDataLength - nCount, 0);\r
493     return dest;\r
494 }\r
495 int CFX_WideString::CompareNoCase(FX_LPCWSTR lpsz) const\r
496 {\r
497     if (m_pData == NULL) {\r
498         return (lpsz == NULL || lpsz[0] == 0) ? 0 : -1;\r
499     }\r
500     return FXSYS_wcsicmp(m_pData->m_String, lpsz);\r
501 }\r
502 int CFX_WideString::Compare(const CFX_WideString& str) const\r
503 {\r
504     if (m_pData == NULL) {\r
505         if (str.m_pData == NULL) {\r
506             return 0;\r
507         }\r
508         return -1;\r
509     } else if (str.m_pData == NULL) {\r
510         return 1;\r
511     }\r
512     int this_len = m_pData->m_nDataLength;\r
513     int that_len = str.m_pData->m_nDataLength;\r
514     int min_len = this_len < that_len ? this_len : that_len;\r
515     for (int i = 0; i < min_len; i ++) {\r
516         if (m_pData->m_String[i] < str.m_pData->m_String[i]) {\r
517             return -1;\r
518         } else if (m_pData->m_String[i] > str.m_pData->m_String[i]) {\r
519             return 1;\r
520         }\r
521     }\r
522     if (this_len < that_len) {\r
523         return -1;\r
524     } else if (this_len > that_len) {\r
525         return 1;\r
526     }\r
527     return 0;\r
528 }\r
529 FX_LPWSTR CFX_WideString::LockBuffer()\r
530 {\r
531     if (m_pData == NULL) {\r
532         return NULL;\r
533     }\r
534     FX_LPWSTR lpsz = GetBuffer(0);\r
535     m_pData->m_nRefs = -1;\r
536     return lpsz;\r
537 }\r
538 void CFX_WideString::SetAt(FX_STRSIZE nIndex, FX_WCHAR ch)\r
539 {\r
540     if (m_pData == NULL) {\r
541         return;\r
542     }\r
543     ASSERT(nIndex >= 0);\r
544     ASSERT(nIndex < m_pData->m_nDataLength);\r
545     CopyBeforeWrite();\r
546     m_pData->m_String[nIndex] = ch;\r
547 }\r
548 void CFX_WideString::MakeLower()\r
549 {\r
550     if (m_pData == NULL) {\r
551         return;\r
552     }\r
553     CopyBeforeWrite();\r
554     if (GetLength() < 1) {\r
555         return;\r
556     }\r
557     FXSYS_wcslwr(m_pData->m_String);\r
558 }\r
559 void CFX_WideString::MakeUpper()\r
560 {\r
561     if (m_pData == NULL) {\r
562         return;\r
563     }\r
564     CopyBeforeWrite();\r
565     if (GetLength() < 1) {\r
566         return;\r
567     }\r
568     FXSYS_wcsupr(m_pData->m_String);\r
569 }\r
570 FX_STRSIZE CFX_WideString::Find(FX_LPCWSTR lpszSub, FX_STRSIZE nStart) const\r
571 {\r
572     FX_STRSIZE nLength = GetLength();\r
573     if (nLength < 1 || nStart > nLength) {\r
574         return -1;\r
575     }\r
576     FX_LPCWSTR lpsz = (FX_LPCWSTR)FXSYS_wcsstr(m_pData->m_String + nStart, lpszSub);\r
577     return (lpsz == NULL) ? -1 : (int)(lpsz - m_pData->m_String);\r
578 }\r
579 FX_STRSIZE CFX_WideString::Find(FX_WCHAR ch, FX_STRSIZE nStart) const\r
580 {\r
581     if (m_pData == NULL) {\r
582         return -1;\r
583     }\r
584     FX_STRSIZE nLength = m_pData->m_nDataLength;\r
585     if (nStart >= nLength) {\r
586         return -1;\r
587     }\r
588     FX_LPCWSTR lpsz = (FX_LPCWSTR)FXSYS_wcschr(m_pData->m_String + nStart, ch);\r
589     return (lpsz == NULL) ? -1 : (int)(lpsz - m_pData->m_String);\r
590 }\r
591 void CFX_WideString::TrimRight(FX_LPCWSTR lpszTargetList)\r
592 {\r
593     FXSYS_assert(lpszTargetList != NULL);\r
594     if (m_pData == NULL || *lpszTargetList == 0) {\r
595         return;\r
596     }\r
597     CopyBeforeWrite();\r
598     FX_STRSIZE len = GetLength();\r
599     if (len < 1) {\r
600         return;\r
601     }\r
602     FX_STRSIZE pos = len;\r
603     while (pos) {\r
604         if (FXSYS_wcschr(lpszTargetList, m_pData->m_String[pos - 1]) == NULL) {\r
605             break;\r
606         }\r
607         pos --;\r
608     }\r
609     if (pos < len) {\r
610         m_pData->m_String[pos] = 0;\r
611         m_pData->m_nDataLength = pos;\r
612     }\r
613 }\r
614 void CFX_WideString::TrimRight(FX_WCHAR chTarget)\r
615 {\r
616     FX_WCHAR str[2] = {chTarget, 0};\r
617     TrimRight(str);\r
618 }\r
619 void CFX_WideString::TrimRight()\r
620 {\r
621     TrimRight(L"\x09\x0a\x0b\x0c\x0d\x20");\r
622 }\r
623 void CFX_WideString::TrimLeft(FX_LPCWSTR lpszTargets)\r
624 {\r
625     FXSYS_assert(lpszTargets != NULL);\r
626     if (m_pData == NULL || *lpszTargets == 0) {\r
627         return;\r
628     }\r
629     CopyBeforeWrite();\r
630     if (GetLength() < 1) {\r
631         return;\r
632     }\r
633     FX_LPCWSTR lpsz = m_pData->m_String;\r
634     while (*lpsz != 0) {\r
635         if (FXSYS_wcschr(lpszTargets, *lpsz) == NULL) {\r
636             break;\r
637         }\r
638         lpsz ++;\r
639     }\r
640     if (lpsz != m_pData->m_String) {\r
641         int nDataLength = m_pData->m_nDataLength - (FX_STRSIZE)(lpsz - m_pData->m_String);\r
642         FXSYS_memmove32(m_pData->m_String, lpsz, (nDataLength + 1)*sizeof(FX_WCHAR));\r
643         m_pData->m_nDataLength = nDataLength;\r
644     }\r
645 }\r
646 void CFX_WideString::TrimLeft(FX_WCHAR chTarget)\r
647 {\r
648     FX_WCHAR str[2] = {chTarget, 0};\r
649     TrimLeft(str);\r
650 }\r
651 void CFX_WideString::TrimLeft()\r
652 {\r
653     TrimLeft(L"\x09\x0a\x0b\x0c\x0d\x20");\r
654 }\r
655 FX_STRSIZE CFX_WideString::Replace(FX_LPCWSTR lpszOld, FX_LPCWSTR lpszNew)\r
656 {\r
657     if (GetLength() < 1) {\r
658         return 0;\r
659     }\r
660     if (lpszOld == NULL) {\r
661         return 0;\r
662     }\r
663     FX_STRSIZE nSourceLen = (FX_STRSIZE)FXSYS_wcslen(lpszOld);\r
664     if (nSourceLen == 0) {\r
665         return 0;\r
666     }\r
667     FX_STRSIZE nReplacementLen = lpszNew ? (FX_STRSIZE)FXSYS_wcslen(lpszNew) : 0;\r
668     FX_STRSIZE nCount = 0;\r
669     FX_LPWSTR lpszStart = m_pData->m_String;\r
670     FX_LPWSTR lpszEnd = m_pData->m_String + m_pData->m_nDataLength;\r
671     FX_LPWSTR lpszTarget;\r
672     {\r
673         while ((lpszTarget = (FX_LPWSTR)FXSYS_wcsstr(lpszStart, lpszOld)) != NULL && lpszStart < lpszEnd) {\r
674             nCount++;\r
675             lpszStart = lpszTarget + nSourceLen;\r
676         }\r
677     }\r
678     if (nCount > 0) {\r
679         CopyBeforeWrite();\r
680         FX_STRSIZE nOldLength = m_pData->m_nDataLength;\r
681         FX_STRSIZE nNewLength =  nOldLength + (nReplacementLen - nSourceLen) * nCount;\r
682         if (m_pData->m_nAllocLength < nNewLength || m_pData->m_nRefs > 1) {\r
683             CFX_StringDataW* pOldData = m_pData;\r
684             FX_LPCWSTR pstr = m_pData->m_String;\r
685             m_pData = FX_AllocStringW(nNewLength);\r
686             if (!m_pData) {\r
687                 return 0;\r
688             }\r
689             FXSYS_memcpy32(m_pData->m_String, pstr, pOldData->m_nDataLength * sizeof(FX_WCHAR));\r
690             FX_ReleaseStringW(pOldData);\r
691         }\r
692         lpszStart = m_pData->m_String;\r
693         lpszEnd = m_pData->m_String + FX_MAX(m_pData->m_nDataLength, nNewLength);\r
694         {\r
695             while ((lpszTarget = (FX_LPWSTR)FXSYS_wcsstr(lpszStart, lpszOld)) != NULL && lpszStart < lpszEnd) {\r
696                 FX_STRSIZE nBalance = nOldLength - (FX_STRSIZE)(lpszTarget - m_pData->m_String + nSourceLen);\r
697                 FXSYS_memmove32(lpszTarget + nReplacementLen, lpszTarget + nSourceLen, nBalance * sizeof(FX_WCHAR));\r
698                 FXSYS_memcpy32(lpszTarget, lpszNew, nReplacementLen * sizeof(FX_WCHAR));\r
699                 lpszStart = lpszTarget + nReplacementLen;\r
700                 lpszStart[nBalance] = 0;\r
701                 nOldLength += (nReplacementLen - nSourceLen);\r
702             }\r
703         }\r
704         ASSERT(m_pData->m_String[nNewLength] == 0);\r
705         m_pData->m_nDataLength = nNewLength;\r
706     }\r
707     return nCount;\r
708 }\r
709 FX_STRSIZE CFX_WideString::Insert(FX_STRSIZE nIndex, FX_WCHAR ch)\r
710 {\r
711     CopyBeforeWrite();\r
712     if (nIndex < 0) {\r
713         nIndex = 0;\r
714     }\r
715     FX_STRSIZE nNewLength = GetLength();\r
716     if (nIndex > nNewLength) {\r
717         nIndex = nNewLength;\r
718     }\r
719     nNewLength++;\r
720     if (m_pData == NULL || m_pData->m_nAllocLength < nNewLength) {\r
721         CFX_StringDataW* pOldData = m_pData;\r
722         FX_LPCWSTR pstr = m_pData->m_String;\r
723         m_pData = FX_AllocStringW(nNewLength);\r
724         if (!m_pData) {\r
725             return 0;\r
726         }\r
727         if(pOldData != NULL) {\r
728             FXSYS_memmove32(m_pData->m_String, pstr, (pOldData->m_nDataLength + 1)*sizeof(FX_WCHAR));\r
729             FX_ReleaseStringW(pOldData);\r
730         } else {\r
731             m_pData->m_String[0] = 0;\r
732         }\r
733     }\r
734     FXSYS_memmove32(m_pData->m_String + nIndex + 1,\r
735                     m_pData->m_String + nIndex, (nNewLength - nIndex)*sizeof(FX_WCHAR));\r
736     m_pData->m_String[nIndex] = ch;\r
737     m_pData->m_nDataLength = nNewLength;\r
738     return nNewLength;\r
739 }\r
740 FX_STRSIZE CFX_WideString::Delete(FX_STRSIZE nIndex, FX_STRSIZE nCount)\r
741 {\r
742     if (GetLength() < 1) {\r
743         return 0;\r
744     }\r
745     if (nIndex < 0) {\r
746         nIndex = 0;\r
747     }\r
748     FX_STRSIZE nOldLength = m_pData->m_nDataLength;\r
749     if (nCount > 0 && nIndex < nOldLength) {\r
750         CopyBeforeWrite();\r
751         int nBytesToCopy = nOldLength - (nIndex + nCount) + 1;\r
752         FXSYS_memmove32(m_pData->m_String + nIndex,\r
753                         m_pData->m_String + nIndex + nCount, nBytesToCopy * sizeof(FX_WCHAR));\r
754         m_pData->m_nDataLength = nOldLength - nCount;\r
755     }\r
756     return m_pData->m_nDataLength;\r
757 }\r
758 FX_STRSIZE CFX_WideString::Remove(FX_WCHAR chRemove)\r
759 {\r
760     if (m_pData == NULL) {\r
761         return 0;\r
762     }\r
763     CopyBeforeWrite();\r
764     if (GetLength() < 1) {\r
765         return 0;\r
766     }\r
767     FX_LPWSTR pstrSource = m_pData->m_String;\r
768     FX_LPWSTR pstrDest = m_pData->m_String;\r
769     FX_LPWSTR pstrEnd = m_pData->m_String + m_pData->m_nDataLength;\r
770     while (pstrSource < pstrEnd) {\r
771         if (*pstrSource != chRemove) {\r
772             *pstrDest = *pstrSource;\r
773             pstrDest ++;\r
774         }\r
775         pstrSource ++;\r
776     }\r
777     *pstrDest = 0;\r
778     FX_STRSIZE nCount = (FX_STRSIZE)(pstrSource - pstrDest);\r
779     m_pData->m_nDataLength -= nCount;\r
780     return nCount;\r
781 }\r
782 #define FORCE_ANSI      0x10000\r
783 #define FORCE_UNICODE   0x20000\r
784 #define FORCE_INT64     0x40000\r
785 void CFX_WideString::FormatV(FX_LPCWSTR lpszFormat, va_list argList)\r
786 {\r
787     va_list argListSave;\r
788 #if defined(__ARMCC_VERSION) || (!defined(_MSC_VER) && (_FX_CPU_ == _FX_X64_ || _FX_CPU_ == _FX_IA64_ || _FX_CPU_ == _FX_ARM64_)) || defined(__native_client__)\r
789     va_copy(argListSave, argList);\r
790 #else\r
791     argListSave = argList;\r
792 #endif\r
793     int nMaxLen = 0;\r
794     for (FX_LPCWSTR lpsz = lpszFormat; *lpsz != 0; lpsz ++) {\r
795         if (*lpsz != '%' || *(lpsz = lpsz + 1) == '%') {\r
796             nMaxLen += (FX_STRSIZE)FXSYS_wcslen(lpsz);\r
797             continue;\r
798         }\r
799         int nItemLen = 0;\r
800         int nWidth = 0;\r
801         for (; *lpsz != 0; lpsz ++) {\r
802             if (*lpsz == '#') {\r
803                 nMaxLen += 2;\r
804             } else if (*lpsz == '*') {\r
805                 nWidth = va_arg(argList, int);\r
806             } else if (*lpsz == '-' || *lpsz == '+' || *lpsz == '0' ||\r
807                        *lpsz == ' ')\r
808                 ;\r
809             else {\r
810                 break;\r
811             }\r
812         }\r
813         if (nWidth == 0) {\r
814             nWidth = FXSYS_wtoi(lpsz);\r
815             for (; *lpsz != 0 && (*lpsz) <= '9' && (*lpsz) >= '0'; lpsz ++)\r
816                 ;\r
817         }\r
818         if (nWidth < 0 || nWidth > 128 * 1024) {\r
819             lpszFormat = (FX_LPCWSTR)L"Bad width";\r
820             nMaxLen = 10;\r
821             break;\r
822         }\r
823         int nPrecision = 0;\r
824         if (*lpsz == '.') {\r
825             lpsz ++;\r
826             if (*lpsz == '*') {\r
827                 nPrecision = va_arg(argList, int);\r
828                 lpsz ++;\r
829             } else {\r
830                 nPrecision = FXSYS_wtoi(lpsz);\r
831                 for (; *lpsz != 0 && (*lpsz) >= '0' && (*lpsz) <= '9'; lpsz ++)\r
832                     ;\r
833             }\r
834         }\r
835         if (nPrecision < 0 || nPrecision > 128 * 1024) {\r
836             lpszFormat = (FX_LPCWSTR)L"Bad precision";\r
837             nMaxLen = 14;\r
838             break;\r
839         }\r
840         int nModifier = 0;\r
841         if (*lpsz == L'I' && *(lpsz + 1) == L'6' && *(lpsz + 2) == L'4') {\r
842             lpsz += 3;\r
843             nModifier = FORCE_INT64;\r
844         } else {\r
845             switch (*lpsz) {\r
846                 case 'h':\r
847                     nModifier = FORCE_ANSI;\r
848                     lpsz ++;\r
849                     break;\r
850                 case 'l':\r
851                     nModifier = FORCE_UNICODE;\r
852                     lpsz ++;\r
853                     break;\r
854                 case 'F':\r
855                 case 'N':\r
856                 case 'L':\r
857                     lpsz ++;\r
858                     break;\r
859             }\r
860         }\r
861         switch (*lpsz | nModifier) {\r
862             case 'c':\r
863             case 'C':\r
864                 nItemLen = 2;\r
865                 va_arg(argList, int);\r
866                 break;\r
867             case 'c'|FORCE_ANSI:\r
868             case 'C'|FORCE_ANSI:\r
869                 nItemLen = 2;\r
870                 va_arg(argList, int);\r
871                 break;\r
872             case 'c'|FORCE_UNICODE:\r
873             case 'C'|FORCE_UNICODE:\r
874                 nItemLen = 2;\r
875                 va_arg(argList, int);\r
876                 break;\r
877             case 's': {\r
878                     FX_LPCWSTR pstrNextArg = va_arg(argList, FX_LPCWSTR);\r
879                     if (pstrNextArg == NULL) {\r
880                         nItemLen = 6;\r
881                     } else {\r
882                         nItemLen = (FX_STRSIZE)FXSYS_wcslen(pstrNextArg);\r
883                         if (nItemLen < 1) {\r
884                             nItemLen = 1;\r
885                         }\r
886                     }\r
887                 }\r
888                 break;\r
889             case 'S': {\r
890                     FX_LPCSTR pstrNextArg = va_arg(argList, FX_LPCSTR);\r
891                     if (pstrNextArg == NULL) {\r
892                         nItemLen = 6;\r
893                     } else {\r
894                         nItemLen = (FX_STRSIZE)FXSYS_strlen(pstrNextArg);\r
895                         if (nItemLen < 1) {\r
896                             nItemLen = 1;\r
897                         }\r
898                     }\r
899                 }\r
900                 break;\r
901             case 's'|FORCE_ANSI:\r
902             case 'S'|FORCE_ANSI: {\r
903                     FX_LPCSTR pstrNextArg = va_arg(argList, FX_LPCSTR);\r
904                     if (pstrNextArg == NULL) {\r
905                         nItemLen = 6;\r
906                     } else {\r
907                         nItemLen = (FX_STRSIZE)FXSYS_strlen(pstrNextArg);\r
908                         if (nItemLen < 1) {\r
909                             nItemLen = 1;\r
910                         }\r
911                     }\r
912                 }\r
913                 break;\r
914             case 's'|FORCE_UNICODE:\r
915             case 'S'|FORCE_UNICODE: {\r
916                     FX_LPWSTR pstrNextArg = va_arg(argList, FX_LPWSTR);\r
917                     if (pstrNextArg == NULL) {\r
918                         nItemLen = 6;\r
919                     } else {\r
920                         nItemLen = (FX_STRSIZE)FXSYS_wcslen(pstrNextArg);\r
921                         if (nItemLen < 1) {\r
922                             nItemLen = 1;\r
923                         }\r
924                     }\r
925                 }\r
926                 break;\r
927         }\r
928         if (nItemLen != 0) {\r
929             if (nPrecision != 0 && nItemLen > nPrecision) {\r
930                 nItemLen = nPrecision;\r
931             }\r
932             if (nItemLen < nWidth) {\r
933                 nItemLen = nWidth;\r
934             }\r
935         } else {\r
936             switch (*lpsz) {\r
937                 case 'd':\r
938                 case 'i':\r
939                 case 'u':\r
940                 case 'x':\r
941                 case 'X':\r
942                 case 'o':\r
943                     if (nModifier & FORCE_INT64) {\r
944                         va_arg(argList, FX_INT64);\r
945                     } else {\r
946                         va_arg(argList, int);\r
947                     }\r
948                     nItemLen = 32;\r
949                     if (nItemLen < nWidth + nPrecision) {\r
950                         nItemLen = nWidth + nPrecision;\r
951                     }\r
952                     break;\r
953                 case 'a':\r
954                 case 'A':\r
955                 case 'e':\r
956                 case 'E':\r
957                 case 'g':\r
958                 case 'G':\r
959                     va_arg(argList, double);\r
960                     nItemLen = 128;\r
961                     if (nItemLen < nWidth + nPrecision) {\r
962                         nItemLen = nWidth + nPrecision;\r
963                     }\r
964                     break;\r
965                 case 'f':\r
966                     if (nWidth + nPrecision > 100) {\r
967                         nItemLen = nPrecision + nWidth + 128;\r
968                     } else {\r
969                         double f;\r
970                         char pszTemp[256];\r
971                         f = va_arg(argList, double);\r
972                         FXSYS_snprintf(pszTemp, sizeof(pszTemp), "%*.*f", nWidth, nPrecision + 6, f );\r
973                         nItemLen = (FX_STRSIZE)FXSYS_strlen(pszTemp);\r
974                     }\r
975                     break;\r
976                 case 'p':\r
977                     va_arg(argList, void*);\r
978                     nItemLen = 32;\r
979                     if (nItemLen < nWidth + nPrecision) {\r
980                         nItemLen = nWidth + nPrecision;\r
981                     }\r
982                     break;\r
983                 case 'n':\r
984                     va_arg(argList, int*);\r
985                     break;\r
986             }\r
987         }\r
988         nMaxLen += nItemLen;\r
989     }\r
990     GetBuffer(nMaxLen);\r
991     if (m_pData) {\r
992         FXSYS_vswprintf((wchar_t*)m_pData->m_String, nMaxLen + 1, (const wchar_t*)lpszFormat, argListSave);\r
993         ReleaseBuffer();\r
994     }\r
995     va_end(argListSave);\r
996 }\r
997 void CFX_WideString::Format(FX_LPCWSTR lpszFormat, ...)\r
998 {\r
999     va_list argList;\r
1000     va_start(argList, lpszFormat);\r
1001     FormatV(lpszFormat, argList);\r
1002     va_end(argList);\r
1003 }\r
1004 FX_FLOAT FX_wtof(FX_LPCWSTR str, int len)\r
1005 {\r
1006     if (len == 0) {\r
1007         return 0.0;\r
1008     }\r
1009     int cc = 0;\r
1010     FX_BOOL bNegative = FALSE;\r
1011     if (str[0] == '+') {\r
1012         cc++;\r
1013     } else if (str[0] == '-') {\r
1014         bNegative = TRUE;\r
1015         cc++;\r
1016     }\r
1017     int integer = 0;\r
1018     while (cc < len) {\r
1019         if (str[cc] == '.') {\r
1020             break;\r
1021         }\r
1022         integer = integer * 10 + str[cc] - '0';\r
1023         cc ++;\r
1024     }\r
1025     FX_FLOAT fraction = 0;\r
1026     if (str[cc] == '.') {\r
1027         cc ++;\r
1028         FX_FLOAT scale = 0.1f;\r
1029         while (cc < len) {\r
1030             fraction += scale * (str[cc] - '0');\r
1031             scale *= 0.1f;\r
1032             cc ++;\r
1033         }\r
1034     }\r
1035     fraction += (FX_FLOAT)integer;\r
1036     return bNegative ? -fraction : fraction;\r
1037 }\r
1038 int CFX_WideString::GetInteger() const\r
1039 {\r
1040     if (m_pData == NULL) {\r
1041         return 0;\r
1042     }\r
1043     return FXSYS_wtoi(m_pData->m_String);\r
1044 }\r
1045 FX_FLOAT CFX_WideString::GetFloat() const\r
1046 {\r
1047     if (m_pData == NULL) {\r
1048         return 0.0;\r
1049     }\r
1050     return FX_wtof(m_pData->m_String, m_pData->m_nDataLength);\r
1051 }\r
1052 void CFX_WideStringL::Empty(IFX_Allocator* pAllocator)\r
1053 {\r
1054     if (m_Ptr) {\r
1055         FX_Allocator_Free(pAllocator, (FX_LPVOID)m_Ptr);\r
1056     }\r
1057     m_Ptr = NULL, m_Length = 0;\r
1058 }\r
1059 void CFX_WideStringL::Set(FX_WSTR src, IFX_Allocator* pAllocator)\r
1060 {\r
1061     Empty(pAllocator);\r
1062     if (src.GetPtr() != NULL && src.GetLength() > 0) {\r
1063         FX_LPWSTR str = FX_Allocator_Alloc(pAllocator, FX_WCHAR, src.GetLength() + 1);\r
1064         if (!str) {\r
1065             return;\r
1066         }\r
1067         FXSYS_memcpy32(str, src.GetPtr(), src.GetLength()*sizeof(FX_WCHAR));\r
1068         str[src.GetLength()] = '\0';\r
1069         *(FX_LPWSTR*)(&m_Ptr) = str;\r
1070         m_Length = src.GetLength();\r
1071     }\r
1072 }\r
1073 int CFX_WideStringL::GetInteger() const\r
1074 {\r
1075     if (!m_Ptr) {\r
1076         return 0;\r
1077     }\r
1078     return FXSYS_wtoi(m_Ptr);\r
1079 }\r
1080 FX_FLOAT CFX_WideStringL::GetFloat() const\r
1081 {\r
1082     if (!m_Ptr) {\r
1083         return 0.0f;\r
1084     }\r
1085     return FX_wtof(m_Ptr, m_Length);\r
1086 }\r
1087 void CFX_WideStringL::TrimRight(FX_LPCWSTR lpszTargets)\r
1088 {\r
1089     if (!lpszTargets || *lpszTargets == 0 || !m_Ptr || m_Length < 1) {\r
1090         return;\r
1091     }\r
1092     FX_STRSIZE pos = m_Length;\r
1093     while (pos) {\r
1094         if (FXSYS_wcschr(lpszTargets, m_Ptr[pos - 1]) == NULL) {\r
1095             break;\r
1096         }\r
1097         pos --;\r
1098     }\r
1099     if (pos < m_Length) {\r
1100         (*(FX_LPWSTR*)(&m_Ptr))[pos] = 0;\r
1101         m_Length = pos;\r
1102     }\r
1103 }\r
1104 static CFX_ByteString _DefMap_GetByteString(CFX_CharMap* pCharMap, const CFX_WideString& widestr)\r
1105 {\r
1106     int src_len = widestr.GetLength();\r
1107     int codepage = pCharMap->m_GetCodePage ? pCharMap->m_GetCodePage() : 0;\r
1108     int dest_len = FXSYS_WideCharToMultiByte(codepage, 0, widestr, src_len, NULL, 0, NULL, NULL);\r
1109     if (dest_len == 0) {\r
1110         return CFX_ByteString();\r
1111     }\r
1112     CFX_ByteString bytestr;\r
1113     FX_LPSTR dest_buf = bytestr.GetBuffer(dest_len);\r
1114     FXSYS_WideCharToMultiByte(codepage, 0, widestr, src_len, dest_buf, dest_len, NULL, NULL);\r
1115     bytestr.ReleaseBuffer(dest_len);\r
1116     return bytestr;\r
1117 }\r
1118 static CFX_WideString _DefMap_GetWideString(CFX_CharMap* pCharMap, const CFX_ByteString& bytestr)\r
1119 {\r
1120     int src_len = bytestr.GetLength();\r
1121     int codepage = pCharMap->m_GetCodePage ? pCharMap->m_GetCodePage() : 0;\r
1122     int dest_len = FXSYS_MultiByteToWideChar(codepage, 0, bytestr, src_len, NULL, 0);\r
1123     if (dest_len == 0) {\r
1124         return CFX_WideString();\r
1125     }\r
1126     CFX_WideString widestr;\r
1127     FX_LPWSTR dest_buf = widestr.GetBuffer(dest_len);\r
1128     FXSYS_MultiByteToWideChar(codepage, 0, bytestr, src_len, dest_buf, dest_len);\r
1129     widestr.ReleaseBuffer(dest_len);\r
1130     return widestr;\r
1131 }\r
1132 static int _DefMap_GetGBKCodePage()\r
1133 {\r
1134     return 936;\r
1135 }\r
1136 static int _DefMap_GetUHCCodePage()\r
1137 {\r
1138     return 949;\r
1139 }\r
1140 static int _DefMap_GetJISCodePage()\r
1141 {\r
1142     return 932;\r
1143 }\r
1144 static int _DefMap_GetBig5CodePage()\r
1145 {\r
1146     return 950;\r
1147 }\r
1148 static const CFX_CharMap g_DefaultMapper = {&_DefMap_GetWideString, &_DefMap_GetByteString, NULL};\r
1149 static const CFX_CharMap g_DefaultGBKMapper = {&_DefMap_GetWideString, &_DefMap_GetByteString, &_DefMap_GetGBKCodePage};\r
1150 static const CFX_CharMap g_DefaultJISMapper = {&_DefMap_GetWideString, &_DefMap_GetByteString, &_DefMap_GetJISCodePage};\r
1151 static const CFX_CharMap g_DefaultUHCMapper = {&_DefMap_GetWideString, &_DefMap_GetByteString, &_DefMap_GetUHCCodePage};\r
1152 static const CFX_CharMap g_DefaultBig5Mapper = {&_DefMap_GetWideString, &_DefMap_GetByteString, &_DefMap_GetBig5CodePage};\r
1153 CFX_CharMap* CFX_CharMap::GetDefaultMapper(FX_INT32 codepage)\r
1154 {\r
1155     switch (codepage) {\r
1156         case 0:\r
1157             return (CFX_CharMap*)&g_DefaultMapper;\r
1158         case 932:\r
1159             return (CFX_CharMap*)&g_DefaultJISMapper;\r
1160         case 936:\r
1161             return (CFX_CharMap*)&g_DefaultGBKMapper;\r
1162         case 949:\r
1163             return (CFX_CharMap*)&g_DefaultUHCMapper;\r
1164         case 950:\r
1165             return (CFX_CharMap*)&g_DefaultBig5Mapper;\r
1166     }\r
1167     return NULL;\r
1168 }\r