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

Generated by: LCOV version 1.11