Merge to XFA: Use stdint.h types throughout PDFium.
[pdfium.git] / xfa / src / fgas / src / crt / fx_encode.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 "../fgas_base.h"\r
8 #include "fx_codepage.h"\r
9 void FX_SwapByteOrder(FX_LPWSTR pStr, int32_t iLength)\r
10 {\r
11     FXSYS_assert(pStr != NULL);\r
12     if (iLength < 0) {\r
13         iLength = FXSYS_wcslen(pStr);\r
14     }\r
15     FX_WORD wch;\r
16     if (sizeof(FX_WCHAR) > 2) {\r
17         while (iLength -- > 0) {\r
18             wch = (FX_WORD) * pStr;\r
19             wch = (wch >> 8) | (wch << 8);\r
20             wch &= 0x00FF;\r
21             *pStr ++ = wch;\r
22         }\r
23     } else {\r
24         while (iLength -- > 0) {\r
25             wch = (FX_WORD) * pStr;\r
26             wch = (wch >> 8) | (wch << 8);\r
27             *pStr ++ = wch;\r
28         }\r
29     }\r
30 }\r
31 void FX_SwapByteOrderCopy(FX_LPCWSTR pSrc, FX_LPWSTR pDst, int32_t iLength)\r
32 {\r
33     FXSYS_assert(pSrc != NULL && pDst != NULL);\r
34     if (iLength < 0) {\r
35         iLength = FXSYS_wcslen(pSrc);\r
36     }\r
37     FX_WORD wch;\r
38     if (sizeof(FX_WCHAR) > 2) {\r
39         while (iLength -- > 0) {\r
40             wch = (FX_WORD) * pSrc ++;\r
41             wch = (wch >> 8) | (wch << 8);\r
42             wch &= 0x00FF;\r
43             *pDst ++ = wch;\r
44         }\r
45     } else {\r
46         while (iLength -- > 0) {\r
47             wch = (FX_WORD) * pSrc ++;\r
48             wch = (wch >> 8) | (wch << 8);\r
49             *pDst ++ = wch;\r
50         }\r
51     }\r
52 }\r
53 void FX_UTF16ToWChar(FX_LPVOID pBuffer, int32_t iLength)\r
54 {\r
55     FXSYS_assert(pBuffer != NULL && iLength > 0);\r
56     if (sizeof(FX_WCHAR) == 2) {\r
57         return;\r
58     }\r
59     FX_WORD *pSrc = (FX_WORD*)pBuffer;\r
60     FX_LPWSTR pDst = (FX_LPWSTR)pBuffer;\r
61     while (--iLength >= 0) {\r
62         pDst[iLength] = (FX_WCHAR)pSrc[iLength];\r
63     }\r
64 }\r
65 void FX_UTF16ToWCharCopy(const FX_WORD *pUTF16, FX_LPWSTR pWChar, int32_t iLength)\r
66 {\r
67     FXSYS_assert(pUTF16 != NULL && pWChar != NULL && iLength > 0);\r
68     if (sizeof(FX_WCHAR) == 2) {\r
69         FXSYS_memcpy(pWChar, pUTF16, iLength * sizeof(FX_WCHAR));\r
70     } else {\r
71         while (--iLength >= 0) {\r
72             pWChar[iLength] = (FX_WCHAR)pUTF16[iLength];\r
73         }\r
74     }\r
75 }\r
76 void FX_WCharToUTF16(FX_LPVOID pBuffer, int32_t iLength)\r
77 {\r
78     FXSYS_assert(pBuffer != NULL && iLength > 0);\r
79     if (sizeof(FX_WCHAR) == 2) {\r
80         return;\r
81     }\r
82     FX_LPCWSTR pSrc = (FX_LPCWSTR)pBuffer;\r
83     FX_WORD *pDst = (FX_WORD*)pBuffer;\r
84     while (--iLength >= 0) {\r
85         *pDst++ = (FX_WORD) * pSrc++;\r
86     }\r
87 }\r
88 void FX_WCharToUTF16Copy(FX_LPCWSTR pWChar, FX_WORD *pUTF16, int32_t iLength)\r
89 {\r
90     FXSYS_assert(pWChar != NULL && pUTF16 != NULL && iLength > 0);\r
91     if (sizeof(FX_WCHAR) == 2) {\r
92         FXSYS_memcpy(pUTF16, pWChar, iLength * sizeof(FX_WCHAR));\r
93     } else {\r
94         while (--iLength >= 0) {\r
95             *pUTF16++ = (FX_WORD) * pWChar++;\r
96         }\r
97     }\r
98 }\r
99 inline FX_DWORD FX_DWordFromBytes(FX_LPCBYTE pStr)\r
100 {\r
101     return FXBSTR_ID(pStr[3], pStr[2], pStr[1], pStr[0]);\r
102 }\r
103 inline FX_WORD FX_WordFromBytes(FX_LPCBYTE pStr)\r
104 {\r
105     return (pStr[1] << 8 | pStr[0]);\r
106 }\r
107 int32_t FX_DecodeString(FX_WORD wCodePage, FX_LPCSTR pSrc, int32_t *pSrcLen, FX_LPWSTR pDst, int32_t *pDstLen, FX_BOOL bErrBreak)\r
108 {\r
109     if (wCodePage == FX_CODEPAGE_UTF8) {\r
110         return FX_UTF8Decode(pSrc, pSrcLen, pDst, pDstLen);\r
111     }\r
112     return -1;\r
113 }\r
114 int32_t FX_UTF8Decode(FX_LPCSTR pSrc, int32_t *pSrcLen, FX_LPWSTR pDst, int32_t *pDstLen)\r
115 {\r
116     if (pSrcLen == NULL || pDstLen == NULL) {\r
117         return -1;\r
118     }\r
119     int32_t iSrcLen = *pSrcLen;\r
120     if (iSrcLen < 1) {\r
121         *pSrcLen = *pDstLen = 0;\r
122         return 1;\r
123     }\r
124     int32_t iDstLen = *pDstLen;\r
125     FX_BOOL bValidDst = (pDst != NULL && iDstLen > 0);\r
126     FX_DWORD dwCode = 0;\r
127     int32_t iPending = 0;\r
128     int32_t iSrcNum = 0, iDstNum = 0;\r
129     int32_t k = 0;\r
130     int32_t iIndex = 0;\r
131     k = 1;\r
132     while (iIndex < iSrcLen) {\r
133         uint8_t byte = (uint8_t) * (pSrc + iIndex);\r
134         if (byte < 0x80) {\r
135             iPending = 0;\r
136             k = 1;\r
137             iDstNum ++;\r
138             iSrcNum += k;\r
139             if (bValidDst) {\r
140                 *pDst ++ = byte;\r
141                 if (iDstNum >= iDstLen) {\r
142                     break;\r
143                 }\r
144             }\r
145         } else if (byte < 0xc0) {\r
146             if (iPending < 1) {\r
147                 break;\r
148             }\r
149             iPending--;\r
150             dwCode |= (byte & 0x3f) << (iPending * 6);\r
151             if (iPending == 0) {\r
152                 iDstNum ++;\r
153                 iSrcNum += k;\r
154                 if (bValidDst) {\r
155                     *pDst ++ = dwCode;\r
156                     if (iDstNum >= iDstLen) {\r
157                         break;\r
158                     }\r
159                 }\r
160             }\r
161         } else if (byte < 0xe0) {\r
162             iPending = 1;\r
163             k = 2;\r
164             dwCode = (byte & 0x1f) << 6;\r
165         } else if (byte < 0xf0) {\r
166             iPending = 2;\r
167             k = 3;\r
168             dwCode = (byte & 0x0f) << 12;\r
169         } else if (byte < 0xf8) {\r
170             iPending = 3;\r
171             k = 4;\r
172             dwCode = (byte & 0x07) << 18;\r
173         } else if (byte < 0xfc) {\r
174             iPending = 4;\r
175             k = 5;\r
176             dwCode = (byte & 0x03) << 24;\r
177         } else if (byte < 0xfe) {\r
178             iPending = 5;\r
179             k = 6;\r
180             dwCode = (byte & 0x01) << 30;\r
181         } else {\r
182             break;\r
183         }\r
184         iIndex++;\r
185     }\r
186     *pSrcLen = iSrcNum;\r
187     *pDstLen = iDstNum;\r
188     return 1;\r
189 }\r