LCOV - code coverage report
Current view: top level - libreoffice/sal/textenc - converteuctw.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 132 197 67.0 %
Date: 2012-12-27 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           2 : void * ImplCreateEucTwToUnicodeContext()
      52             : {
      53           2 :     ImplEucTwToUnicodeContext * pContext = new ImplEucTwToUnicodeContext;
      54           2 :     pContext->m_eState = IMPL_EUC_TW_TO_UNICODE_STATE_0;
      55           2 :     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           2 : void ImplDestroyEucTwToUnicodeContext(void * pContext)
      66             : {
      67           2 :     delete static_cast< ImplEucTwToUnicodeContext * >(pContext);
      68           2 : }
      69             : 
      70          28 : 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          28 :               m_pCns116431992ToUnicodeData;
      83             :     sal_Int32 const * pCns116431992RowOffsets
      84             :         = static_cast< ImplEucTwConverterData const * >(pData)->
      85          28 :               m_pCns116431992ToUnicodeRowOffsets;
      86             :     sal_Int32 const * pCns116431992PlaneOffsets
      87             :         = static_cast< ImplEucTwConverterData const * >(pData)->
      88          28 :               m_pCns116431992ToUnicodePlaneOffsets;
      89          28 :     ImplEucTwToUnicodeState eState = IMPL_EUC_TW_TO_UNICODE_STATE_0;
      90          28 :     sal_Int32 nPlane = 0;
      91          28 :     sal_Int32 nRow = 0;
      92          28 :     sal_uInt32 nInfo = 0;
      93          28 :     sal_Size nConverted = 0;
      94          28 :     sal_Unicode * pDestBufPtr = pDestBuf;
      95          28 :     sal_Unicode * pDestBufEnd = pDestBuf + nDestChars;
      96             : 
      97          28 :     if (pContext)
      98             :     {
      99          15 :         eState = static_cast< ImplEucTwToUnicodeContext * >(pContext)->m_eState;
     100          15 :         nPlane = static_cast< ImplEucTwToUnicodeContext * >(pContext)->m_nPlane;
     101          15 :         nRow = static_cast< ImplEucTwToUnicodeContext * >(pContext)->m_nRow;
     102             :     }
     103             : 
     104          74 :     for (; nConverted < nSrcBytes; ++nConverted)
     105             :     {
     106          46 :         bool bUndefined = true;
     107          46 :         sal_uInt32 nChar = *(sal_uChar const *) pSrcBuf++;
     108          46 :         switch (eState)
     109             :         {
     110             :         case IMPL_EUC_TW_TO_UNICODE_STATE_0:
     111          31 :             if (nChar < 0x80)
     112          21 :                 if (pDestBufPtr != pDestBufEnd)
     113          21 :                     *pDestBufPtr++ = (sal_Unicode) nChar;
     114             :                 else
     115           0 :                     goto no_output;
     116          10 :             else if (nChar >= 0xA1 && nChar <= 0xFE)
     117             :             {
     118           4 :                 nRow = nChar - 0xA1;
     119           4 :                 eState = IMPL_EUC_TW_TO_UNICODE_STATE_1;
     120             :             }
     121           6 :             else if (nChar == 0x8E)
     122           6 :                 eState = IMPL_EUC_TW_TO_UNICODE_STATE_2_1;
     123             :             else
     124             :             {
     125           0 :                 bUndefined = false;
     126           0 :                 goto bad_input;
     127             :             }
     128          31 :             break;
     129             : 
     130             :         case IMPL_EUC_TW_TO_UNICODE_STATE_1:
     131           3 :             if (nChar >= 0xA1 && nChar <= 0xFE)
     132             :             {
     133           3 :                 nPlane = 0;
     134           3 :                 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           5 :             if (nChar >= 0xA1 && nChar <= 0xB0)
     145             :             {
     146           5 :                 nPlane = nChar - 0xA1;
     147           5 :                 eState = IMPL_EUC_TW_TO_UNICODE_STATE_2_2;
     148             :             }
     149             :             else
     150             :             {
     151           0 :                 bUndefined = false;
     152           0 :                 goto bad_input;
     153             :             }
     154           5 :             break;
     155             : 
     156             :         case IMPL_EUC_TW_TO_UNICODE_STATE_2_2:
     157           4 :             if (nChar >= 0xA1 && nChar <= 0xFE)
     158             :             {
     159           4 :                 nRow = nChar - 0xA1;
     160           4 :                 eState = IMPL_EUC_TW_TO_UNICODE_STATE_2_3;
     161             :             }
     162             :             else
     163             :             {
     164           0 :                 bUndefined = false;
     165           0 :                 goto bad_input;
     166             :             }
     167           4 :             break;
     168             : 
     169             :         case IMPL_EUC_TW_TO_UNICODE_STATE_2_3:
     170           3 :             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          40 :         continue;
     180             : 
     181             :     transform:
     182             :         {
     183           6 :             sal_Int32 nPlaneOffset = pCns116431992PlaneOffsets[nPlane];
     184           6 :             if (nPlaneOffset == -1)
     185           0 :                 goto bad_input;
     186             :             else
     187             :             {
     188             :                 sal_Int32 nOffset
     189           6 :                     = pCns116431992RowOffsets[nPlaneOffset + nRow];
     190           6 :                 if (nOffset == -1)
     191           0 :                     goto bad_input;
     192             :                 else
     193             :                 {
     194           6 :                     sal_uInt32 nFirstLast = pCns116431992Data[nOffset++];
     195           6 :                     sal_uInt32 nFirst = nFirstLast & 0xFF;
     196           6 :                     sal_uInt32 nLast = nFirstLast >> 8;
     197           6 :                     nChar -= 0xA0;
     198           6 :                     if (nChar >= nFirst && nChar <= nLast)
     199             :                     {
     200             :                         sal_uInt32 nUnicode
     201           6 :                             = pCns116431992Data[nOffset + (nChar - nFirst)];
     202           6 :                         if (nUnicode == 0xFFFF)
     203           0 :                             goto bad_input;
     204           6 :                         else if (ImplIsHighSurrogate(nUnicode))
     205           3 :                             if (pDestBufEnd - pDestBufPtr >= 2)
     206             :                             {
     207           3 :                                 nOffset += nLast - nFirst + 1;
     208           3 :                                 nFirst = pCns116431992Data[nOffset++];
     209           3 :                                 *pDestBufPtr++ = (sal_Unicode) nUnicode;
     210             :                                 *pDestBufPtr++
     211             :                                     = (sal_Unicode)
     212             :                                           pCns116431992Data[
     213           3 :                                               nOffset + (nChar - nFirst)];
     214             :                             }
     215             :                             else
     216           0 :                                 goto no_output;
     217             :                         else
     218           3 :                             if (pDestBufPtr != pDestBufEnd)
     219           3 :                                 *pDestBufPtr++ = (sal_Unicode) nUnicode;
     220             :                             else
     221           0 :                                 goto no_output;
     222             :                     }
     223             :                     else
     224             :                         goto bad_input;
     225           6 :                     eState = IMPL_EUC_TW_TO_UNICODE_STATE_0;
     226             :                 }
     227             :             }
     228           6 :             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          28 :     if (eState != IMPL_EUC_TW_TO_UNICODE_STATE_0
     256             :         && (nInfo & (RTL_TEXTTOUNICODE_INFO_ERROR
     257             :                          | RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOSMALL))
     258             :                == 0)
     259             :     {
     260           8 :         if ((nFlags & RTL_TEXTTOUNICODE_FLAGS_FLUSH) == 0)
     261           8 :             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          28 :     if (pContext)
     279             :     {
     280          15 :         static_cast< ImplEucTwToUnicodeContext * >(pContext)->m_eState = eState;
     281          15 :         static_cast< ImplEucTwToUnicodeContext * >(pContext)->m_nPlane = nPlane;
     282          15 :         static_cast< ImplEucTwToUnicodeContext * >(pContext)->m_nRow = nRow;
     283             :     }
     284          28 :     if (pInfo)
     285          28 :         *pInfo = nInfo;
     286          28 :     if (pSrcCvtBytes)
     287          28 :         *pSrcCvtBytes = nConverted;
     288             : 
     289          28 :     return pDestBufPtr - pDestBuf;
     290             : }
     291             : 
     292           1 : 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           1 :               m_pUnicodeToCns116431992Data;
     305             :     sal_Int32 const * pCns116431992PageOffsets
     306             :         = static_cast< ImplEucTwConverterData const * >(pData)->
     307           1 :               m_pUnicodeToCns116431992PageOffsets;
     308             :     sal_Int32 const * pCns116431992PlaneOffsets
     309             :         = static_cast< ImplEucTwConverterData const * >(pData)->
     310           1 :               m_pUnicodeToCns116431992PlaneOffsets;
     311           1 :     sal_Unicode nHighSurrogate = 0;
     312           1 :     sal_uInt32 nInfo = 0;
     313           1 :     sal_Size nConverted = 0;
     314           1 :     char * pDestBufPtr = pDestBuf;
     315           1 :     char * pDestBufEnd = pDestBuf + nDestBytes;
     316             : 
     317           1 :     if (pContext)
     318             :         nHighSurrogate
     319           1 :             = ((ImplUnicodeToTextContext *) pContext)->m_nHighSurrogate;
     320             : 
     321          11 :     for (; nConverted < nSrcChars; ++nConverted)
     322             :     {
     323          10 :         bool bUndefined = true;
     324          10 :         sal_uInt32 nChar = *pSrcBuf++;
     325          10 :         if (nHighSurrogate == 0)
     326             :         {
     327           9 :             if (ImplIsHighSurrogate(nChar))
     328             :             {
     329           1 :                 nHighSurrogate = (sal_Unicode) nChar;
     330           1 :                 continue;
     331             :             }
     332             :         }
     333           1 :         else if (ImplIsLowSurrogate(nChar))
     334           1 :             nChar = ImplCombineSurrogates(nHighSurrogate, nChar);
     335             :         else
     336             :         {
     337           0 :             bUndefined = false;
     338           0 :             goto bad_input;
     339             :         }
     340             : 
     341           9 :         if (ImplIsLowSurrogate(nChar) || ImplIsNoncharacter(nChar))
     342             :         {
     343           0 :             bUndefined = false;
     344           0 :             goto bad_input;
     345             :         }
     346             : 
     347           9 :         if (nChar < 0x80)
     348           7 :             if (pDestBufPtr != pDestBufEnd)
     349           7 :                 *pDestBufPtr++ = static_cast< char >(nChar);
     350             :             else
     351           0 :                 goto no_output;
     352             :         else
     353             :         {
     354           2 :             sal_Int32 nOffset = pCns116431992PlaneOffsets[nChar >> 16];
     355             :             sal_uInt32 nFirst;
     356             :             sal_uInt32 nLast;
     357             :             sal_uInt32 nPlane;
     358           2 :             if (nOffset == -1)
     359           0 :                 goto bad_input;
     360             :             nOffset
     361           2 :                 = pCns116431992PageOffsets[nOffset + ((nChar & 0xFF00) >> 8)];
     362           2 :             if (nOffset == -1)
     363           0 :                 goto bad_input;
     364           2 :             nFirst = pCns116431992Data[nOffset++];
     365           2 :             nLast = pCns116431992Data[nOffset++];
     366           2 :             nChar &= 0xFF;
     367           2 :             if (nChar < nFirst || nChar > nLast)
     368             :                 goto bad_input;
     369           2 :             nOffset += 3 * (nChar - nFirst);
     370           2 :             nPlane = pCns116431992Data[nOffset++];
     371           2 :             if (nPlane == 0)
     372           0 :                 goto bad_input;
     373           2 :             if (pDestBufEnd - pDestBufPtr < (nPlane == 1 ? 2 : 4))
     374           0 :                 goto no_output;
     375           2 :             if (nPlane != 1)
     376             :             {
     377           1 :                 *pDestBufPtr++ = static_cast< char >(static_cast< unsigned char >(0x8E));
     378           1 :                 *pDestBufPtr++ = static_cast< char >(0xA0 + nPlane);
     379             :             }
     380           2 :             *pDestBufPtr++ = static_cast< char >(0xA0 + pCns116431992Data[nOffset++]);
     381           2 :             *pDestBufPtr++ = static_cast< char >(0xA0 + pCns116431992Data[nOffset]);
     382             :         }
     383           9 :         nHighSurrogate = 0;
     384           9 :         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           1 :     if (nHighSurrogate != 0
     411             :         && (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           1 :     if (pContext)
     434             :         ((ImplUnicodeToTextContext *) pContext)->m_nHighSurrogate
     435           1 :             = nHighSurrogate;
     436           1 :     if (pInfo)
     437           1 :         *pInfo = nInfo;
     438           1 :     if (pSrcCvtChars)
     439           1 :         *pSrcCvtChars = nConverted;
     440             : 
     441           1 :     return pDestBufPtr - pDestBuf;
     442             : }
     443             : 
     444             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10