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" 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 } 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 } 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 } 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 } 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 } 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 } 98 inline FX_DWORD FX_DWordFromBytes(const uint8_t* pStr) { 99 return FXBSTR_ID(pStr[3], pStr[2], pStr[1], pStr[0]); 100 } 101 inline FX_WORD FX_WordFromBytes(const uint8_t* pStr) { 102 return (pStr[1] << 8 | pStr[0]); 103 } 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 } 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