LCOV - code coverage report
Current view: top level - libreoffice/sal/textenc - convertiso2022cn.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 265 405 65.4 %
Date: 2012-12-27 Functions: 8 10 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 "convertiso2022cn.hxx"
      28             : #include "tenchelp.hxx"
      29             : #include "unichars.hxx"
      30             : 
      31             : namespace {
      32             : 
      33             : enum ImplIso2022CnToUnicodeState // order is important:
      34             : {
      35             :     IMPL_ISO_2022_CN_TO_UNICODE_STATE_ASCII,
      36             :     IMPL_ISO_2022_CN_TO_UNICODE_STATE_SO,
      37             :     IMPL_ISO_2022_CN_TO_UNICODE_STATE_SO_2,
      38             :     IMPL_ISO_2022_CN_TO_UNICODE_STATE_116432,
      39             :     IMPL_ISO_2022_CN_TO_UNICODE_STATE_116432_2,
      40             :     IMPL_ISO_2022_CN_TO_UNICODE_STATE_ESC,
      41             :     IMPL_ISO_2022_CN_TO_UNICODE_STATE_ESC_DOLLAR,
      42             :     IMPL_ISO_2022_CN_TO_UNICODE_STATE_ESC_DOLLAR_RPAREN,
      43             :     IMPL_ISO_2022_CN_TO_UNICODE_STATE_ESC_DOLLAR_ASTERISK
      44             : };
      45             : 
      46             : struct ImplIso2022CnToUnicodeContext
      47             : {
      48             :     ImplIso2022CnToUnicodeState m_eState;
      49             :     sal_uInt32 m_nRow;
      50             :     bool m_bSo;
      51             :     bool m_b116431;
      52             : };
      53             : 
      54             : enum ImplUnicodeToIso2022CnDesignator
      55             : {
      56             :     IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_NONE,
      57             :     IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_2312,
      58             :     IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_116431
      59             : };
      60             : 
      61             : struct ImplUnicodeToIso2022CnContext
      62             : {
      63             :     sal_Unicode m_nHighSurrogate;
      64             :     ImplUnicodeToIso2022CnDesignator m_eSoDesignator;
      65             :     bool m_b116432Designator;
      66             :     bool m_bSo;
      67             : };
      68             : 
      69             : }
      70             : 
      71           4 : void * ImplCreateIso2022CnToUnicodeContext()
      72             : {
      73             :     ImplIso2022CnToUnicodeContext * pContext =
      74           4 :         new ImplIso2022CnToUnicodeContext;
      75           4 :     pContext->m_eState = IMPL_ISO_2022_CN_TO_UNICODE_STATE_ASCII;
      76           4 :     pContext->m_bSo = false;
      77           4 :     pContext->m_b116431 = false;
      78           4 :     return pContext;
      79             : }
      80             : 
      81           0 : void ImplResetIso2022CnToUnicodeContext(void * pContext)
      82             : {
      83           0 :     if (pContext)
      84             :     {
      85             :         static_cast< ImplIso2022CnToUnicodeContext * >(pContext)->m_eState
      86           0 :             = IMPL_ISO_2022_CN_TO_UNICODE_STATE_ASCII;
      87           0 :         static_cast< ImplIso2022CnToUnicodeContext * >(pContext)->m_bSo = false;
      88           0 :         static_cast< ImplIso2022CnToUnicodeContext * >(pContext)->m_b116431 = false;
      89             :     }
      90           0 : }
      91             : 
      92           4 : void ImplDestroyIso2022CnToUnicodeContext(void * pContext)
      93             : {
      94           4 :     delete static_cast< ImplIso2022CnToUnicodeContext * >(pContext);
      95           4 : }
      96             : 
      97          74 : sal_Size ImplConvertIso2022CnToUnicode(void const * pData,
      98             :                                        void * pContext,
      99             :                                        char const * pSrcBuf,
     100             :                                        sal_Size nSrcBytes,
     101             :                                        sal_Unicode * pDestBuf,
     102             :                                        sal_Size nDestChars,
     103             :                                        sal_uInt32 nFlags,
     104             :                                        sal_uInt32 * pInfo,
     105             :                                        sal_Size * pSrcCvtBytes)
     106             : {
     107             :     ImplDBCSToUniLeadTab const * pGb2312Data
     108             :         = static_cast< ImplIso2022CnConverterData const * >(pData)->
     109          74 :               m_pGb2312ToUnicodeData;
     110             :     sal_uInt16 const * pCns116431992Data
     111             :         = static_cast< ImplIso2022CnConverterData const * >(pData)->
     112          74 :               m_pCns116431992ToUnicodeData;
     113             :     sal_Int32 const * pCns116431992RowOffsets
     114             :         = static_cast< ImplIso2022CnConverterData const * >(pData)->
     115          74 :               m_pCns116431992ToUnicodeRowOffsets;
     116             :     sal_Int32 const * pCns116431992PlaneOffsets
     117             :         = static_cast< ImplIso2022CnConverterData const * >(pData)->
     118          74 :               m_pCns116431992ToUnicodePlaneOffsets;
     119             :     ImplIso2022CnToUnicodeState eState
     120          74 :         = IMPL_ISO_2022_CN_TO_UNICODE_STATE_ASCII;
     121          74 :     sal_uInt32 nRow = 0;
     122          74 :     bool bSo = false;
     123          74 :     bool b116431 = false;
     124          74 :     sal_uInt32 nInfo = 0;
     125          74 :     sal_Size nConverted = 0;
     126          74 :     sal_Unicode * pDestBufPtr = pDestBuf;
     127          74 :     sal_Unicode * pDestBufEnd = pDestBuf + nDestChars;
     128             : 
     129          74 :     if (pContext)
     130             :     {
     131          74 :         eState = static_cast< ImplIso2022CnToUnicodeContext * >(pContext)->m_eState;
     132          74 :         nRow = static_cast< ImplIso2022CnToUnicodeContext * >(pContext)->m_nRow;
     133          74 :         bSo = static_cast< ImplIso2022CnToUnicodeContext * >(pContext)->m_bSo;
     134          74 :         b116431 = static_cast< ImplIso2022CnToUnicodeContext * >(pContext)->m_b116431;
     135             :     }
     136             : 
     137         214 :     for (; nConverted < nSrcBytes; ++nConverted)
     138             :     {
     139         140 :         bool bUndefined = true;
     140         140 :         sal_uInt32 nChar = *(sal_uChar const *) pSrcBuf++;
     141             :         sal_uInt32 nPlane;
     142         140 :         switch (eState)
     143             :         {
     144             :         case IMPL_ISO_2022_CN_TO_UNICODE_STATE_ASCII:
     145          52 :             if (nChar == 0x0E) // SO
     146             :             {
     147           8 :                 bSo = true;
     148           8 :                 eState = IMPL_ISO_2022_CN_TO_UNICODE_STATE_SO;
     149             :             }
     150          44 :             else if (nChar == 0x1B) // ESC
     151           8 :                 eState = IMPL_ISO_2022_CN_TO_UNICODE_STATE_ESC;
     152          36 :             else if (nChar < 0x80)
     153          36 :                 if (pDestBufPtr != pDestBufEnd)
     154          36 :                     *pDestBufPtr++ = (sal_Unicode) nChar;
     155             :                 else
     156           0 :                     goto no_output;
     157             :             else
     158             :             {
     159           0 :                 bUndefined = false;
     160           0 :                 goto bad_input;
     161             :             }
     162          52 :             break;
     163             : 
     164             :         case IMPL_ISO_2022_CN_TO_UNICODE_STATE_SO:
     165          28 :             if (nChar == 0x0F) // SI
     166             :             {
     167           8 :                 bSo = false;
     168           8 :                 eState = IMPL_ISO_2022_CN_TO_UNICODE_STATE_ASCII;
     169             :             }
     170          20 :             else if (nChar == 0x1B) // ESC
     171           8 :                 eState = IMPL_ISO_2022_CN_TO_UNICODE_STATE_ESC;
     172          12 :             else if (nChar >= 0x21 && nChar <= 0x7E)
     173             :             {
     174          12 :                 nRow = nChar;
     175          12 :                 eState = IMPL_ISO_2022_CN_TO_UNICODE_STATE_SO_2;
     176             :             }
     177             :             else
     178             :             {
     179           0 :                 bUndefined = false;
     180           0 :                 goto bad_input;
     181             :             }
     182          28 :             break;
     183             : 
     184             :         case IMPL_ISO_2022_CN_TO_UNICODE_STATE_SO_2:
     185          12 :             if (nChar >= 0x21 && nChar <= 0x7E)
     186          12 :                 if (b116431)
     187             :                 {
     188           4 :                     nPlane = 0;
     189           4 :                     goto transform;
     190             :                 }
     191             :                 else
     192             :                 {
     193           8 :                     sal_uInt16 nUnicode = 0;
     194             :                     sal_uInt32 nFirst;
     195           8 :                     nRow += 0x80;
     196           8 :                     nChar += 0x80;
     197           8 :                     nFirst = pGb2312Data[nRow].mnTrailStart;
     198          16 :                     if (nChar >= nFirst
     199           8 :                         && nChar <= pGb2312Data[nRow].mnTrailEnd)
     200           8 :                         nUnicode = pGb2312Data[nRow].
     201           8 :                                        mpToUniTrailTab[nChar - nFirst];
     202           8 :                     if (nUnicode != 0)
     203           8 :                         if (pDestBufPtr != pDestBufEnd)
     204             :                         {
     205           8 :                             *pDestBufPtr++ = (sal_Unicode) nUnicode;
     206           8 :                             eState = IMPL_ISO_2022_CN_TO_UNICODE_STATE_SO;
     207             :                         }
     208             :                         else
     209           0 :                             goto no_output;
     210             :                     else
     211           0 :                         goto bad_input;
     212           8 :                 }
     213             :             else
     214             :             {
     215           0 :                 bUndefined = false;
     216           0 :                 goto bad_input;
     217             :             }
     218           8 :             break;
     219             : 
     220             :         case IMPL_ISO_2022_CN_TO_UNICODE_STATE_116432:
     221           4 :             if (nChar >= 0x21 && nChar <= 0x7E)
     222             :             {
     223           4 :                 nRow = nChar;
     224           4 :                 eState = IMPL_ISO_2022_CN_TO_UNICODE_STATE_116432_2;
     225             :             }
     226             :             else
     227             :             {
     228           0 :                 bUndefined = false;
     229           0 :                 goto bad_input;
     230             :             }
     231           4 :             break;
     232             : 
     233             :         case IMPL_ISO_2022_CN_TO_UNICODE_STATE_116432_2:
     234           4 :             if (nChar >= 0x21 && nChar <= 0x7E)
     235             :             {
     236           4 :                 nPlane = 1;
     237           4 :                 goto transform;
     238             :             }
     239             :             else
     240             :             {
     241           0 :                 bUndefined = false;
     242           0 :                 goto bad_input;
     243             :             }
     244             :             break;
     245             : 
     246             :         case IMPL_ISO_2022_CN_TO_UNICODE_STATE_ESC:
     247          16 :             if (nChar == 0x24) // $
     248          12 :                 eState = IMPL_ISO_2022_CN_TO_UNICODE_STATE_ESC_DOLLAR;
     249           4 :             else if (nChar == 0x4E) // N
     250           4 :                 eState = IMPL_ISO_2022_CN_TO_UNICODE_STATE_116432;
     251             :             else
     252             :             {
     253           0 :                 bUndefined = false;
     254           0 :                 goto bad_input;
     255             :             }
     256          16 :             break;
     257             : 
     258             :         case IMPL_ISO_2022_CN_TO_UNICODE_STATE_ESC_DOLLAR:
     259          12 :             if (nChar == 0x29) // )
     260           8 :                 eState = IMPL_ISO_2022_CN_TO_UNICODE_STATE_ESC_DOLLAR_RPAREN;
     261           4 :             else if (nChar == 0x2A) // *
     262             :                 eState
     263           4 :                     = IMPL_ISO_2022_CN_TO_UNICODE_STATE_ESC_DOLLAR_ASTERISK;
     264             :             else
     265             :             {
     266           0 :                 bUndefined = false;
     267           0 :                 goto bad_input;
     268             :             }
     269          12 :             break;
     270             : 
     271             :         case IMPL_ISO_2022_CN_TO_UNICODE_STATE_ESC_DOLLAR_RPAREN:
     272           8 :             if (nChar == 0x41) // A
     273             :             {
     274           6 :                 b116431 = false;
     275             :                 eState = bSo ? IMPL_ISO_2022_CN_TO_UNICODE_STATE_SO :
     276           6 :                                IMPL_ISO_2022_CN_TO_UNICODE_STATE_ASCII;
     277             :             }
     278           2 :             else if (nChar == 0x47) // G
     279             :             {
     280           2 :                 b116431 = true;
     281             :                 eState = bSo ? IMPL_ISO_2022_CN_TO_UNICODE_STATE_SO :
     282           2 :                                IMPL_ISO_2022_CN_TO_UNICODE_STATE_ASCII;
     283             :             }
     284             :             else
     285             :             {
     286           0 :                 bUndefined = false;
     287           0 :                 goto bad_input;
     288             :             }
     289           8 :             break;
     290             : 
     291             :         case IMPL_ISO_2022_CN_TO_UNICODE_STATE_ESC_DOLLAR_ASTERISK:
     292           4 :             if (nChar == 0x48) // H
     293             :                 eState = bSo ? IMPL_ISO_2022_CN_TO_UNICODE_STATE_SO :
     294           4 :                                IMPL_ISO_2022_CN_TO_UNICODE_STATE_ASCII;
     295             :             else
     296             :             {
     297           0 :                 bUndefined = false;
     298           0 :                 goto bad_input;
     299             :             }
     300           4 :             break;
     301             :         }
     302         132 :         continue;
     303             : 
     304             :     transform:
     305             :         {
     306           8 :             sal_Int32 nPlaneOffset = pCns116431992PlaneOffsets[nPlane];
     307           8 :             if (nPlaneOffset == -1)
     308           0 :                 goto bad_input;
     309             :             else
     310             :             {
     311             :                 sal_Int32 nOffset
     312           8 :                     = pCns116431992RowOffsets[nPlaneOffset + (nRow - 0x21)];
     313           8 :                 if (nOffset == -1)
     314           0 :                     goto bad_input;
     315             :                 else
     316             :                 {
     317           8 :                     sal_uInt32 nFirstLast = pCns116431992Data[nOffset++];
     318           8 :                     sal_uInt32 nFirst = nFirstLast & 0xFF;
     319           8 :                     sal_uInt32 nLast = nFirstLast >> 8;
     320           8 :                     nChar -= 0x20;
     321           8 :                     if (nChar >= nFirst && nChar <= nLast)
     322             :                     {
     323             :                         sal_uInt32 nUnicode
     324           8 :                             = pCns116431992Data[nOffset + (nChar - nFirst)];
     325           8 :                         if (nUnicode == 0xFFFF)
     326           0 :                             goto bad_input;
     327           8 :                         else if (ImplIsHighSurrogate(nUnicode))
     328           0 :                             if (pDestBufEnd - pDestBufPtr >= 2)
     329             :                             {
     330           0 :                                 nOffset += nLast - nFirst + 1;
     331           0 :                                 nFirst = pCns116431992Data[nOffset++];
     332           0 :                                 *pDestBufPtr++ = (sal_Unicode) nUnicode;
     333             :                                 *pDestBufPtr++
     334             :                                     = (sal_Unicode)
     335             :                                           pCns116431992Data[
     336           0 :                                               nOffset + (nChar - nFirst)];
     337             :                             }
     338             :                             else
     339           0 :                                 goto no_output;
     340             :                         else
     341           8 :                             if (pDestBufPtr != pDestBufEnd)
     342           8 :                                 *pDestBufPtr++ = (sal_Unicode) nUnicode;
     343             :                             else
     344           0 :                                 goto no_output;
     345             :                     }
     346             :                     else
     347             :                         goto bad_input;
     348             :                     eState = bSo ? IMPL_ISO_2022_CN_TO_UNICODE_STATE_SO :
     349           8 :                                    IMPL_ISO_2022_CN_TO_UNICODE_STATE_ASCII;
     350             :                 }
     351             :             }
     352           8 :             continue;
     353             :         }
     354             : 
     355             :     bad_input:
     356           0 :         switch (sal::detail::textenc::handleBadInputTextToUnicodeConversion(
     357             :                     bUndefined, true, 0, nFlags, &pDestBufPtr, pDestBufEnd,
     358           0 :                     &nInfo))
     359             :         {
     360             :         case sal::detail::textenc::BAD_INPUT_STOP:
     361           0 :             eState = IMPL_ISO_2022_CN_TO_UNICODE_STATE_ASCII;
     362           0 :             b116431 = false;
     363           0 :             break;
     364             : 
     365             :         case sal::detail::textenc::BAD_INPUT_CONTINUE:
     366           0 :             eState = IMPL_ISO_2022_CN_TO_UNICODE_STATE_ASCII;
     367           0 :             b116431 = false;
     368           0 :             continue;
     369             : 
     370             :         case sal::detail::textenc::BAD_INPUT_NO_OUTPUT:
     371           0 :             goto no_output;
     372             :         }
     373           0 :         break;
     374             : 
     375             :     no_output:
     376           0 :         --pSrcBuf;
     377           0 :         nInfo |= RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOSMALL;
     378           0 :         break;
     379             :     }
     380             : 
     381          74 :     if (eState > IMPL_ISO_2022_CN_TO_UNICODE_STATE_SO
     382             :         && (nInfo & (RTL_TEXTTOUNICODE_INFO_ERROR
     383             :                          | RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOSMALL))
     384             :                == 0)
     385             :     {
     386          30 :         if ((nFlags & RTL_TEXTTOUNICODE_FLAGS_FLUSH) == 0)
     387          30 :             nInfo |= RTL_TEXTTOUNICODE_INFO_SRCBUFFERTOSMALL;
     388             :         else
     389           0 :             switch (sal::detail::textenc::handleBadInputTextToUnicodeConversion(
     390             :                         false, true, 0, nFlags, &pDestBufPtr, pDestBufEnd,
     391           0 :                         &nInfo))
     392             :             {
     393             :             case sal::detail::textenc::BAD_INPUT_STOP:
     394             :             case sal::detail::textenc::BAD_INPUT_CONTINUE:
     395           0 :                 eState = IMPL_ISO_2022_CN_TO_UNICODE_STATE_ASCII;
     396           0 :                 b116431 = false;
     397           0 :                 break;
     398             : 
     399             :             case sal::detail::textenc::BAD_INPUT_NO_OUTPUT:
     400           0 :                 nInfo |= RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOSMALL;
     401           0 :                 break;
     402             :             }
     403             :     }
     404             : 
     405          74 :     if (pContext)
     406             :     {
     407          74 :         static_cast< ImplIso2022CnToUnicodeContext * >(pContext)->m_eState = eState;
     408          74 :         static_cast< ImplIso2022CnToUnicodeContext * >(pContext)->m_nRow = nRow;
     409          74 :         static_cast< ImplIso2022CnToUnicodeContext * >(pContext)->m_bSo = bSo;
     410          74 :         static_cast< ImplIso2022CnToUnicodeContext * >(pContext)->m_b116431 = b116431;
     411             :     }
     412          74 :     if (pInfo)
     413          74 :         *pInfo = nInfo;
     414          74 :     if (pSrcCvtBytes)
     415          74 :         *pSrcCvtBytes = nConverted;
     416             : 
     417          74 :     return pDestBufPtr - pDestBuf;
     418             : }
     419             : 
     420           1 : void * ImplCreateUnicodeToIso2022CnContext(void)
     421             : {
     422             :     ImplUnicodeToIso2022CnContext * pContext =
     423           1 :         new ImplUnicodeToIso2022CnContext;
     424           1 :     pContext->m_nHighSurrogate = 0;
     425           1 :     pContext->m_eSoDesignator = IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_NONE;
     426           1 :     pContext->m_b116432Designator = false;
     427           1 :     pContext->m_bSo = false;
     428           1 :     return pContext;
     429             : }
     430             : 
     431           0 : void ImplResetUnicodeToIso2022CnContext(void * pContext)
     432             : {
     433           0 :     if (pContext)
     434             :     {
     435           0 :         static_cast< ImplUnicodeToIso2022CnContext * >(pContext)->m_nHighSurrogate = 0;
     436             :         static_cast< ImplUnicodeToIso2022CnContext * >(pContext)->m_eSoDesignator
     437           0 :             = IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_NONE;
     438             :         static_cast< ImplUnicodeToIso2022CnContext * >(pContext)->m_b116432Designator
     439           0 :             = false;
     440           0 :         static_cast< ImplUnicodeToIso2022CnContext * >(pContext)->m_bSo = false;
     441             :     }
     442           0 : }
     443             : 
     444           1 : void ImplDestroyUnicodeToIso2022CnContext(void * pContext)
     445             : {
     446           1 :     delete static_cast< ImplUnicodeToIso2022CnContext * >(pContext);
     447           1 : }
     448             : 
     449           4 : static sal_uInt32 ImplIso2022CnTranslateTo2312(ImplUniToDBCSHighTab const *
     450             :                                                    pGb2312Data,
     451             :                                                sal_uInt32 nChar)
     452             : {
     453           4 :     sal_uInt32 nIndex1 = nChar >> 8;
     454           4 :     if (nIndex1 < 0x100)
     455             :     {
     456           4 :         sal_uInt32 nIndex2 = nChar & 0xFF;
     457           4 :         sal_uInt32 nFirst = pGb2312Data[nIndex1].mnLowStart;
     458           4 :         if (nIndex2 >= nFirst && nIndex2 <= pGb2312Data[nIndex1].mnLowEnd)
     459           4 :             return pGb2312Data[nIndex1].mpToUniTrailTab[nIndex2 - nFirst]
     460           4 :                        & 0x7F7F;
     461             :     }
     462           0 :     return 0;
     463             : }
     464             : 
     465             : static sal_uInt32
     466           1 : ImplIso2022CnTranslateTo116431(sal_uInt8 const * pCns116431992Data,
     467             :                                sal_Int32 const * pCns116431992PageOffsets,
     468             :                                sal_Int32 const * pCns116431992PlaneOffsets,
     469             :                                sal_uInt32 nChar)
     470             : {
     471           1 :     sal_Int32 nOffset = pCns116431992PlaneOffsets[nChar >> 16];
     472             :     sal_uInt32 nFirst;
     473             :     sal_uInt32 nLast;
     474             :     sal_uInt32 nPlane;
     475           1 :     if (nOffset == -1)
     476           0 :         return 0;
     477           1 :     nOffset = pCns116431992PageOffsets[nOffset + ((nChar & 0xFF00) >> 8)];
     478           1 :     if (nOffset == -1)
     479           0 :         return 0;
     480           1 :     nFirst = pCns116431992Data[nOffset++];
     481           1 :     nLast = pCns116431992Data[nOffset++];
     482           1 :     nChar &= 0xFF;
     483           1 :     if (nChar < nFirst || nChar > nLast)
     484           0 :         return 0;
     485           1 :     nOffset += 3 * (nChar - nFirst);
     486           1 :     nPlane = pCns116431992Data[nOffset++];
     487           1 :     if (nPlane != 1)
     488           1 :         return 0;
     489           0 :     return (0x20 + pCns116431992Data[nOffset]) << 8
     490           0 :                | (0x20 + pCns116431992Data[nOffset + 1]);
     491             : }
     492             : 
     493           1 : sal_Size ImplConvertUnicodeToIso2022Cn(void const * pData,
     494             :                                        void * pContext,
     495             :                                        sal_Unicode const * pSrcBuf,
     496             :                                        sal_Size nSrcChars,
     497             :                                        char * pDestBuf,
     498             :                                        sal_Size nDestBytes,
     499             :                                        sal_uInt32 nFlags,
     500             :                                        sal_uInt32 * pInfo,
     501             :                                        sal_Size * pSrcCvtChars)
     502             : {
     503             :     ImplUniToDBCSHighTab const * pGb2312Data
     504             :         = static_cast< ImplIso2022CnConverterData const * >(pData)->
     505           1 :               m_pUnicodeToGb2312Data;
     506             :     sal_uInt8 const * pCns116431992Data
     507             :         = static_cast< ImplIso2022CnConverterData const * >(pData)->
     508           1 :               m_pUnicodeToCns116431992Data;
     509             :     sal_Int32 const * pCns116431992PageOffsets
     510             :         = static_cast< ImplIso2022CnConverterData const * >(pData)->
     511           1 :               m_pUnicodeToCns116431992PageOffsets;
     512             :     sal_Int32 const * pCns116431992PlaneOffsets
     513             :         = static_cast< ImplIso2022CnConverterData const * >(pData)->
     514           1 :               m_pUnicodeToCns116431992PlaneOffsets;
     515           1 :     sal_Unicode nHighSurrogate = 0;
     516             :     ImplUnicodeToIso2022CnDesignator eSoDesignator
     517           1 :         = IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_NONE;
     518           1 :     bool b116432Designator = false;
     519           1 :     bool bSo = false;
     520           1 :     sal_uInt32 nInfo = 0;
     521           1 :     sal_Size nConverted = 0;
     522           1 :     char * pDestBufPtr = pDestBuf;
     523           1 :     char * pDestBufEnd = pDestBuf + nDestBytes;
     524             :     bool bWritten;
     525             : 
     526           1 :     if (pContext)
     527             :     {
     528             :         nHighSurrogate
     529           1 :             = static_cast< ImplUnicodeToIso2022CnContext * >(pContext)->m_nHighSurrogate;
     530             :         eSoDesignator
     531           1 :             = static_cast< ImplUnicodeToIso2022CnContext * >(pContext)->m_eSoDesignator;
     532             :         b116432Designator = static_cast< ImplUnicodeToIso2022CnContext * >(pContext)->
     533           1 :                                 m_b116432Designator;
     534           1 :         bSo = static_cast< ImplUnicodeToIso2022CnContext * >(pContext)->m_bSo;
     535             :     }
     536             : 
     537          15 :     for (; nConverted < nSrcChars; ++nConverted)
     538             :     {
     539          14 :         bool bUndefined = true;
     540          14 :         sal_uInt32 nChar = *pSrcBuf++;
     541          14 :         if (nHighSurrogate == 0)
     542             :         {
     543          14 :             if (ImplIsHighSurrogate(nChar))
     544             :             {
     545           0 :                 nHighSurrogate = (sal_Unicode) nChar;
     546           0 :                 continue;
     547             :             }
     548             :         }
     549           0 :         else if (ImplIsLowSurrogate(nChar))
     550           0 :             nChar = ImplCombineSurrogates(nHighSurrogate, nChar);
     551             :         else
     552             :         {
     553           0 :             bUndefined = false;
     554           0 :             goto bad_input;
     555             :         }
     556             : 
     557          14 :         if (ImplIsLowSurrogate(nChar) || ImplIsNoncharacter(nChar))
     558             :         {
     559           0 :             bUndefined = false;
     560           0 :             goto bad_input;
     561             :         }
     562             : 
     563          14 :         if (nChar == 0x0A || nChar == 0x0D) // LF, CR
     564             :         {
     565           2 :             if (bSo)
     566             :             {
     567           1 :                 if (pDestBufPtr != pDestBufEnd)
     568             :                 {
     569           1 :                     *pDestBufPtr++ = 0x0F; // SI
     570           1 :                     bSo = false;
     571             :                     eSoDesignator
     572           1 :                         = IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_NONE;
     573           1 :                     b116432Designator = false;
     574             :                 }
     575             :                 else
     576           0 :                     goto no_output;
     577             :             }
     578           4 :             if (pDestBufPtr != pDestBufEnd)
     579           2 :                 *pDestBufPtr++ = static_cast< char >(nChar);
     580             :             else
     581           0 :                 goto no_output;
     582             :         }
     583          12 :         else if (nChar == 0x0E || nChar == 0x0F || nChar == 0x1B)
     584             :             goto bad_input;
     585          12 :         else if (nChar < 0x80)
     586             :         {
     587           8 :             if (bSo)
     588             :             {
     589           0 :                 if (pDestBufPtr != pDestBufEnd)
     590             :                 {
     591           0 :                     *pDestBufPtr++ = 0x0F; // SI
     592           0 :                     bSo = false;
     593             :                 }
     594             :                 else
     595           0 :                     goto no_output;
     596             :             }
     597           8 :             if (pDestBufPtr != pDestBufEnd)
     598           8 :                 *pDestBufPtr++ = static_cast< char >(nChar);
     599             :             else
     600           0 :                 goto no_output;
     601             :         }
     602             :         else
     603             :         {
     604           4 :             sal_uInt32 nBytes = 0;
     605             :             ImplUnicodeToIso2022CnDesignator eNewDesignator =
     606           4 :                          IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_NONE;
     607           4 :             switch (eSoDesignator)
     608             :             {
     609             :             case IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_NONE:
     610           2 :                 nBytes = ImplIso2022CnTranslateTo2312(pGb2312Data, nChar);
     611           2 :                 if (nBytes != 0)
     612             :                 {
     613             :                     eNewDesignator
     614           2 :                         = IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_2312;
     615           2 :                     break;
     616             :                 }
     617             :                 nBytes = ImplIso2022CnTranslateTo116431(
     618             :                              pCns116431992Data,
     619             :                              pCns116431992PageOffsets,
     620             :                              pCns116431992PlaneOffsets,
     621           0 :                              nChar);
     622           0 :                 if (nBytes != 0)
     623             :                 {
     624             :                     eNewDesignator
     625           0 :                         = IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_116431;
     626           0 :                     break;
     627             :                 }
     628           0 :                 break;
     629             : 
     630             :             case IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_2312:
     631           2 :                 nBytes = ImplIso2022CnTranslateTo2312(pGb2312Data, nChar);
     632           2 :                 if (nBytes != 0)
     633             :                 {
     634             :                     eNewDesignator
     635           1 :                         = IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_NONE;
     636           1 :                     break;
     637             :                 }
     638             :                 nBytes = ImplIso2022CnTranslateTo116431(
     639             :                              pCns116431992Data,
     640             :                              pCns116431992PageOffsets,
     641             :                              pCns116431992PlaneOffsets,
     642           1 :                              nChar);
     643           1 :                 if (nBytes != 0)
     644             :                 {
     645             :                     eNewDesignator
     646           0 :                         = IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_116431;
     647           0 :                     break;
     648             :                 }
     649           1 :                 break;
     650             : 
     651             :             case IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_116431:
     652             :                 nBytes = ImplIso2022CnTranslateTo116431(
     653             :                              pCns116431992Data,
     654             :                              pCns116431992PageOffsets,
     655             :                              pCns116431992PlaneOffsets,
     656           0 :                              nChar);
     657           0 :                 if (nBytes != 0)
     658             :                 {
     659             :                     eNewDesignator
     660           0 :                         = IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_NONE;
     661           0 :                     break;
     662             :                 }
     663           0 :                 nBytes = ImplIso2022CnTranslateTo2312(pGb2312Data, nChar);
     664           0 :                 if (nBytes != 0)
     665             :                 {
     666             :                     eNewDesignator
     667           0 :                         = IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_2312;
     668           0 :                     break;
     669             :                 }
     670           0 :                 break;
     671             :             }
     672           4 :             if (nBytes != 0)
     673             :             {
     674           3 :                 if (eNewDesignator
     675             :                         != IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_NONE)
     676             :                 {
     677           2 :                     if (bSo)
     678             :                     {
     679           0 :                         if (pDestBufPtr != pDestBufEnd)
     680             :                         {
     681           0 :                             *pDestBufPtr++ = 0x0F; // SI
     682           0 :                             bSo = false;
     683             :                         }
     684             :                         else
     685           0 :                             goto no_output;
     686             :                     }
     687           2 :                     if (pDestBufEnd - pDestBufPtr >= 4)
     688             :                     {
     689           2 :                         *pDestBufPtr++ = 0x1B; // ESC
     690           2 :                         *pDestBufPtr++ = 0x24; // $
     691           2 :                         *pDestBufPtr++ = 0x29; // )
     692             :                         *pDestBufPtr++
     693             :                             = eNewDesignator
     694             :                               == IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_2312 ?
     695           2 :                                   0x41 : 0x47; // A, G
     696           2 :                         eSoDesignator = eNewDesignator;
     697             :                     }
     698             :                     else
     699           0 :                         goto no_output;
     700             :                 }
     701           3 :                 if (!bSo)
     702             :                 {
     703           2 :                     if (pDestBufPtr != pDestBufEnd)
     704             :                     {
     705           2 :                         *pDestBufPtr++ = 0x0E; // SO
     706           2 :                         bSo = true;
     707             :                     }
     708             :                     else
     709           0 :                         goto no_output;
     710             :                 }
     711           3 :                 if (pDestBufEnd - pDestBufPtr >= 4)
     712             :                 {
     713           3 :                     *pDestBufPtr++ = static_cast< char >(nBytes >> 8);
     714           3 :                     *pDestBufPtr++ = static_cast< char >(nBytes & 0xFF);
     715             :                 }
     716             :                 else
     717           0 :                     goto no_output;
     718             :             }
     719             :             else
     720             :             {
     721           1 :                 sal_Int32 nOffset = pCns116431992PlaneOffsets[nChar >> 16];
     722             :                 sal_uInt32 nFirst;
     723             :                 sal_uInt32 nLast;
     724             :                 sal_uInt32 nPlane;
     725           1 :                 if (nOffset == -1)
     726           0 :                     goto bad_input;
     727             :                 nOffset
     728             :                     = pCns116431992PageOffsets[nOffset
     729           1 :                                                    + ((nChar & 0xFF00) >> 8)];
     730           1 :                 if (nOffset == -1)
     731           0 :                     goto bad_input;
     732           1 :                 nFirst = pCns116431992Data[nOffset++];
     733           1 :                 nLast = pCns116431992Data[nOffset++];
     734           1 :                 nChar &= 0xFF;
     735           1 :                 if (nChar < nFirst || nChar > nLast)
     736             :                     goto bad_input;
     737           1 :                 nOffset += 3 * (nChar - nFirst);
     738           1 :                 nPlane = pCns116431992Data[nOffset++];
     739           1 :                 if (nPlane != 2)
     740           0 :                     goto bad_input;
     741           1 :                 if (!b116432Designator)
     742             :                 {
     743           1 :                     if (pDestBufEnd - pDestBufPtr >= 4)
     744             :                     {
     745           1 :                         *pDestBufPtr++ = 0x1B; // ESC
     746           1 :                         *pDestBufPtr++ = 0x24; // $
     747           1 :                         *pDestBufPtr++ = 0x2A; // *
     748           1 :                         *pDestBufPtr++ = 0x48; // H
     749           1 :                         b116432Designator = true;
     750             :                     }
     751             :                     else
     752           0 :                         goto no_output;
     753             :                 }
     754           1 :                 if (pDestBufEnd - pDestBufPtr >= 4)
     755             :                 {
     756           1 :                     *pDestBufPtr++ = 0x1B; // ESC
     757           1 :                     *pDestBufPtr++ = 0x4E; // N
     758             :                     *pDestBufPtr++
     759           1 :                         = static_cast< char >(0x20 + pCns116431992Data[nOffset++]);
     760             :                     *pDestBufPtr++
     761           1 :                         = static_cast< char >(0x20 + pCns116431992Data[nOffset]);
     762             :                 }
     763             :                 else
     764           0 :                     goto no_output;
     765             :             }
     766             :         }
     767          14 :         nHighSurrogate = 0;
     768          14 :         continue;
     769             : 
     770             :     bad_input:
     771           0 :         switch (sal::detail::textenc::handleBadInputUnicodeToTextConversion(
     772             :                     bUndefined, nChar, nFlags, &pDestBufPtr, pDestBufEnd,
     773           0 :                     &nInfo, "\x0F" /* SI */, bSo ? 1 : 0, &bWritten))
     774             :         {
     775             :         case sal::detail::textenc::BAD_INPUT_STOP:
     776           0 :             nHighSurrogate = 0;
     777           0 :             break;
     778             : 
     779             :         case sal::detail::textenc::BAD_INPUT_CONTINUE:
     780           0 :             if (bWritten)
     781           0 :                 bSo = false;
     782           0 :             nHighSurrogate = 0;
     783           0 :             continue;
     784             : 
     785             :         case sal::detail::textenc::BAD_INPUT_NO_OUTPUT:
     786           0 :             goto no_output;
     787             :         }
     788           0 :         break;
     789             : 
     790             :     no_output:
     791           0 :         --pSrcBuf;
     792           0 :         nInfo |= RTL_UNICODETOTEXT_INFO_DESTBUFFERTOSMALL;
     793           0 :         break;
     794             :     }
     795             : 
     796           1 :     if ((nInfo & (RTL_UNICODETOTEXT_INFO_ERROR
     797             :                       | RTL_UNICODETOTEXT_INFO_DESTBUFFERTOSMALL))
     798             :             == 0)
     799             :     {
     800           1 :         bool bFlush = true;
     801           1 :         if (nHighSurrogate != 0)
     802             :         {
     803           0 :             if ((nFlags & RTL_UNICODETOTEXT_FLAGS_FLUSH) != 0)
     804           0 :                 nInfo |= RTL_UNICODETOTEXT_INFO_SRCBUFFERTOSMALL;
     805             :             else
     806           0 :                 switch (sal::detail::textenc::handleBadInputUnicodeToTextConversion(
     807             :                             false, 0, nFlags, &pDestBufPtr, pDestBufEnd, &nInfo,
     808           0 :                             "\x0F" /* SI */, bSo ? 1 : 0, &bWritten))
     809             :                 {
     810             :                 case sal::detail::textenc::BAD_INPUT_STOP:
     811           0 :                     nHighSurrogate = 0;
     812           0 :                     bFlush = false;
     813           0 :                     break;
     814             : 
     815             :                 case sal::detail::textenc::BAD_INPUT_CONTINUE:
     816           0 :                     if (bWritten)
     817           0 :                         bSo = false;
     818           0 :                     nHighSurrogate = 0;
     819           0 :                     break;
     820             : 
     821             :                 case sal::detail::textenc::BAD_INPUT_NO_OUTPUT:
     822           0 :                     nInfo |= RTL_UNICODETOTEXT_INFO_DESTBUFFERTOSMALL;
     823           0 :                     break;
     824             :                 }
     825             :         }
     826           1 :         if (bFlush && bSo && (nFlags & RTL_UNICODETOTEXT_FLAGS_FLUSH) != 0)
     827             :         {
     828           1 :             if (pDestBufPtr != pDestBufEnd)
     829             :             {
     830           1 :                 *pDestBufPtr++ = 0x0F; // SI
     831           1 :                 bSo = false;
     832             :             }
     833             :             else
     834           0 :                 nInfo |= RTL_UNICODETOTEXT_INFO_DESTBUFFERTOSMALL;
     835             :         }
     836             :     }
     837             : 
     838           1 :     if (pContext)
     839             :     {
     840             :         static_cast< ImplUnicodeToIso2022CnContext * >(pContext)->m_nHighSurrogate
     841           1 :             = nHighSurrogate;
     842             :         static_cast< ImplUnicodeToIso2022CnContext * >(pContext)->m_eSoDesignator
     843           1 :             = eSoDesignator;
     844             :         static_cast< ImplUnicodeToIso2022CnContext * >(pContext)->m_b116432Designator
     845           1 :             = b116432Designator;
     846           1 :         static_cast< ImplUnicodeToIso2022CnContext * >(pContext)->m_bSo = bSo;
     847             :     }
     848           1 :     if (pInfo)
     849           1 :         *pInfo = nInfo;
     850           1 :     if (pSrcCvtChars)
     851           1 :         *pSrcCvtChars = nConverted;
     852             : 
     853           1 :     return pDestBufPtr - pDestBuf;
     854             : }
     855             : 
     856             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10