LCOV - code coverage report
Current view: top level - sal/textenc - convertbig5hkscs.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 161 238 67.6 %
Date: 2014-11-03 Functions: 4 5 80.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include "sal/config.h"
      21             : 
      22             : #include <cassert>
      23             : 
      24             : #include "rtl/textcvt.h"
      25             : #include "sal/types.h"
      26             : 
      27             : #include "context.hxx"
      28             : #include "convertbig5hkscs.hxx"
      29             : #include "converter.hxx"
      30             : #include "tenchelp.hxx"
      31             : #include "unichars.hxx"
      32             : 
      33             : namespace {
      34             : 
      35             : struct ImplBig5HkscsToUnicodeContext
      36             : {
      37             :     sal_Int32 m_nRow; // 0--255; 0 means none
      38             : };
      39             : 
      40             : }
      41             : 
      42          20 : void * ImplCreateBig5HkscsToUnicodeContext()
      43             : {
      44             :     ImplBig5HkscsToUnicodeContext * pContext =
      45          20 :         new ImplBig5HkscsToUnicodeContext;
      46          20 :     pContext->m_nRow = 0;
      47          20 :     return pContext;
      48             : }
      49             : 
      50           0 : void ImplResetBig5HkscsToUnicodeContext(void * pContext)
      51             : {
      52           0 :     if (pContext)
      53           0 :         static_cast< ImplBig5HkscsToUnicodeContext * >(pContext)->m_nRow = 0;
      54           0 : }
      55             : 
      56          20 : void ImplDestroyBig5HkscsToUnicodeContext(void * pContext)
      57             : {
      58          20 :     delete static_cast< ImplBig5HkscsToUnicodeContext * >(pContext);
      59          20 : }
      60             : 
      61         232 : sal_Size ImplConvertBig5HkscsToUnicode(void const * pData,
      62             :                                        void * pContext,
      63             :                                        char const * pSrcBuf,
      64             :                                        sal_Size nSrcBytes,
      65             :                                        sal_Unicode * pDestBuf,
      66             :                                        sal_Size nDestChars,
      67             :                                        sal_uInt32 nFlags,
      68             :                                        sal_uInt32 * pInfo,
      69             :                                        sal_Size * pSrcCvtBytes)
      70             : {
      71             :     sal_uInt16 const * pBig5Hkscs2001Data
      72             :         = static_cast< ImplBig5HkscsConverterData const * >(pData)->
      73         232 :               m_pBig5Hkscs2001ToUnicodeData;
      74             :     sal_Int32 const * pBig5Hkscs2001RowOffsets
      75             :         = static_cast< ImplBig5HkscsConverterData const * >(pData)->
      76         232 :               m_pBig5Hkscs2001ToUnicodeRowOffsets;
      77             :     ImplDBCSToUniLeadTab const * pBig5Data
      78             :         = static_cast< ImplBig5HkscsConverterData const * >(pData)->
      79         232 :               m_pBig5ToUnicodeData;
      80         232 :     sal_Int32 nRow = 0;
      81         232 :     sal_uInt32 nInfo = 0;
      82         232 :     sal_Size nConverted = 0;
      83         232 :     sal_Unicode * pDestBufPtr = pDestBuf;
      84         232 :     sal_Unicode * pDestBufEnd = pDestBuf + nDestChars;
      85             : 
      86         232 :     if (pContext)
      87         126 :         nRow = static_cast< ImplBig5HkscsToUnicodeContext * >(pContext)->m_nRow;
      88             : 
      89         596 :     for (; nConverted < nSrcBytes; ++nConverted)
      90             :     {
      91         364 :         bool bUndefined = true;
      92         364 :         sal_uInt32 nChar = *(unsigned char const *) pSrcBuf++;
      93         364 :         if (nRow == 0)
      94         226 :             if (nChar < 0x80)
      95          42 :                 if (pDestBufPtr != pDestBufEnd)
      96          42 :                     *pDestBufPtr++ = (sal_Unicode) nChar;
      97             :                 else
      98           0 :                     goto no_output;
      99         184 :             else if (nChar >= 0x81 && nChar <= 0xFE)
     100         184 :                 nRow = nChar;
     101             :             else
     102             :             {
     103           0 :                 bUndefined = false;
     104           0 :                 goto bad_input;
     105             :             }
     106             :         else
     107         138 :             if ((nChar >= 0x40 && nChar <= 0x7E)
     108          90 :                 || (nChar >= 0xA1 && nChar <= 0xFE))
     109             :             {
     110         138 :                 sal_uInt32 nUnicode = 0xFFFF;
     111         138 :                 sal_Int32 nOffset = pBig5Hkscs2001RowOffsets[nRow];
     112         138 :                 sal_uInt32 nFirst=0;
     113         138 :                 sal_uInt32 nLast=0;
     114         138 :                 if (nOffset != -1)
     115             :                 {
     116         114 :                     sal_uInt32 nFirstLast = pBig5Hkscs2001Data[nOffset++];
     117         114 :                     nFirst = nFirstLast & 0xFF;
     118         114 :                     nLast = nFirstLast >> 8;
     119         114 :                     if (nChar >= nFirst && nChar <= nLast)
     120             :                         nUnicode
     121         108 :                             = pBig5Hkscs2001Data[nOffset + (nChar - nFirst)];
     122             :                 }
     123         138 :                 if (nUnicode == 0xFFFF)
     124             :                 {
     125          30 :                     sal_uInt32 n = pBig5Data[nRow].mnTrailStart;
     126          30 :                     if (nChar >= n && nChar <= pBig5Data[nRow].mnTrailEnd)
     127             :                     {
     128          18 :                         nUnicode = pBig5Data[nRow].mpToUniTrailTab[nChar - n];
     129          18 :                         if (nUnicode == 0)
     130           0 :                             nUnicode = 0xFFFF;
     131             :                         assert(!ImplIsHighSurrogate(nUnicode));
     132             :                     }
     133             :                 }
     134         138 :                 if (nUnicode == 0xFFFF)
     135             :                 {
     136             :                     ImplDBCSEUDCData const * p
     137             :                         = static_cast< ImplBig5HkscsConverterData const * >(pData)->
     138          12 :                               m_pEudcData;
     139             :                     sal_uInt32 nCount
     140             :                         = static_cast< ImplBig5HkscsConverterData const * >(pData)->
     141          12 :                               m_nEudcCount;
     142             :                     sal_uInt32 i;
     143          36 :                     for (i = 0; i < nCount; ++i)
     144             :                     {
     145          36 :                         if (nRow >= p->mnLeadStart && nRow <= p->mnLeadEnd)
     146             :                         {
     147          12 :                             if (nChar < p->mnTrail1Start)
     148           0 :                                 break;
     149          12 :                             if (nChar <= p->mnTrail1End)
     150             :                             {
     151             :                                 nUnicode
     152             :                                     = p->mnUniStart
     153          12 :                                           + (nRow - p->mnLeadStart)
     154           6 :                                                 * p->mnTrailRangeCount
     155           6 :                                           + (nChar - p->mnTrail1Start);
     156           6 :                                 break;
     157             :                             }
     158           6 :                             if (p->mnTrailCount < 2
     159           6 :                                 || nChar < p->mnTrail2Start)
     160             :                                 break;
     161           6 :                             if (nChar <= p->mnTrail2End)
     162             :                             {
     163             :                                 nUnicode
     164             :                                     = p->mnUniStart
     165          12 :                                           + (nRow - p->mnLeadStart)
     166           6 :                                                 * p->mnTrailRangeCount
     167           6 :                                           + (nChar - p->mnTrail2Start)
     168           6 :                                           + (p->mnTrail1End - p->mnTrail1Start
     169           6 :                                                  + 1);
     170           6 :                                 break;
     171             :                             }
     172           0 :                             if (p->mnTrailCount < 3
     173           0 :                                 || nChar < p->mnTrail3Start)
     174             :                                 break;
     175           0 :                             if (nChar <= p->mnTrail3End)
     176             :                             {
     177             :                                 nUnicode
     178             :                                     = p->mnUniStart
     179           0 :                                           + (nRow - p->mnLeadStart)
     180           0 :                                                 * p->mnTrailRangeCount
     181           0 :                                           + (nChar - p->mnTrail3Start)
     182           0 :                                           + (p->mnTrail1End - p->mnTrail1Start
     183             :                                                  + 1)
     184           0 :                                           + (p->mnTrail2End - p->mnTrail2Start
     185           0 :                                                  + 1);
     186           0 :                                 break;
     187             :                             }
     188           0 :                             break;
     189             :                         }
     190          24 :                         ++p;
     191             :                     }
     192             :                     assert(!ImplIsHighSurrogate(nUnicode));
     193             :                 }
     194         138 :                 if (nUnicode == 0xFFFF)
     195           0 :                     goto bad_input;
     196         138 :                 if (ImplIsHighSurrogate(nUnicode))
     197           0 :                     if (pDestBufEnd - pDestBufPtr >= 2)
     198             :                     {
     199           0 :                         nOffset += nLast - nFirst + 1;
     200           0 :                         nFirst = pBig5Hkscs2001Data[nOffset++];
     201           0 :                         *pDestBufPtr++ = (sal_Unicode) nUnicode;
     202             :                         *pDestBufPtr++
     203             :                             = (sal_Unicode) pBig5Hkscs2001Data[
     204           0 :                                                 nOffset + (nChar - nFirst)];
     205             :                     }
     206             :                     else
     207           0 :                         goto no_output;
     208             :                 else
     209         138 :                     if (pDestBufPtr != pDestBufEnd)
     210         138 :                         *pDestBufPtr++ = (sal_Unicode) nUnicode;
     211             :                     else
     212           0 :                         goto no_output;
     213         138 :                 nRow = 0;
     214             :             }
     215             :             else
     216             :             {
     217           0 :                 bUndefined = false;
     218           0 :                 goto bad_input;
     219             :             }
     220         364 :         continue;
     221             : 
     222             :     bad_input:
     223           0 :         switch (sal::detail::textenc::handleBadInputTextToUnicodeConversion(
     224             :                     bUndefined, true, 0, nFlags, &pDestBufPtr, pDestBufEnd,
     225           0 :                     &nInfo))
     226             :         {
     227             :         case sal::detail::textenc::BAD_INPUT_STOP:
     228           0 :             nRow = 0;
     229           0 :             break;
     230             : 
     231             :         case sal::detail::textenc::BAD_INPUT_CONTINUE:
     232           0 :             nRow = 0;
     233           0 :             continue;
     234             : 
     235             :         case sal::detail::textenc::BAD_INPUT_NO_OUTPUT:
     236           0 :             goto no_output;
     237             :         }
     238           0 :         break;
     239             : 
     240             :     no_output:
     241           0 :         --pSrcBuf;
     242           0 :         nInfo |= RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOSMALL;
     243           0 :         break;
     244             :     }
     245             : 
     246         232 :     if (nRow != 0
     247          92 :         && (nInfo & (RTL_TEXTTOUNICODE_INFO_ERROR
     248             :                          | RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOSMALL))
     249             :                == 0)
     250             :     {
     251          92 :         if ((nFlags & RTL_TEXTTOUNICODE_FLAGS_FLUSH) == 0)
     252          92 :             nInfo |= RTL_TEXTTOUNICODE_INFO_SRCBUFFERTOSMALL;
     253             :         else
     254           0 :             switch (sal::detail::textenc::handleBadInputTextToUnicodeConversion(
     255             :                         false, true, 0, nFlags, &pDestBufPtr, pDestBufEnd,
     256           0 :                         &nInfo))
     257             :             {
     258             :             case sal::detail::textenc::BAD_INPUT_STOP:
     259             :             case sal::detail::textenc::BAD_INPUT_CONTINUE:
     260           0 :                 nRow = 0;
     261           0 :                 break;
     262             : 
     263             :             case sal::detail::textenc::BAD_INPUT_NO_OUTPUT:
     264           0 :                 nInfo |= RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOSMALL;
     265           0 :                 break;
     266             :             }
     267             :     }
     268             : 
     269         232 :     if (pContext)
     270         126 :         static_cast< ImplBig5HkscsToUnicodeContext * >(pContext)->m_nRow = nRow;
     271         232 :     if (pInfo)
     272         232 :         *pInfo = nInfo;
     273         232 :     if (pSrcCvtBytes)
     274         232 :         *pSrcCvtBytes = nConverted;
     275             : 
     276         232 :     return pDestBufPtr - pDestBuf;
     277             : }
     278             : 
     279          16 : sal_Size ImplConvertUnicodeToBig5Hkscs(void const * pData,
     280             :                                        void * pContext,
     281             :                                        sal_Unicode const * pSrcBuf,
     282             :                                        sal_Size nSrcChars,
     283             :                                        char * pDestBuf,
     284             :                                        sal_Size nDestBytes,
     285             :                                        sal_uInt32 nFlags,
     286             :                                        sal_uInt32 * pInfo,
     287             :                                        sal_Size * pSrcCvtChars)
     288             : {
     289             :     sal_uInt16 const * pBig5Hkscs2001Data
     290             :         = static_cast< ImplBig5HkscsConverterData const * >(pData)->
     291          16 :               m_pUnicodeToBig5Hkscs2001Data;
     292             :     sal_Int32 const * pBig5Hkscs2001PageOffsets
     293             :         = static_cast< ImplBig5HkscsConverterData const * >(pData)->
     294          16 :               m_pUnicodeToBig5Hkscs2001PageOffsets;
     295             :     sal_Int32 const * pBig5Hkscs2001PlaneOffsets
     296             :         = static_cast< ImplBig5HkscsConverterData const * >(pData)->
     297          16 :               m_pUnicodeToBig5Hkscs2001PlaneOffsets;
     298             :     ImplUniToDBCSHighTab const * pBig5Data
     299             :         = static_cast< ImplBig5HkscsConverterData const * >(pData)->
     300          16 :               m_pUnicodeToBig5Data;
     301          16 :     sal_Unicode nHighSurrogate = 0;
     302          16 :     sal_uInt32 nInfo = 0;
     303          16 :     sal_Size nConverted = 0;
     304          16 :     char * pDestBufPtr = pDestBuf;
     305          16 :     char * pDestBufEnd = pDestBuf + nDestBytes;
     306             : 
     307          16 :     if (pContext)
     308             :         nHighSurrogate
     309          16 :             = ((ImplUnicodeToTextContext *) pContext)->m_nHighSurrogate;
     310             : 
     311         126 :     for (; nConverted < nSrcChars; ++nConverted)
     312             :     {
     313         110 :         bool bUndefined = true;
     314         110 :         sal_uInt32 nChar = *pSrcBuf++;
     315         110 :         if (nHighSurrogate == 0)
     316             :         {
     317         106 :             if (ImplIsHighSurrogate(nChar))
     318             :             {
     319           4 :                 nHighSurrogate = (sal_Unicode) nChar;
     320           4 :                 continue;
     321             :             }
     322             :         }
     323           4 :         else if (ImplIsLowSurrogate(nChar))
     324           4 :             nChar = ImplCombineSurrogates(nHighSurrogate, nChar);
     325             :         else
     326             :         {
     327           0 :             bUndefined = false;
     328           0 :             goto bad_input;
     329             :         }
     330             : 
     331         106 :         if (ImplIsLowSurrogate(nChar) || ImplIsNoncharacter(nChar))
     332             :         {
     333           0 :             bUndefined = false;
     334           0 :             goto bad_input;
     335             :         }
     336             : 
     337         106 :         if (nChar < 0x80)
     338          28 :             if (pDestBufPtr != pDestBufEnd)
     339          28 :                 *pDestBufPtr++ = static_cast< char >(nChar);
     340             :             else
     341           0 :                 goto no_output;
     342             :         else
     343             :         {
     344          78 :             sal_uInt32 nBytes = 0;
     345          78 :             sal_Int32 nOffset = pBig5Hkscs2001PlaneOffsets[nChar >> 16];
     346          78 :             if (nOffset != -1)
     347             :             {
     348             :                 nOffset
     349         156 :                     = pBig5Hkscs2001PageOffsets[nOffset + ((nChar & 0xFF00)
     350         156 :                                                                >> 8)];
     351          78 :                 if (nOffset != -1)
     352             :                 {
     353          76 :                     sal_uInt32 nFirstLast = pBig5Hkscs2001Data[nOffset++];
     354          76 :                     sal_uInt32 nFirst = nFirstLast & 0xFF;
     355          76 :                     sal_uInt32 nLast = nFirstLast >> 8;
     356          76 :                     sal_uInt32 nIndex = nChar & 0xFF;
     357          76 :                     if (nIndex >= nFirst && nIndex <= nLast)
     358             :                     {
     359             :                         nBytes
     360          66 :                             = pBig5Hkscs2001Data[nOffset + (nIndex - nFirst)];
     361             :                     }
     362             :                 }
     363             :             }
     364          78 :             if (nBytes == 0)
     365             :             {
     366          24 :                 sal_uInt32 nIndex1 = nChar >> 8;
     367          24 :                 if (nIndex1 < 0x100)
     368             :                 {
     369          24 :                     sal_uInt32 nIndex2 = nChar & 0xFF;
     370          24 :                     sal_uInt32 nFirst = pBig5Data[nIndex1].mnLowStart;
     371          24 :                     if (nIndex2 >= nFirst
     372          24 :                         && nIndex2 <= pBig5Data[nIndex1].mnLowEnd)
     373          10 :                         nBytes = pBig5Data[nIndex1].
     374          10 :                                      mpToUniTrailTab[nIndex2 - nFirst];
     375             :                 }
     376             :             }
     377          78 :             if (nBytes == 0)
     378             :             {
     379             :                 ImplDBCSEUDCData const * p
     380             :                     = static_cast< ImplBig5HkscsConverterData const * >(pData)->
     381          14 :                           m_pEudcData;
     382             :                 sal_uInt32 nCount
     383             :                     = static_cast< ImplBig5HkscsConverterData const * >(pData)->
     384          14 :                           m_nEudcCount;
     385             :                 sal_uInt32 i;
     386          42 :                 for (i = 0; i < nCount; ++i) {
     387          42 :                     if (nChar >= p->mnUniStart && nChar <= p->mnUniEnd)
     388             :                     {
     389          14 :                         sal_uInt32 nIndex = nChar - p->mnUniStart;
     390          14 :                         sal_uInt32 nLeadOff = nIndex / p->mnTrailRangeCount;
     391          14 :                         sal_uInt32 nTrailOff = nIndex % p->mnTrailRangeCount;
     392             :                         sal_uInt32 nSize;
     393          14 :                         nBytes = (p->mnLeadStart + nLeadOff) << 8;
     394          14 :                         nSize = p->mnTrail1End - p->mnTrail1Start + 1;
     395          14 :                         if (nTrailOff < nSize)
     396             :                         {
     397           6 :                             nBytes |= p->mnTrail1Start + nTrailOff;
     398           6 :                             break;
     399             :                         }
     400           8 :                         nTrailOff -= nSize;
     401           8 :                         nSize = p->mnTrail2End - p->mnTrail2Start + 1;
     402           8 :                         if (nTrailOff < nSize)
     403             :                         {
     404           8 :                             nBytes |= p->mnTrail2Start + nTrailOff;
     405           8 :                             break;
     406             :                         }
     407           0 :                         nTrailOff -= nSize;
     408           0 :                         nBytes |= p->mnTrail3Start + nTrailOff;
     409           0 :                         break;
     410             :                     }
     411          28 :                     ++p;
     412             :                 }
     413             :             }
     414          78 :             if (nBytes == 0)
     415           0 :                 goto bad_input;
     416          78 :             if (pDestBufEnd - pDestBufPtr >= 2)
     417             :             {
     418          78 :                 *pDestBufPtr++ = static_cast< char >(nBytes >> 8);
     419          78 :                 *pDestBufPtr++ = static_cast< char >(nBytes & 0xFF);
     420             :             }
     421             :             else
     422           0 :                 goto no_output;
     423             :         }
     424         106 :         nHighSurrogate = 0;
     425         106 :         continue;
     426             : 
     427             :     bad_input:
     428           0 :         switch (sal::detail::textenc::handleBadInputUnicodeToTextConversion(
     429             :                     bUndefined, nChar, nFlags, &pDestBufPtr, pDestBufEnd,
     430           0 :                     &nInfo, NULL, 0, NULL))
     431             :         {
     432             :         case sal::detail::textenc::BAD_INPUT_STOP:
     433           0 :             nHighSurrogate = 0;
     434           0 :             break;
     435             : 
     436             :         case sal::detail::textenc::BAD_INPUT_CONTINUE:
     437           0 :             nHighSurrogate = 0;
     438           0 :             continue;
     439             : 
     440             :         case sal::detail::textenc::BAD_INPUT_NO_OUTPUT:
     441           0 :             goto no_output;
     442             :         }
     443           0 :         break;
     444             : 
     445             :     no_output:
     446           0 :         --pSrcBuf;
     447           0 :         nInfo |= RTL_UNICODETOTEXT_INFO_DESTBUFFERTOSMALL;
     448           0 :         break;
     449             :     }
     450             : 
     451          16 :     if (nHighSurrogate != 0
     452           0 :         && (nInfo & (RTL_UNICODETOTEXT_INFO_ERROR
     453             :                          | RTL_UNICODETOTEXT_INFO_DESTBUFFERTOSMALL))
     454             :                == 0)
     455             :     {
     456           0 :         if ((nFlags & RTL_UNICODETOTEXT_FLAGS_FLUSH) != 0)
     457           0 :             nInfo |= RTL_UNICODETOTEXT_INFO_SRCBUFFERTOSMALL;
     458             :         else
     459           0 :             switch (sal::detail::textenc::handleBadInputUnicodeToTextConversion(
     460             :                         false, 0, nFlags, &pDestBufPtr, pDestBufEnd, &nInfo,
     461           0 :                         NULL, 0, NULL))
     462             :             {
     463             :             case sal::detail::textenc::BAD_INPUT_STOP:
     464             :             case sal::detail::textenc::BAD_INPUT_CONTINUE:
     465           0 :                 nHighSurrogate = 0;
     466           0 :                 break;
     467             : 
     468             :             case sal::detail::textenc::BAD_INPUT_NO_OUTPUT:
     469           0 :                 nInfo |= RTL_UNICODETOTEXT_INFO_DESTBUFFERTOSMALL;
     470           0 :                 break;
     471             :             }
     472             :     }
     473             : 
     474          16 :     if (pContext)
     475             :         ((ImplUnicodeToTextContext *) pContext)->m_nHighSurrogate
     476          16 :             = nHighSurrogate;
     477          16 :     if (pInfo)
     478          16 :         *pInfo = nInfo;
     479          16 :     if (pSrcCvtChars)
     480          16 :         *pSrcCvtChars = nConverted;
     481             : 
     482          16 :     return pDestBufPtr - pDestBuf;
     483             : }
     484             : 
     485             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10