LCOV - code coverage report
Current view: top level - sal/textenc - converteuctw.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 133 199 66.8 %
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 "rtl/textcvt.h"
      23             : #include "sal/types.h"
      24             : 
      25             : #include "context.hxx"
      26             : #include "converter.hxx"
      27             : #include "converteuctw.hxx"
      28             : #include "tenchelp.hxx"
      29             : #include "unichars.hxx"
      30             : 
      31             : namespace {
      32             : 
      33             : enum ImplEucTwToUnicodeState
      34             : {
      35             :     IMPL_EUC_TW_TO_UNICODE_STATE_0,
      36             :     IMPL_EUC_TW_TO_UNICODE_STATE_1,
      37             :     IMPL_EUC_TW_TO_UNICODE_STATE_2_1,
      38             :     IMPL_EUC_TW_TO_UNICODE_STATE_2_2,
      39             :     IMPL_EUC_TW_TO_UNICODE_STATE_2_3
      40             : };
      41             : 
      42             : struct ImplEucTwToUnicodeContext
      43             : {
      44             :     ImplEucTwToUnicodeState m_eState;
      45             :     sal_Int32 m_nPlane; // 0--15
      46             :     sal_Int32 m_nRow; // 0--93
      47             : };
      48             : 
      49             : }
      50             : 
      51           4 : void * ImplCreateEucTwToUnicodeContext()
      52             : {
      53           4 :     ImplEucTwToUnicodeContext * pContext = new ImplEucTwToUnicodeContext;
      54           4 :     pContext->m_eState = IMPL_EUC_TW_TO_UNICODE_STATE_0;
      55           4 :     return pContext;
      56             : }
      57             : 
      58           0 : void ImplResetEucTwToUnicodeContext(void * pContext)
      59             : {
      60           0 :     if (pContext)
      61             :         static_cast< ImplEucTwToUnicodeContext * >(pContext)->m_eState
      62           0 :             = IMPL_EUC_TW_TO_UNICODE_STATE_0;
      63           0 : }
      64             : 
      65           4 : void ImplDestroyEucTwToUnicodeContext(void * pContext)
      66             : {
      67           4 :     delete static_cast< ImplEucTwToUnicodeContext * >(pContext);
      68           4 : }
      69             : 
      70          56 : sal_Size ImplConvertEucTwToUnicode(void const * pData,
      71             :                                    void * pContext,
      72             :                                    char const * pSrcBuf,
      73             :                                    sal_Size nSrcBytes,
      74             :                                    sal_Unicode * pDestBuf,
      75             :                                    sal_Size nDestChars,
      76             :                                    sal_uInt32 nFlags,
      77             :                                    sal_uInt32 * pInfo,
      78             :                                    sal_Size * pSrcCvtBytes)
      79             : {
      80             :     sal_uInt16 const * pCns116431992Data
      81             :         = static_cast< ImplEucTwConverterData const * >(pData)->
      82          56 :               m_pCns116431992ToUnicodeData;
      83             :     sal_Int32 const * pCns116431992RowOffsets
      84             :         = static_cast< ImplEucTwConverterData const * >(pData)->
      85          56 :               m_pCns116431992ToUnicodeRowOffsets;
      86             :     sal_Int32 const * pCns116431992PlaneOffsets
      87             :         = static_cast< ImplEucTwConverterData const * >(pData)->
      88          56 :               m_pCns116431992ToUnicodePlaneOffsets;
      89          56 :     ImplEucTwToUnicodeState eState = IMPL_EUC_TW_TO_UNICODE_STATE_0;
      90          56 :     sal_Int32 nPlane = 0;
      91          56 :     sal_Int32 nRow = 0;
      92          56 :     sal_uInt32 nInfo = 0;
      93          56 :     sal_Size nConverted = 0;
      94          56 :     sal_Unicode * pDestBufPtr = pDestBuf;
      95          56 :     sal_Unicode * pDestBufEnd = pDestBuf + nDestChars;
      96             : 
      97          56 :     if (pContext)
      98             :     {
      99          30 :         eState = static_cast< ImplEucTwToUnicodeContext * >(pContext)->m_eState;
     100          30 :         nPlane = static_cast< ImplEucTwToUnicodeContext * >(pContext)->m_nPlane;
     101          30 :         nRow = static_cast< ImplEucTwToUnicodeContext * >(pContext)->m_nRow;
     102             :     }
     103             : 
     104         148 :     for (; nConverted < nSrcBytes; ++nConverted)
     105             :     {
     106          92 :         bool bUndefined = true;
     107          92 :         sal_uInt32 nChar = *(unsigned char const *) pSrcBuf++;
     108          92 :         switch (eState)
     109             :         {
     110             :         case IMPL_EUC_TW_TO_UNICODE_STATE_0:
     111          62 :             if (nChar < 0x80)
     112          42 :                 if (pDestBufPtr != pDestBufEnd)
     113          42 :                     *pDestBufPtr++ = (sal_Unicode) nChar;
     114             :                 else
     115           0 :                     goto no_output;
     116          20 :             else if (nChar >= 0xA1 && nChar <= 0xFE)
     117             :             {
     118           8 :                 nRow = nChar - 0xA1;
     119           8 :                 eState = IMPL_EUC_TW_TO_UNICODE_STATE_1;
     120             :             }
     121          12 :             else if (nChar == 0x8E)
     122          12 :                 eState = IMPL_EUC_TW_TO_UNICODE_STATE_2_1;
     123             :             else
     124             :             {
     125           0 :                 bUndefined = false;
     126           0 :                 goto bad_input;
     127             :             }
     128          62 :             break;
     129             : 
     130             :         case IMPL_EUC_TW_TO_UNICODE_STATE_1:
     131           6 :             if (nChar >= 0xA1 && nChar <= 0xFE)
     132             :             {
     133           6 :                 nPlane = 0;
     134           6 :                 goto transform;
     135             :             }
     136             :             else
     137             :             {
     138           0 :                 bUndefined = false;
     139           0 :                 goto bad_input;
     140             :             }
     141             :             break;
     142             : 
     143             :         case IMPL_EUC_TW_TO_UNICODE_STATE_2_1:
     144          10 :             if (nChar >= 0xA1 && nChar <= 0xB0)
     145             :             {
     146          10 :                 nPlane = nChar - 0xA1;
     147          10 :                 eState = IMPL_EUC_TW_TO_UNICODE_STATE_2_2;
     148             :             }
     149             :             else
     150             :             {
     151           0 :                 bUndefined = false;
     152           0 :                 goto bad_input;
     153             :             }
     154          10 :             break;
     155             : 
     156             :         case IMPL_EUC_TW_TO_UNICODE_STATE_2_2:
     157           8 :             if (nChar >= 0xA1 && nChar <= 0xFE)
     158             :             {
     159           8 :                 nRow = nChar - 0xA1;
     160           8 :                 eState = IMPL_EUC_TW_TO_UNICODE_STATE_2_3;
     161             :             }
     162             :             else
     163             :             {
     164           0 :                 bUndefined = false;
     165           0 :                 goto bad_input;
     166             :             }
     167           8 :             break;
     168             : 
     169             :         case IMPL_EUC_TW_TO_UNICODE_STATE_2_3:
     170           6 :             if (nChar >= 0xA1 && nChar <= 0xFE)
     171             :                 goto transform;
     172             :             else
     173             :             {
     174           0 :                 bUndefined = false;
     175           0 :                 goto bad_input;
     176             :             }
     177             :             break;
     178             :         }
     179          80 :         continue;
     180             : 
     181             :     transform:
     182             :         {
     183          12 :             sal_Int32 nPlaneOffset = pCns116431992PlaneOffsets[nPlane];
     184          12 :             if (nPlaneOffset == -1)
     185           0 :                 goto bad_input;
     186             :             else
     187             :             {
     188             :                 sal_Int32 nOffset
     189          12 :                     = pCns116431992RowOffsets[nPlaneOffset + nRow];
     190          12 :                 if (nOffset == -1)
     191           0 :                     goto bad_input;
     192             :                 else
     193             :                 {
     194          12 :                     sal_uInt32 nFirstLast = pCns116431992Data[nOffset++];
     195          12 :                     sal_uInt32 nFirst = nFirstLast & 0xFF;
     196          12 :                     sal_uInt32 nLast = nFirstLast >> 8;
     197          12 :                     nChar -= 0xA0;
     198          12 :                     if (nChar >= nFirst && nChar <= nLast)
     199             :                     {
     200             :                         sal_uInt32 nUnicode
     201          12 :                             = pCns116431992Data[nOffset + (nChar - nFirst)];
     202          12 :                         if (nUnicode == 0xFFFF)
     203           0 :                             goto bad_input;
     204          12 :                         else if (ImplIsHighSurrogate(nUnicode))
     205           6 :                             if (pDestBufEnd - pDestBufPtr >= 2)
     206             :                             {
     207           6 :                                 nOffset += nLast - nFirst + 1;
     208           6 :                                 nFirst = pCns116431992Data[nOffset++];
     209           6 :                                 *pDestBufPtr++ = (sal_Unicode) nUnicode;
     210             :                                 *pDestBufPtr++
     211             :                                     = (sal_Unicode)
     212             :                                           pCns116431992Data[
     213           6 :                                               nOffset + (nChar - nFirst)];
     214             :                             }
     215             :                             else
     216           0 :                                 goto no_output;
     217             :                         else
     218           6 :                             if (pDestBufPtr != pDestBufEnd)
     219           6 :                                 *pDestBufPtr++ = (sal_Unicode) nUnicode;
     220             :                             else
     221           0 :                                 goto no_output;
     222             :                     }
     223             :                     else
     224             :                         goto bad_input;
     225          12 :                     eState = IMPL_EUC_TW_TO_UNICODE_STATE_0;
     226             :                 }
     227             :             }
     228          12 :             continue;
     229             :         }
     230             : 
     231             :     bad_input:
     232           0 :         switch (sal::detail::textenc::handleBadInputTextToUnicodeConversion(
     233             :                     bUndefined, true, 0, nFlags, &pDestBufPtr, pDestBufEnd,
     234           0 :                     &nInfo))
     235             :         {
     236             :         case sal::detail::textenc::BAD_INPUT_STOP:
     237           0 :             eState = IMPL_EUC_TW_TO_UNICODE_STATE_0;
     238           0 :             break;
     239             : 
     240             :         case sal::detail::textenc::BAD_INPUT_CONTINUE:
     241           0 :             eState = IMPL_EUC_TW_TO_UNICODE_STATE_0;
     242           0 :             continue;
     243             : 
     244             :         case sal::detail::textenc::BAD_INPUT_NO_OUTPUT:
     245           0 :             goto no_output;
     246             :         }
     247           0 :         break;
     248             : 
     249             :     no_output:
     250           0 :         --pSrcBuf;
     251           0 :         nInfo |= RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOSMALL;
     252           0 :         break;
     253             :     }
     254             : 
     255          56 :     if (eState != IMPL_EUC_TW_TO_UNICODE_STATE_0
     256          16 :         && (nInfo & (RTL_TEXTTOUNICODE_INFO_ERROR
     257             :                          | RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOSMALL))
     258             :                == 0)
     259             :     {
     260          16 :         if ((nFlags & RTL_TEXTTOUNICODE_FLAGS_FLUSH) == 0)
     261          16 :             nInfo |= RTL_TEXTTOUNICODE_INFO_SRCBUFFERTOSMALL;
     262             :         else
     263           0 :             switch (sal::detail::textenc::handleBadInputTextToUnicodeConversion(
     264             :                         false, true, 0, nFlags, &pDestBufPtr, pDestBufEnd,
     265           0 :                         &nInfo))
     266             :             {
     267             :             case sal::detail::textenc::BAD_INPUT_STOP:
     268             :             case sal::detail::textenc::BAD_INPUT_CONTINUE:
     269           0 :                 eState = IMPL_EUC_TW_TO_UNICODE_STATE_0;
     270           0 :                 break;
     271             : 
     272             :             case sal::detail::textenc::BAD_INPUT_NO_OUTPUT:
     273           0 :                 nInfo |= RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOSMALL;
     274           0 :                 break;
     275             :             }
     276             :     }
     277             : 
     278          56 :     if (pContext)
     279             :     {
     280          30 :         static_cast< ImplEucTwToUnicodeContext * >(pContext)->m_eState = eState;
     281          30 :         static_cast< ImplEucTwToUnicodeContext * >(pContext)->m_nPlane = nPlane;
     282          30 :         static_cast< ImplEucTwToUnicodeContext * >(pContext)->m_nRow = nRow;
     283             :     }
     284          56 :     if (pInfo)
     285          56 :         *pInfo = nInfo;
     286          56 :     if (pSrcCvtBytes)
     287          56 :         *pSrcCvtBytes = nConverted;
     288             : 
     289          56 :     return pDestBufPtr - pDestBuf;
     290             : }
     291             : 
     292           2 : sal_Size ImplConvertUnicodeToEucTw(void const * pData,
     293             :                                    void * pContext,
     294             :                                    sal_Unicode const * pSrcBuf,
     295             :                                    sal_Size nSrcChars,
     296             :                                    char * pDestBuf,
     297             :                                    sal_Size nDestBytes,
     298             :                                    sal_uInt32 nFlags,
     299             :                                    sal_uInt32 * pInfo,
     300             :                                    sal_Size * pSrcCvtChars)
     301             : {
     302             :     sal_uInt8 const * pCns116431992Data
     303             :         = static_cast< ImplEucTwConverterData const * >(pData)->
     304           2 :               m_pUnicodeToCns116431992Data;
     305             :     sal_Int32 const * pCns116431992PageOffsets
     306             :         = static_cast< ImplEucTwConverterData const * >(pData)->
     307           2 :               m_pUnicodeToCns116431992PageOffsets;
     308             :     sal_Int32 const * pCns116431992PlaneOffsets
     309             :         = static_cast< ImplEucTwConverterData const * >(pData)->
     310           2 :               m_pUnicodeToCns116431992PlaneOffsets;
     311           2 :     sal_Unicode nHighSurrogate = 0;
     312           2 :     sal_uInt32 nInfo = 0;
     313           2 :     sal_Size nConverted = 0;
     314           2 :     char * pDestBufPtr = pDestBuf;
     315           2 :     char * pDestBufEnd = pDestBuf + nDestBytes;
     316             : 
     317           2 :     if (pContext)
     318             :         nHighSurrogate
     319           2 :             = ((ImplUnicodeToTextContext *) pContext)->m_nHighSurrogate;
     320             : 
     321          22 :     for (; nConverted < nSrcChars; ++nConverted)
     322             :     {
     323          20 :         bool bUndefined = true;
     324          20 :         sal_uInt32 nChar = *pSrcBuf++;
     325          20 :         if (nHighSurrogate == 0)
     326             :         {
     327          18 :             if (ImplIsHighSurrogate(nChar))
     328             :             {
     329           2 :                 nHighSurrogate = (sal_Unicode) nChar;
     330           2 :                 continue;
     331             :             }
     332             :         }
     333           2 :         else if (ImplIsLowSurrogate(nChar))
     334           2 :             nChar = ImplCombineSurrogates(nHighSurrogate, nChar);
     335             :         else
     336             :         {
     337           0 :             bUndefined = false;
     338           0 :             goto bad_input;
     339             :         }
     340             : 
     341          18 :         if (ImplIsLowSurrogate(nChar) || ImplIsNoncharacter(nChar))
     342             :         {
     343           0 :             bUndefined = false;
     344           0 :             goto bad_input;
     345             :         }
     346             : 
     347          18 :         if (nChar < 0x80)
     348          14 :             if (pDestBufPtr != pDestBufEnd)
     349          14 :                 *pDestBufPtr++ = static_cast< char >(nChar);
     350             :             else
     351           0 :                 goto no_output;
     352             :         else
     353             :         {
     354           4 :             sal_Int32 nOffset = pCns116431992PlaneOffsets[nChar >> 16];
     355             :             sal_uInt32 nFirst;
     356             :             sal_uInt32 nLast;
     357             :             sal_uInt32 nPlane;
     358           4 :             if (nOffset == -1)
     359           0 :                 goto bad_input;
     360             :             nOffset
     361           4 :                 = pCns116431992PageOffsets[nOffset + ((nChar & 0xFF00) >> 8)];
     362           4 :             if (nOffset == -1)
     363           0 :                 goto bad_input;
     364           4 :             nFirst = pCns116431992Data[nOffset++];
     365           4 :             nLast = pCns116431992Data[nOffset++];
     366           4 :             nChar &= 0xFF;
     367           4 :             if (nChar < nFirst || nChar > nLast)
     368             :                 goto bad_input;
     369           4 :             nOffset += 3 * (nChar - nFirst);
     370           4 :             nPlane = pCns116431992Data[nOffset++];
     371           4 :             if (nPlane == 0)
     372           0 :                 goto bad_input;
     373           4 :             if (pDestBufEnd - pDestBufPtr < (nPlane == 1 ? 2 : 4))
     374           0 :                 goto no_output;
     375           4 :             if (nPlane != 1)
     376             :             {
     377           2 :                 *pDestBufPtr++ = static_cast< char >(static_cast< unsigned char >(0x8E));
     378           2 :                 *pDestBufPtr++ = static_cast< char >(0xA0 + nPlane);
     379             :             }
     380           4 :             *pDestBufPtr++ = static_cast< char >(0xA0 + pCns116431992Data[nOffset++]);
     381           4 :             *pDestBufPtr++ = static_cast< char >(0xA0 + pCns116431992Data[nOffset]);
     382             :         }
     383          18 :         nHighSurrogate = 0;
     384          18 :         continue;
     385             : 
     386             :     bad_input:
     387           0 :         switch (sal::detail::textenc::handleBadInputUnicodeToTextConversion(
     388             :                     bUndefined, nChar, nFlags, &pDestBufPtr, pDestBufEnd,
     389           0 :                     &nInfo, NULL, 0, NULL))
     390             :         {
     391             :         case sal::detail::textenc::BAD_INPUT_STOP:
     392           0 :             nHighSurrogate = 0;
     393           0 :             break;
     394             : 
     395             :         case sal::detail::textenc::BAD_INPUT_CONTINUE:
     396           0 :             nHighSurrogate = 0;
     397           0 :             continue;
     398             : 
     399             :         case sal::detail::textenc::BAD_INPUT_NO_OUTPUT:
     400           0 :             goto no_output;
     401             :         }
     402           0 :         break;
     403             : 
     404             :     no_output:
     405           0 :         --pSrcBuf;
     406           0 :         nInfo |= RTL_UNICODETOTEXT_INFO_DESTBUFFERTOSMALL;
     407           0 :         break;
     408             :     }
     409             : 
     410           2 :     if (nHighSurrogate != 0
     411           0 :         && (nInfo & (RTL_UNICODETOTEXT_INFO_ERROR
     412             :                          | RTL_UNICODETOTEXT_INFO_DESTBUFFERTOSMALL))
     413             :                == 0)
     414             :     {
     415           0 :         if ((nFlags & RTL_UNICODETOTEXT_FLAGS_FLUSH) != 0)
     416           0 :             nInfo |= RTL_UNICODETOTEXT_INFO_SRCBUFFERTOSMALL;
     417             :         else
     418           0 :             switch (sal::detail::textenc::handleBadInputUnicodeToTextConversion(
     419             :                         false, 0, nFlags, &pDestBufPtr, pDestBufEnd, &nInfo,
     420           0 :                         NULL, 0, NULL))
     421             :             {
     422             :             case sal::detail::textenc::BAD_INPUT_STOP:
     423             :             case sal::detail::textenc::BAD_INPUT_CONTINUE:
     424           0 :                 nHighSurrogate = 0;
     425           0 :                 break;
     426             : 
     427             :             case sal::detail::textenc::BAD_INPUT_NO_OUTPUT:
     428           0 :                 nInfo |= RTL_UNICODETOTEXT_INFO_DESTBUFFERTOSMALL;
     429           0 :                 break;
     430             :             }
     431             :     }
     432             : 
     433           2 :     if (pContext)
     434             :         ((ImplUnicodeToTextContext *) pContext)->m_nHighSurrogate
     435           2 :             = nHighSurrogate;
     436           2 :     if (pInfo)
     437           2 :         *pInfo = nInfo;
     438           2 :     if (pSrcCvtChars)
     439           2 :         *pSrcCvtChars = nConverted;
     440             : 
     441           2 :     return pDestBufPtr - pDestBuf;
     442             : }
     443             : 
     444             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10