LCOV - code coverage report
Current view: top level - sal/textenc - convertbig5hkscs.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 161 238 67.6 %
Date: 2015-06-13 12:38:46 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          10 : void * ImplCreateBig5HkscsToUnicodeContext()
      43             : {
      44             :     ImplBig5HkscsToUnicodeContext * pContext =
      45          10 :         new ImplBig5HkscsToUnicodeContext;
      46          10 :     pContext->m_nRow = 0;
      47          10 :     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          10 : void ImplDestroyBig5HkscsToUnicodeContext(void * pContext)
      57             : {
      58          10 :     delete static_cast< ImplBig5HkscsToUnicodeContext * >(pContext);
      59          10 : }
      60             : 
      61         116 : 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         116 :               m_pBig5Hkscs2001ToUnicodeData;
      74             :     sal_Int32 const * pBig5Hkscs2001RowOffsets
      75             :         = static_cast< ImplBig5HkscsConverterData const * >(pData)->
      76         116 :               m_pBig5Hkscs2001ToUnicodeRowOffsets;
      77             :     ImplDBCSToUniLeadTab const * pBig5Data
      78             :         = static_cast< ImplBig5HkscsConverterData const * >(pData)->
      79         116 :               m_pBig5ToUnicodeData;
      80         116 :     sal_Int32 nRow = 0;
      81         116 :     sal_uInt32 nInfo = 0;
      82         116 :     sal_Size nConverted = 0;
      83         116 :     sal_Unicode * pDestBufPtr = pDestBuf;
      84         116 :     sal_Unicode * pDestBufEnd = pDestBuf + nDestChars;
      85             : 
      86         116 :     if (pContext)
      87          63 :         nRow = static_cast< ImplBig5HkscsToUnicodeContext * >(pContext)->m_nRow;
      88             : 
      89         298 :     for (; nConverted < nSrcBytes; ++nConverted)
      90             :     {
      91         182 :         bool bUndefined = true;
      92         182 :         sal_uInt32 nChar = *reinterpret_cast<unsigned char const *>(pSrcBuf++);
      93         182 :         if (nRow == 0)
      94         113 :             if (nChar < 0x80)
      95          21 :                 if (pDestBufPtr != pDestBufEnd)
      96          21 :                     *pDestBufPtr++ = (sal_Unicode) nChar;
      97             :                 else
      98           0 :                     goto no_output;
      99          92 :             else if (nChar >= 0x81 && nChar <= 0xFE)
     100          92 :                 nRow = nChar;
     101             :             else
     102             :             {
     103           0 :                 bUndefined = false;
     104           0 :                 goto bad_input;
     105             :             }
     106             :         else
     107          69 :             if ((nChar >= 0x40 && nChar <= 0x7E)
     108          45 :                 || (nChar >= 0xA1 && nChar <= 0xFE))
     109             :             {
     110          69 :                 sal_uInt32 nUnicode = 0xFFFF;
     111          69 :                 sal_Int32 nOffset = pBig5Hkscs2001RowOffsets[nRow];
     112          69 :                 sal_uInt32 nFirst=0;
     113          69 :                 sal_uInt32 nLast=0;
     114          69 :                 if (nOffset != -1)
     115             :                 {
     116          57 :                     sal_uInt32 nFirstLast = pBig5Hkscs2001Data[nOffset++];
     117          57 :                     nFirst = nFirstLast & 0xFF;
     118          57 :                     nLast = nFirstLast >> 8;
     119          57 :                     if (nChar >= nFirst && nChar <= nLast)
     120             :                         nUnicode
     121          54 :                             = pBig5Hkscs2001Data[nOffset + (nChar - nFirst)];
     122             :                 }
     123          69 :                 if (nUnicode == 0xFFFF)
     124             :                 {
     125          15 :                     sal_uInt32 n = pBig5Data[nRow].mnTrailStart;
     126          15 :                     if (nChar >= n && nChar <= pBig5Data[nRow].mnTrailEnd)
     127             :                     {
     128           9 :                         nUnicode = pBig5Data[nRow].mpToUniTrailTab[nChar - n];
     129           9 :                         if (nUnicode == 0)
     130           0 :                             nUnicode = 0xFFFF;
     131             :                         assert(!ImplIsHighSurrogate(nUnicode));
     132             :                     }
     133             :                 }
     134          69 :                 if (nUnicode == 0xFFFF)
     135             :                 {
     136             :                     ImplDBCSEUDCData const * p
     137             :                         = static_cast< ImplBig5HkscsConverterData const * >(pData)->
     138           6 :                               m_pEudcData;
     139             :                     sal_uInt32 nCount
     140             :                         = static_cast< ImplBig5HkscsConverterData const * >(pData)->
     141           6 :                               m_nEudcCount;
     142             :                     sal_uInt32 i;
     143          18 :                     for (i = 0; i < nCount; ++i)
     144             :                     {
     145          18 :                         if (nRow >= p->mnLeadStart && nRow <= p->mnLeadEnd)
     146             :                         {
     147           6 :                             if (nChar < p->mnTrail1Start)
     148           0 :                                 break;
     149           6 :                             if (nChar <= p->mnTrail1End)
     150             :                             {
     151             :                                 nUnicode
     152             :                                     = p->mnUniStart
     153           6 :                                           + (nRow - p->mnLeadStart)
     154           3 :                                                 * p->mnTrailRangeCount
     155           3 :                                           + (nChar - p->mnTrail1Start);
     156           3 :                                 break;
     157             :                             }
     158           3 :                             if (p->mnTrailCount < 2
     159           3 :                                 || nChar < p->mnTrail2Start)
     160             :                                 break;
     161           3 :                             if (nChar <= p->mnTrail2End)
     162             :                             {
     163             :                                 nUnicode
     164             :                                     = p->mnUniStart
     165           6 :                                           + (nRow - p->mnLeadStart)
     166           3 :                                                 * p->mnTrailRangeCount
     167           3 :                                           + (nChar - p->mnTrail2Start)
     168           3 :                                           + (p->mnTrail1End - p->mnTrail1Start
     169           3 :                                                  + 1);
     170           3 :                                 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          12 :                         ++p;
     191             :                     }
     192             :                     assert(!ImplIsHighSurrogate(nUnicode));
     193             :                 }
     194          69 :                 if (nUnicode == 0xFFFF)
     195           0 :                     goto bad_input;
     196          69 :                 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          69 :                     if (pDestBufPtr != pDestBufEnd)
     210          69 :                         *pDestBufPtr++ = (sal_Unicode) nUnicode;
     211             :                     else
     212           0 :                         goto no_output;
     213          69 :                 nRow = 0;
     214             :             }
     215             :             else
     216             :             {
     217           0 :                 bUndefined = false;
     218           0 :                 goto bad_input;
     219             :             }
     220         182 :         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         116 :     if (nRow != 0
     247          46 :         && (nInfo & (RTL_TEXTTOUNICODE_INFO_ERROR
     248             :                          | RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOSMALL))
     249             :                == 0)
     250             :     {
     251          46 :         if ((nFlags & RTL_TEXTTOUNICODE_FLAGS_FLUSH) == 0)
     252          46 :             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         116 :     if (pContext)
     270          63 :         static_cast< ImplBig5HkscsToUnicodeContext * >(pContext)->m_nRow = nRow;
     271         116 :     if (pInfo)
     272         116 :         *pInfo = nInfo;
     273         116 :     if (pSrcCvtBytes)
     274         116 :         *pSrcCvtBytes = nConverted;
     275             : 
     276         116 :     return pDestBufPtr - pDestBuf;
     277             : }
     278             : 
     279           8 : 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           8 :               m_pUnicodeToBig5Hkscs2001Data;
     292             :     sal_Int32 const * pBig5Hkscs2001PageOffsets
     293             :         = static_cast< ImplBig5HkscsConverterData const * >(pData)->
     294           8 :               m_pUnicodeToBig5Hkscs2001PageOffsets;
     295             :     sal_Int32 const * pBig5Hkscs2001PlaneOffsets
     296             :         = static_cast< ImplBig5HkscsConverterData const * >(pData)->
     297           8 :               m_pUnicodeToBig5Hkscs2001PlaneOffsets;
     298             :     ImplUniToDBCSHighTab const * pBig5Data
     299             :         = static_cast< ImplBig5HkscsConverterData const * >(pData)->
     300           8 :               m_pUnicodeToBig5Data;
     301           8 :     sal_Unicode nHighSurrogate = 0;
     302           8 :     sal_uInt32 nInfo = 0;
     303           8 :     sal_Size nConverted = 0;
     304           8 :     char * pDestBufPtr = pDestBuf;
     305           8 :     char * pDestBufEnd = pDestBuf + nDestBytes;
     306             : 
     307           8 :     if (pContext)
     308             :         nHighSurrogate
     309           8 :             = static_cast<ImplUnicodeToTextContext *>(pContext)->m_nHighSurrogate;
     310             : 
     311          63 :     for (; nConverted < nSrcChars; ++nConverted)
     312             :     {
     313          55 :         bool bUndefined = true;
     314          55 :         sal_uInt32 nChar = *pSrcBuf++;
     315          55 :         if (nHighSurrogate == 0)
     316             :         {
     317          53 :             if (ImplIsHighSurrogate(nChar))
     318             :             {
     319           2 :                 nHighSurrogate = (sal_Unicode) nChar;
     320           2 :                 continue;
     321             :             }
     322             :         }
     323           2 :         else if (ImplIsLowSurrogate(nChar))
     324           2 :             nChar = ImplCombineSurrogates(nHighSurrogate, nChar);
     325             :         else
     326             :         {
     327           0 :             bUndefined = false;
     328           0 :             goto bad_input;
     329             :         }
     330             : 
     331          53 :         if (ImplIsLowSurrogate(nChar) || ImplIsNoncharacter(nChar))
     332             :         {
     333           0 :             bUndefined = false;
     334           0 :             goto bad_input;
     335             :         }
     336             : 
     337          53 :         if (nChar < 0x80)
     338          14 :             if (pDestBufPtr != pDestBufEnd)
     339          14 :                 *pDestBufPtr++ = static_cast< char >(nChar);
     340             :             else
     341           0 :                 goto no_output;
     342             :         else
     343             :         {
     344          39 :             sal_uInt32 nBytes = 0;
     345          39 :             sal_Int32 nOffset = pBig5Hkscs2001PlaneOffsets[nChar >> 16];
     346          39 :             if (nOffset != -1)
     347             :             {
     348             :                 nOffset
     349          78 :                     = pBig5Hkscs2001PageOffsets[nOffset + ((nChar & 0xFF00)
     350          78 :                                                                >> 8)];
     351          39 :                 if (nOffset != -1)
     352             :                 {
     353          38 :                     sal_uInt32 nFirstLast = pBig5Hkscs2001Data[nOffset++];
     354          38 :                     sal_uInt32 nFirst = nFirstLast & 0xFF;
     355          38 :                     sal_uInt32 nLast = nFirstLast >> 8;
     356          38 :                     sal_uInt32 nIndex = nChar & 0xFF;
     357          38 :                     if (nIndex >= nFirst && nIndex <= nLast)
     358             :                     {
     359             :                         nBytes
     360          33 :                             = pBig5Hkscs2001Data[nOffset + (nIndex - nFirst)];
     361             :                     }
     362             :                 }
     363             :             }
     364          39 :             if (nBytes == 0)
     365             :             {
     366          12 :                 sal_uInt32 nIndex1 = nChar >> 8;
     367          12 :                 if (nIndex1 < 0x100)
     368             :                 {
     369          12 :                     sal_uInt32 nIndex2 = nChar & 0xFF;
     370          12 :                     sal_uInt32 nFirst = pBig5Data[nIndex1].mnLowStart;
     371          12 :                     if (nIndex2 >= nFirst
     372          12 :                         && nIndex2 <= pBig5Data[nIndex1].mnLowEnd)
     373           5 :                         nBytes = pBig5Data[nIndex1].
     374           5 :                                      mpToUniTrailTab[nIndex2 - nFirst];
     375             :                 }
     376             :             }
     377          39 :             if (nBytes == 0)
     378             :             {
     379             :                 ImplDBCSEUDCData const * p
     380             :                     = static_cast< ImplBig5HkscsConverterData const * >(pData)->
     381           7 :                           m_pEudcData;
     382             :                 sal_uInt32 nCount
     383             :                     = static_cast< ImplBig5HkscsConverterData const * >(pData)->
     384           7 :                           m_nEudcCount;
     385             :                 sal_uInt32 i;
     386          21 :                 for (i = 0; i < nCount; ++i) {
     387          21 :                     if (nChar >= p->mnUniStart && nChar <= p->mnUniEnd)
     388             :                     {
     389           7 :                         sal_uInt32 nIndex = nChar - p->mnUniStart;
     390           7 :                         sal_uInt32 nLeadOff = nIndex / p->mnTrailRangeCount;
     391           7 :                         sal_uInt32 nTrailOff = nIndex % p->mnTrailRangeCount;
     392             :                         sal_uInt32 nSize;
     393           7 :                         nBytes = (p->mnLeadStart + nLeadOff) << 8;
     394           7 :                         nSize = p->mnTrail1End - p->mnTrail1Start + 1;
     395           7 :                         if (nTrailOff < nSize)
     396             :                         {
     397           3 :                             nBytes |= p->mnTrail1Start + nTrailOff;
     398           3 :                             break;
     399             :                         }
     400           4 :                         nTrailOff -= nSize;
     401           4 :                         nSize = p->mnTrail2End - p->mnTrail2Start + 1;
     402           4 :                         if (nTrailOff < nSize)
     403             :                         {
     404           4 :                             nBytes |= p->mnTrail2Start + nTrailOff;
     405           4 :                             break;
     406             :                         }
     407           0 :                         nTrailOff -= nSize;
     408           0 :                         nBytes |= p->mnTrail3Start + nTrailOff;
     409           0 :                         break;
     410             :                     }
     411          14 :                     ++p;
     412             :                 }
     413             :             }
     414          39 :             if (nBytes == 0)
     415           0 :                 goto bad_input;
     416          39 :             if (pDestBufEnd - pDestBufPtr >= 2)
     417             :             {
     418          39 :                 *pDestBufPtr++ = static_cast< char >(nBytes >> 8);
     419          39 :                 *pDestBufPtr++ = static_cast< char >(nBytes & 0xFF);
     420             :             }
     421             :             else
     422           0 :                 goto no_output;
     423             :         }
     424          53 :         nHighSurrogate = 0;
     425          53 :         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           8 :     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           8 :     if (pContext)
     475             :         static_cast<ImplUnicodeToTextContext *>(pContext)->m_nHighSurrogate
     476           8 :             = nHighSurrogate;
     477           8 :     if (pInfo)
     478           8 :         *pInfo = nInfo;
     479           8 :     if (pSrcCvtChars)
     480           8 :         *pSrcCvtChars = nConverted;
     481             : 
     482           8 :     return pDestBufPtr - pDestBuf;
     483             : }
     484             : 
     485             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11