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