LCOV - code coverage report
Current view: top level - sal/textenc - convertiso2022cn.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 266 406 65.5 %
Date: 2014-11-03 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           8 : void * ImplCreateIso2022CnToUnicodeContext()
      72             : {
      73             :     ImplIso2022CnToUnicodeContext * pContext =
      74           8 :         new ImplIso2022CnToUnicodeContext;
      75           8 :     pContext->m_eState = IMPL_ISO_2022_CN_TO_UNICODE_STATE_ASCII;
      76           8 :     pContext->m_bSo = false;
      77           8 :     pContext->m_b116431 = false;
      78           8 :     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           8 : void ImplDestroyIso2022CnToUnicodeContext(void * pContext)
      93             : {
      94           8 :     delete static_cast< ImplIso2022CnToUnicodeContext * >(pContext);
      95           8 : }
      96             : 
      97         148 : 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         148 :               m_pGb2312ToUnicodeData;
     110             :     sal_uInt16 const * pCns116431992Data
     111             :         = static_cast< ImplIso2022CnConverterData const * >(pData)->
     112         148 :               m_pCns116431992ToUnicodeData;
     113             :     sal_Int32 const * pCns116431992RowOffsets
     114             :         = static_cast< ImplIso2022CnConverterData const * >(pData)->
     115         148 :               m_pCns116431992ToUnicodeRowOffsets;
     116             :     sal_Int32 const * pCns116431992PlaneOffsets
     117             :         = static_cast< ImplIso2022CnConverterData const * >(pData)->
     118         148 :               m_pCns116431992ToUnicodePlaneOffsets;
     119             :     ImplIso2022CnToUnicodeState eState
     120         148 :         = IMPL_ISO_2022_CN_TO_UNICODE_STATE_ASCII;
     121         148 :     sal_uInt32 nRow = 0;
     122         148 :     bool bSo = false;
     123         148 :     bool b116431 = false;
     124         148 :     sal_uInt32 nInfo = 0;
     125         148 :     sal_Size nConverted = 0;
     126         148 :     sal_Unicode * pDestBufPtr = pDestBuf;
     127         148 :     sal_Unicode * pDestBufEnd = pDestBuf + nDestChars;
     128             : 
     129         148 :     if (pContext)
     130             :     {
     131         148 :         eState = static_cast< ImplIso2022CnToUnicodeContext * >(pContext)->m_eState;
     132         148 :         nRow = static_cast< ImplIso2022CnToUnicodeContext * >(pContext)->m_nRow;
     133         148 :         bSo = static_cast< ImplIso2022CnToUnicodeContext * >(pContext)->m_bSo;
     134         148 :         b116431 = static_cast< ImplIso2022CnToUnicodeContext * >(pContext)->m_b116431;
     135             :     }
     136             : 
     137         428 :     for (; nConverted < nSrcBytes; ++nConverted)
     138             :     {
     139         280 :         bool bUndefined = true;
     140         280 :         sal_uInt32 nChar = *(unsigned char const *) pSrcBuf++;
     141             :         sal_uInt32 nPlane;
     142         280 :         switch (eState)
     143             :         {
     144             :         case IMPL_ISO_2022_CN_TO_UNICODE_STATE_ASCII:
     145         104 :             if (nChar == 0x0E) // SO
     146             :             {
     147          16 :                 bSo = true;
     148          16 :                 eState = IMPL_ISO_2022_CN_TO_UNICODE_STATE_SO;
     149             :             }
     150          88 :             else if (nChar == 0x1B) // ESC
     151          16 :                 eState = IMPL_ISO_2022_CN_TO_UNICODE_STATE_ESC;
     152          72 :             else if (nChar < 0x80)
     153          72 :                 if (pDestBufPtr != pDestBufEnd)
     154          72 :                     *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         104 :             break;
     163             : 
     164             :         case IMPL_ISO_2022_CN_TO_UNICODE_STATE_SO:
     165          56 :             if (nChar == 0x0F) // SI
     166             :             {
     167          16 :                 bSo = false;
     168          16 :                 eState = IMPL_ISO_2022_CN_TO_UNICODE_STATE_ASCII;
     169             :             }
     170          40 :             else if (nChar == 0x1B) // ESC
     171          16 :                 eState = IMPL_ISO_2022_CN_TO_UNICODE_STATE_ESC;
     172          24 :             else if (nChar >= 0x21 && nChar <= 0x7E)
     173             :             {
     174          24 :                 nRow = nChar;
     175          24 :                 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          56 :             break;
     183             : 
     184             :         case IMPL_ISO_2022_CN_TO_UNICODE_STATE_SO_2:
     185          24 :             if (nChar >= 0x21 && nChar <= 0x7E)
     186          24 :                 if (b116431)
     187             :                 {
     188           8 :                     nPlane = 0;
     189           8 :                     goto transform;
     190             :                 }
     191             :                 else
     192             :                 {
     193          16 :                     sal_uInt16 nUnicode = 0;
     194             :                     sal_uInt32 nFirst;
     195          16 :                     nRow += 0x80;
     196          16 :                     nChar += 0x80;
     197          16 :                     nFirst = pGb2312Data[nRow].mnTrailStart;
     198          16 :                     if (nChar >= nFirst
     199          16 :                         && nChar <= pGb2312Data[nRow].mnTrailEnd)
     200          16 :                         nUnicode = pGb2312Data[nRow].
     201          16 :                                        mpToUniTrailTab[nChar - nFirst];
     202          16 :                     if (nUnicode != 0)
     203          16 :                         if (pDestBufPtr != pDestBufEnd)
     204             :                         {
     205          16 :                             *pDestBufPtr++ = (sal_Unicode) nUnicode;
     206          16 :                             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          16 :                 }
     213             :             else
     214             :             {
     215           0 :                 bUndefined = false;
     216           0 :                 goto bad_input;
     217             :             }
     218          16 :             break;
     219             : 
     220             :         case IMPL_ISO_2022_CN_TO_UNICODE_STATE_116432:
     221           8 :             if (nChar >= 0x21 && nChar <= 0x7E)
     222             :             {
     223           8 :                 nRow = nChar;
     224           8 :                 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           8 :             break;
     232             : 
     233             :         case IMPL_ISO_2022_CN_TO_UNICODE_STATE_116432_2:
     234           8 :             if (nChar >= 0x21 && nChar <= 0x7E)
     235             :             {
     236           8 :                 nPlane = 1;
     237           8 :                 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          32 :             if (nChar == 0x24) // $
     248          24 :                 eState = IMPL_ISO_2022_CN_TO_UNICODE_STATE_ESC_DOLLAR;
     249           8 :             else if (nChar == 0x4E) // N
     250           8 :                 eState = IMPL_ISO_2022_CN_TO_UNICODE_STATE_116432;
     251             :             else
     252             :             {
     253           0 :                 bUndefined = false;
     254           0 :                 goto bad_input;
     255             :             }
     256          32 :             break;
     257             : 
     258             :         case IMPL_ISO_2022_CN_TO_UNICODE_STATE_ESC_DOLLAR:
     259          24 :             if (nChar == 0x29) // )
     260          16 :                 eState = IMPL_ISO_2022_CN_TO_UNICODE_STATE_ESC_DOLLAR_RPAREN;
     261           8 :             else if (nChar == 0x2A) // *
     262             :                 eState
     263           8 :                     = IMPL_ISO_2022_CN_TO_UNICODE_STATE_ESC_DOLLAR_ASTERISK;
     264             :             else
     265             :             {
     266           0 :                 bUndefined = false;
     267           0 :                 goto bad_input;
     268             :             }
     269          24 :             break;
     270             : 
     271             :         case IMPL_ISO_2022_CN_TO_UNICODE_STATE_ESC_DOLLAR_RPAREN:
     272          16 :             if (nChar == 0x41) // A
     273             :             {
     274          12 :                 b116431 = false;
     275             :                 eState = bSo ? IMPL_ISO_2022_CN_TO_UNICODE_STATE_SO :
     276          12 :                                IMPL_ISO_2022_CN_TO_UNICODE_STATE_ASCII;
     277             :             }
     278           4 :             else if (nChar == 0x47) // G
     279             :             {
     280           4 :                 b116431 = true;
     281             :                 eState = bSo ? IMPL_ISO_2022_CN_TO_UNICODE_STATE_SO :
     282           4 :                                IMPL_ISO_2022_CN_TO_UNICODE_STATE_ASCII;
     283             :             }
     284             :             else
     285             :             {
     286           0 :                 bUndefined = false;
     287           0 :                 goto bad_input;
     288             :             }
     289          16 :             break;
     290             : 
     291             :         case IMPL_ISO_2022_CN_TO_UNICODE_STATE_ESC_DOLLAR_ASTERISK:
     292           8 :             if (nChar == 0x48) // H
     293             :                 eState = bSo ? IMPL_ISO_2022_CN_TO_UNICODE_STATE_SO :
     294           8 :                                IMPL_ISO_2022_CN_TO_UNICODE_STATE_ASCII;
     295             :             else
     296             :             {
     297           0 :                 bUndefined = false;
     298           0 :                 goto bad_input;
     299             :             }
     300           8 :             break;
     301             :         }
     302         264 :         continue;
     303             : 
     304             :     transform:
     305             :         {
     306          16 :             sal_Int32 nPlaneOffset = pCns116431992PlaneOffsets[nPlane];
     307          16 :             if (nPlaneOffset == -1)
     308           0 :                 goto bad_input;
     309             :             else
     310             :             {
     311             :                 sal_Int32 nOffset
     312          16 :                     = pCns116431992RowOffsets[nPlaneOffset + (nRow - 0x21)];
     313          16 :                 if (nOffset == -1)
     314           0 :                     goto bad_input;
     315             :                 else
     316             :                 {
     317          16 :                     sal_uInt32 nFirstLast = pCns116431992Data[nOffset++];
     318          16 :                     sal_uInt32 nFirst = nFirstLast & 0xFF;
     319          16 :                     sal_uInt32 nLast = nFirstLast >> 8;
     320          16 :                     nChar -= 0x20;
     321          16 :                     if (nChar >= nFirst && nChar <= nLast)
     322             :                     {
     323             :                         sal_uInt32 nUnicode
     324          16 :                             = pCns116431992Data[nOffset + (nChar - nFirst)];
     325          16 :                         if (nUnicode == 0xFFFF)
     326           0 :                             goto bad_input;
     327          16 :                         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          16 :                             if (pDestBufPtr != pDestBufEnd)
     342          16 :                                 *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          16 :                                    IMPL_ISO_2022_CN_TO_UNICODE_STATE_ASCII;
     350             :                 }
     351             :             }
     352          16 :             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         148 :     if (eState > IMPL_ISO_2022_CN_TO_UNICODE_STATE_SO
     382          60 :         && (nInfo & (RTL_TEXTTOUNICODE_INFO_ERROR
     383             :                          | RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOSMALL))
     384             :                == 0)
     385             :     {
     386          60 :         if ((nFlags & RTL_TEXTTOUNICODE_FLAGS_FLUSH) == 0)
     387          60 :             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         148 :     if (pContext)
     406             :     {
     407         148 :         static_cast< ImplIso2022CnToUnicodeContext * >(pContext)->m_eState = eState;
     408         148 :         static_cast< ImplIso2022CnToUnicodeContext * >(pContext)->m_nRow = nRow;
     409         148 :         static_cast< ImplIso2022CnToUnicodeContext * >(pContext)->m_bSo = bSo;
     410         148 :         static_cast< ImplIso2022CnToUnicodeContext * >(pContext)->m_b116431 = b116431;
     411             :     }
     412         148 :     if (pInfo)
     413         148 :         *pInfo = nInfo;
     414         148 :     if (pSrcCvtBytes)
     415         148 :         *pSrcCvtBytes = nConverted;
     416             : 
     417         148 :     return pDestBufPtr - pDestBuf;
     418             : }
     419             : 
     420           2 : void * ImplCreateUnicodeToIso2022CnContext(void)
     421             : {
     422             :     ImplUnicodeToIso2022CnContext * pContext =
     423           2 :         new ImplUnicodeToIso2022CnContext;
     424           2 :     pContext->m_nHighSurrogate = 0;
     425           2 :     pContext->m_eSoDesignator = IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_NONE;
     426           2 :     pContext->m_b116432Designator = false;
     427           2 :     pContext->m_bSo = false;
     428           2 :     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           2 : void ImplDestroyUnicodeToIso2022CnContext(void * pContext)
     445             : {
     446           2 :     delete static_cast< ImplUnicodeToIso2022CnContext * >(pContext);
     447           2 : }
     448             : 
     449           8 : static sal_uInt32 ImplIso2022CnTranslateTo2312(ImplUniToDBCSHighTab const *
     450             :                                                    pGb2312Data,
     451             :                                                sal_uInt32 nChar)
     452             : {
     453           8 :     sal_uInt32 nIndex1 = nChar >> 8;
     454           8 :     if (nIndex1 < 0x100)
     455             :     {
     456           8 :         sal_uInt32 nIndex2 = nChar & 0xFF;
     457           8 :         sal_uInt32 nFirst = pGb2312Data[nIndex1].mnLowStart;
     458           8 :         if (nIndex2 >= nFirst && nIndex2 <= pGb2312Data[nIndex1].mnLowEnd)
     459           8 :             return pGb2312Data[nIndex1].mpToUniTrailTab[nIndex2 - nFirst]
     460           8 :                        & 0x7F7F;
     461             :     }
     462           0 :     return 0;
     463             : }
     464             : 
     465             : static sal_uInt32
     466           2 : ImplIso2022CnTranslateTo116431(sal_uInt8 const * pCns116431992Data,
     467             :                                sal_Int32 const * pCns116431992PageOffsets,
     468             :                                sal_Int32 const * pCns116431992PlaneOffsets,
     469             :                                sal_uInt32 nChar)
     470             : {
     471           2 :     sal_Int32 nOffset = pCns116431992PlaneOffsets[nChar >> 16];
     472             :     sal_uInt32 nFirst;
     473             :     sal_uInt32 nLast;
     474             :     sal_uInt32 nPlane;
     475           2 :     if (nOffset == -1)
     476           0 :         return 0;
     477           2 :     nOffset = pCns116431992PageOffsets[nOffset + ((nChar & 0xFF00) >> 8)];
     478           2 :     if (nOffset == -1)
     479           0 :         return 0;
     480           2 :     nFirst = pCns116431992Data[nOffset++];
     481           2 :     nLast = pCns116431992Data[nOffset++];
     482           2 :     nChar &= 0xFF;
     483           2 :     if (nChar < nFirst || nChar > nLast)
     484           0 :         return 0;
     485           2 :     nOffset += 3 * (nChar - nFirst);
     486           2 :     nPlane = pCns116431992Data[nOffset++];
     487           2 :     if (nPlane != 1)
     488           2 :         return 0;
     489           0 :     return (0x20 + pCns116431992Data[nOffset]) << 8
     490           0 :                | (0x20 + pCns116431992Data[nOffset + 1]);
     491             : }
     492             : 
     493           2 : 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           2 :               m_pUnicodeToGb2312Data;
     506             :     sal_uInt8 const * pCns116431992Data
     507             :         = static_cast< ImplIso2022CnConverterData const * >(pData)->
     508           2 :               m_pUnicodeToCns116431992Data;
     509             :     sal_Int32 const * pCns116431992PageOffsets
     510             :         = static_cast< ImplIso2022CnConverterData const * >(pData)->
     511           2 :               m_pUnicodeToCns116431992PageOffsets;
     512             :     sal_Int32 const * pCns116431992PlaneOffsets
     513             :         = static_cast< ImplIso2022CnConverterData const * >(pData)->
     514           2 :               m_pUnicodeToCns116431992PlaneOffsets;
     515           2 :     sal_Unicode nHighSurrogate = 0;
     516             :     ImplUnicodeToIso2022CnDesignator eSoDesignator
     517           2 :         = IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_NONE;
     518           2 :     bool b116432Designator = false;
     519           2 :     bool bSo = false;
     520           2 :     sal_uInt32 nInfo = 0;
     521           2 :     sal_Size nConverted = 0;
     522           2 :     char * pDestBufPtr = pDestBuf;
     523           2 :     char * pDestBufEnd = pDestBuf + nDestBytes;
     524             :     bool bWritten;
     525             : 
     526           2 :     if (pContext)
     527             :     {
     528             :         nHighSurrogate
     529           2 :             = static_cast< ImplUnicodeToIso2022CnContext * >(pContext)->m_nHighSurrogate;
     530             :         eSoDesignator
     531           2 :             = static_cast< ImplUnicodeToIso2022CnContext * >(pContext)->m_eSoDesignator;
     532             :         b116432Designator = static_cast< ImplUnicodeToIso2022CnContext * >(pContext)->
     533           2 :                                 m_b116432Designator;
     534           2 :         bSo = static_cast< ImplUnicodeToIso2022CnContext * >(pContext)->m_bSo;
     535             :     }
     536             : 
     537          30 :     for (; nConverted < nSrcChars; ++nConverted)
     538             :     {
     539          28 :         bool bUndefined = true;
     540          28 :         sal_uInt32 nChar = *pSrcBuf++;
     541          28 :         if (nHighSurrogate == 0)
     542             :         {
     543          28 :             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          28 :         if (ImplIsLowSurrogate(nChar) || ImplIsNoncharacter(nChar))
     558             :         {
     559           0 :             bUndefined = false;
     560           0 :             goto bad_input;
     561             :         }
     562             : 
     563          28 :         if (nChar == 0x0A || nChar == 0x0D) // LF, CR
     564             :         {
     565           4 :             if (bSo)
     566             :             {
     567           2 :                 if (pDestBufPtr != pDestBufEnd)
     568             :                 {
     569           2 :                     *pDestBufPtr++ = 0x0F; // SI
     570           2 :                     bSo = false;
     571             :                     eSoDesignator
     572           2 :                         = IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_NONE;
     573           2 :                     b116432Designator = false;
     574             :                 }
     575             :                 else
     576           0 :                     goto no_output;
     577             :             }
     578           8 :             if (pDestBufPtr != pDestBufEnd)
     579           4 :                 *pDestBufPtr++ = static_cast< char >(nChar);
     580             :             else
     581           0 :                 goto no_output;
     582             :         }
     583          24 :         else if (nChar == 0x0E || nChar == 0x0F || nChar == 0x1B)
     584             :             goto bad_input;
     585          24 :         else if (nChar < 0x80)
     586             :         {
     587          16 :             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          16 :             if (pDestBufPtr != pDestBufEnd)
     598          16 :                 *pDestBufPtr++ = static_cast< char >(nChar);
     599             :             else
     600           0 :                 goto no_output;
     601             :         }
     602             :         else
     603             :         {
     604           8 :             sal_uInt32 nBytes = 0;
     605             :             ImplUnicodeToIso2022CnDesignator eNewDesignator =
     606           8 :                          IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_NONE;
     607           8 :             switch (eSoDesignator)
     608             :             {
     609             :             case IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_NONE:
     610           4 :                 nBytes = ImplIso2022CnTranslateTo2312(pGb2312Data, nChar);
     611           4 :                 if (nBytes != 0)
     612             :                 {
     613             :                     eNewDesignator
     614           4 :                         = IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_2312;
     615           4 :                     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           4 :                 nBytes = ImplIso2022CnTranslateTo2312(pGb2312Data, nChar);
     632           4 :                 if (nBytes != 0)
     633             :                 {
     634             :                     eNewDesignator
     635           2 :                         = IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_NONE;
     636           2 :                     break;
     637             :                 }
     638             :                 nBytes = ImplIso2022CnTranslateTo116431(
     639             :                              pCns116431992Data,
     640             :                              pCns116431992PageOffsets,
     641             :                              pCns116431992PlaneOffsets,
     642           2 :                              nChar);
     643           2 :                 if (nBytes != 0)
     644             :                 {
     645             :                     eNewDesignator
     646           0 :                         = IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_116431;
     647           0 :                     break;
     648             :                 }
     649           2 :                 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           8 :             if (nBytes != 0)
     673             :             {
     674           6 :                 if (eNewDesignator
     675             :                         != IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_NONE)
     676             :                 {
     677           4 :                     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           4 :                     if (pDestBufEnd - pDestBufPtr >= 4)
     688             :                     {
     689           4 :                         *pDestBufPtr++ = 0x1B; // ESC
     690           4 :                         *pDestBufPtr++ = 0x24; // $
     691           4 :                         *pDestBufPtr++ = 0x29; // )
     692             :                         *pDestBufPtr++
     693             :                             = eNewDesignator
     694             :                               == IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_2312 ?
     695           4 :                                   0x41 : 0x47; // A, G
     696           4 :                         eSoDesignator = eNewDesignator;
     697             :                     }
     698             :                     else
     699           0 :                         goto no_output;
     700             :                 }
     701           6 :                 if (!bSo)
     702             :                 {
     703           4 :                     if (pDestBufPtr != pDestBufEnd)
     704             :                     {
     705           4 :                         *pDestBufPtr++ = 0x0E; // SO
     706           4 :                         bSo = true;
     707             :                     }
     708             :                     else
     709           0 :                         goto no_output;
     710             :                 }
     711           6 :                 if (pDestBufEnd - pDestBufPtr >= 4)
     712             :                 {
     713           6 :                     *pDestBufPtr++ = static_cast< char >(nBytes >> 8);
     714           6 :                     *pDestBufPtr++ = static_cast< char >(nBytes & 0xFF);
     715             :                 }
     716             :                 else
     717           0 :                     goto no_output;
     718             :             }
     719             :             else
     720             :             {
     721           2 :                 sal_Int32 nOffset = pCns116431992PlaneOffsets[nChar >> 16];
     722             :                 sal_uInt32 nFirst;
     723             :                 sal_uInt32 nLast;
     724             :                 sal_uInt32 nPlane;
     725           2 :                 if (nOffset == -1)
     726           0 :                     goto bad_input;
     727             :                 nOffset
     728             :                     = pCns116431992PageOffsets[nOffset
     729           2 :                                                    + ((nChar & 0xFF00) >> 8)];
     730           2 :                 if (nOffset == -1)
     731           0 :                     goto bad_input;
     732           2 :                 nFirst = pCns116431992Data[nOffset++];
     733           2 :                 nLast = pCns116431992Data[nOffset++];
     734           2 :                 nChar &= 0xFF;
     735           2 :                 if (nChar < nFirst || nChar > nLast)
     736             :                     goto bad_input;
     737           2 :                 nOffset += 3 * (nChar - nFirst);
     738           2 :                 nPlane = pCns116431992Data[nOffset++];
     739           2 :                 if (nPlane != 2)
     740           0 :                     goto bad_input;
     741           2 :                 if (!b116432Designator)
     742             :                 {
     743           2 :                     if (pDestBufEnd - pDestBufPtr >= 4)
     744             :                     {
     745           2 :                         *pDestBufPtr++ = 0x1B; // ESC
     746           2 :                         *pDestBufPtr++ = 0x24; // $
     747           2 :                         *pDestBufPtr++ = 0x2A; // *
     748           2 :                         *pDestBufPtr++ = 0x48; // H
     749           2 :                         b116432Designator = true;
     750             :                     }
     751             :                     else
     752           0 :                         goto no_output;
     753             :                 }
     754           2 :                 if (pDestBufEnd - pDestBufPtr >= 4)
     755             :                 {
     756           2 :                     *pDestBufPtr++ = 0x1B; // ESC
     757           2 :                     *pDestBufPtr++ = 0x4E; // N
     758             :                     *pDestBufPtr++
     759           2 :                         = static_cast< char >(0x20 + pCns116431992Data[nOffset++]);
     760             :                     *pDestBufPtr++
     761           2 :                         = static_cast< char >(0x20 + pCns116431992Data[nOffset]);
     762             :                 }
     763             :                 else
     764           0 :                     goto no_output;
     765             :             }
     766             :         }
     767          28 :         nHighSurrogate = 0;
     768          28 :         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           2 :     if ((nInfo & (RTL_UNICODETOTEXT_INFO_ERROR
     797             :                       | RTL_UNICODETOTEXT_INFO_DESTBUFFERTOSMALL))
     798             :             == 0)
     799             :     {
     800           2 :         bool bFlush = true;
     801           2 :         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           2 :         if (bFlush && bSo && (nFlags & RTL_UNICODETOTEXT_FLAGS_FLUSH) != 0)
     827             :         {
     828           2 :             if (pDestBufPtr != pDestBufEnd)
     829             :             {
     830           2 :                 *pDestBufPtr++ = 0x0F; // SI
     831           2 :                 bSo = false;
     832             :             }
     833             :             else
     834           0 :                 nInfo |= RTL_UNICODETOTEXT_INFO_DESTBUFFERTOSMALL;
     835             :         }
     836             :     }
     837             : 
     838           2 :     if (pContext)
     839             :     {
     840             :         static_cast< ImplUnicodeToIso2022CnContext * >(pContext)->m_nHighSurrogate
     841           2 :             = nHighSurrogate;
     842             :         static_cast< ImplUnicodeToIso2022CnContext * >(pContext)->m_eSoDesignator
     843           2 :             = eSoDesignator;
     844             :         static_cast< ImplUnicodeToIso2022CnContext * >(pContext)->m_b116432Designator
     845           2 :             = b116432Designator;
     846           2 :         static_cast< ImplUnicodeToIso2022CnContext * >(pContext)->m_bSo = bSo;
     847             :     }
     848           2 :     if (pInfo)
     849           2 :         *pInfo = nInfo;
     850           2 :     if (pSrcCvtChars)
     851           2 :         *pSrcCvtChars = nConverted;
     852             : 
     853           2 :     return pDestBufPtr - pDestBuf;
     854             : }
     855             : 
     856             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10