Home | History | Annotate | Download | only in crt
      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