in main/sal/textenc/convertiso2022cn.c [484:858]
sal_Size ImplConvertUnicodeToIso2022Cn(ImplTextConverterData const * pData,
void * pContext,
sal_Unicode const * pSrcBuf,
sal_Size nSrcChars,
sal_Char * pDestBuf,
sal_Size nDestBytes,
sal_uInt32 nFlags,
sal_uInt32 * pInfo,
sal_Size * pSrcCvtChars)
{
ImplUniToDBCSHighTab const * pGb2312Data
= ((ImplIso2022CnConverterData const *) pData)->
m_pUnicodeToGb2312Data;
sal_uInt8 const * pCns116431992Data
= ((ImplIso2022CnConverterData const *) pData)->
m_pUnicodeToCns116431992Data;
sal_Int32 const * pCns116431992PageOffsets
= ((ImplIso2022CnConverterData const *) pData)->
m_pUnicodeToCns116431992PageOffsets;
sal_Int32 const * pCns116431992PlaneOffsets
= ((ImplIso2022CnConverterData const *) pData)->
m_pUnicodeToCns116431992PlaneOffsets;
sal_Unicode nHighSurrogate = 0;
ImplUnicodeToIso2022CnDesignator eSoDesignator
= IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_NONE;
sal_Bool b116432Designator = sal_False;
sal_Bool bSo = sal_False;
sal_uInt32 nInfo = 0;
sal_Size nConverted = 0;
sal_Char * pDestBufPtr = pDestBuf;
sal_Char * pDestBufEnd = pDestBuf + nDestBytes;
sal_Bool bWritten;
if (pContext)
{
nHighSurrogate
= ((ImplUnicodeToIso2022CnContext *) pContext)->m_nHighSurrogate;
eSoDesignator
= ((ImplUnicodeToIso2022CnContext *) pContext)->m_eSoDesignator;
b116432Designator = ((ImplUnicodeToIso2022CnContext *) pContext)->
m_b116432Designator;
bSo = ((ImplUnicodeToIso2022CnContext *) pContext)->m_bSo;
}
for (; nConverted < nSrcChars; ++nConverted)
{
sal_Bool bUndefined = sal_True;
sal_uInt32 nChar = *pSrcBuf++;
if (nHighSurrogate == 0)
{
if (ImplIsHighSurrogate(nChar))
{
nHighSurrogate = (sal_Unicode) nChar;
continue;
}
}
else if (ImplIsLowSurrogate(nChar))
nChar = ImplCombineSurrogates(nHighSurrogate, nChar);
else
{
bUndefined = sal_False;
goto bad_input;
}
if (ImplIsLowSurrogate(nChar) || ImplIsNoncharacter(nChar))
{
bUndefined = sal_False;
goto bad_input;
}
if (nChar == 0x0A || nChar == 0x0D) /* LF, CR */
{
if (bSo)
{
if (pDestBufPtr != pDestBufEnd)
{
*pDestBufPtr++ = 0x0F; /* SI */
bSo = sal_False;
eSoDesignator
= IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_NONE;
b116432Designator = sal_False;
}
else
goto no_output;
}
if (pDestBufPtr != pDestBufEnd)
*pDestBufPtr++ = (sal_Char) nChar;
else
goto no_output;
}
else if (nChar == 0x0E || nChar == 0x0F || nChar == 0x1B)
goto bad_input;
else if (nChar < 0x80)
{
if (bSo)
{
if (pDestBufPtr != pDestBufEnd)
{
*pDestBufPtr++ = 0x0F; /* SI */
bSo = sal_False;
}
else
goto no_output;
}
if (pDestBufPtr != pDestBufEnd)
*pDestBufPtr++ = (sal_Char) nChar;
else
goto no_output;
}
else
{
sal_uInt32 nBytes = 0;
ImplUnicodeToIso2022CnDesignator eNewDesignator =
IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_NONE;
switch (eSoDesignator)
{
case IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_NONE:
nBytes = ImplIso2022CnTranslateTo2312(pGb2312Data, nChar);
if (nBytes != 0)
{
eNewDesignator
= IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_2312;
break;
}
nBytes = ImplIso2022CnTranslateTo116431(
pCns116431992Data,
pCns116431992PageOffsets,
pCns116431992PlaneOffsets,
nChar);
if (nBytes != 0)
{
eNewDesignator
= IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_116431;
break;
}
break;
case IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_2312:
nBytes = ImplIso2022CnTranslateTo2312(pGb2312Data, nChar);
if (nBytes != 0)
{
eNewDesignator
= IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_NONE;
break;
}
nBytes = ImplIso2022CnTranslateTo116431(
pCns116431992Data,
pCns116431992PageOffsets,
pCns116431992PlaneOffsets,
nChar);
if (nBytes != 0)
{
eNewDesignator
= IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_116431;
break;
}
break;
case IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_116431:
nBytes = ImplIso2022CnTranslateTo116431(
pCns116431992Data,
pCns116431992PageOffsets,
pCns116431992PlaneOffsets,
nChar);
if (nBytes != 0)
{
eNewDesignator
= IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_NONE;
break;
}
nBytes = ImplIso2022CnTranslateTo2312(pGb2312Data, nChar);
if (nBytes != 0)
{
eNewDesignator
= IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_2312;
break;
}
break;
}
if (nBytes != 0)
{
if (eNewDesignator
!= IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_NONE)
{
if (bSo)
{
if (pDestBufPtr != pDestBufEnd)
{
*pDestBufPtr++ = 0x0F; /* SI */
bSo = sal_False;
}
else
goto no_output;
}
if (pDestBufEnd - pDestBufPtr >= 4)
{
*pDestBufPtr++ = 0x1B; /* ESC */
*pDestBufPtr++ = 0x24; /* $ */
*pDestBufPtr++ = 0x29; /* ) */
*pDestBufPtr++
= eNewDesignator
== IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_2312 ?
0x41 : 0x47; /* A, G */
eSoDesignator = eNewDesignator;
}
else
goto no_output;
}
if (!bSo)
{
if (pDestBufPtr != pDestBufEnd)
{
*pDestBufPtr++ = 0x0E; /* SO */
bSo = sal_True;
}
else
goto no_output;
}
if (pDestBufEnd - pDestBufPtr >= 4)
{
*pDestBufPtr++ = (sal_Char) (nBytes >> 8);
*pDestBufPtr++ = (sal_Char) (nBytes & 0xFF);
}
else
goto no_output;
}
else
{
sal_Int32 nOffset = pCns116431992PlaneOffsets[nChar >> 16];
sal_uInt32 nFirst;
sal_uInt32 nLast;
sal_uInt32 nPlane;
if (nOffset == -1)
goto bad_input;
nOffset
= pCns116431992PageOffsets[nOffset
+ ((nChar & 0xFF00) >> 8)];
if (nOffset == -1)
goto bad_input;
nFirst = pCns116431992Data[nOffset++];
nLast = pCns116431992Data[nOffset++];
nChar &= 0xFF;
if (nChar < nFirst || nChar > nLast)
goto bad_input;
nOffset += 3 * (nChar - nFirst);
nPlane = pCns116431992Data[nOffset++];
if (nPlane != 2)
goto bad_input;
if (!b116432Designator)
{
if (pDestBufEnd - pDestBufPtr >= 4)
{
*pDestBufPtr++ = 0x1B; /* ESC */
*pDestBufPtr++ = 0x24; /* $ */
*pDestBufPtr++ = 0x2A; /* * */
*pDestBufPtr++ = 0x48; /* H */
b116432Designator = sal_True;
}
else
goto no_output;
}
if (pDestBufEnd - pDestBufPtr >= 4)
{
*pDestBufPtr++ = 0x1B; /* ESC */
*pDestBufPtr++ = 0x4E; /* N */
*pDestBufPtr++
= (sal_Char) (0x20 + pCns116431992Data[nOffset++]);
*pDestBufPtr++
= (sal_Char) (0x20 + pCns116431992Data[nOffset]);
}
else
goto no_output;
}
}
nHighSurrogate = 0;
continue;
bad_input:
switch (ImplHandleBadInputUnicodeToTextConversion(bUndefined,
nChar,
nFlags,
&pDestBufPtr,
pDestBufEnd,
&nInfo,
"\x0F", /* SI */
bSo ? 1 : 0,
&bWritten))
{
case IMPL_BAD_INPUT_STOP:
nHighSurrogate = 0;
break;
case IMPL_BAD_INPUT_CONTINUE:
if (bWritten)
bSo = sal_False;
nHighSurrogate = 0;
continue;
case IMPL_BAD_INPUT_NO_OUTPUT:
goto no_output;
}
break;
no_output:
--pSrcBuf;
nInfo |= RTL_UNICODETOTEXT_INFO_DESTBUFFERTOSMALL;
break;
}
if ((nInfo & (RTL_UNICODETOTEXT_INFO_ERROR
| RTL_UNICODETOTEXT_INFO_DESTBUFFERTOSMALL))
== 0)
{
sal_Bool bFlush = sal_True;
if (nHighSurrogate != 0)
{
if ((nFlags & RTL_UNICODETOTEXT_FLAGS_FLUSH) != 0)
nInfo |= RTL_UNICODETOTEXT_INFO_SRCBUFFERTOSMALL;
else
switch (ImplHandleBadInputUnicodeToTextConversion(
sal_False,
0,
nFlags,
&pDestBufPtr,
pDestBufEnd,
&nInfo,
"\x0F", /* SI */
bSo ? 1 : 0,
&bWritten))
{
case IMPL_BAD_INPUT_STOP:
nHighSurrogate = 0;
bFlush = sal_False;
break;
case IMPL_BAD_INPUT_CONTINUE:
if (bWritten)
bSo = sal_False;
nHighSurrogate = 0;
break;
case IMPL_BAD_INPUT_NO_OUTPUT:
nInfo |= RTL_UNICODETOTEXT_INFO_DESTBUFFERTOSMALL;
break;
}
}
if (bFlush && bSo && (nFlags & RTL_UNICODETOTEXT_FLAGS_FLUSH) != 0)
{
if (pDestBufPtr != pDestBufEnd)
{
*pDestBufPtr++ = 0x0F; /* SI */
bSo = sal_False;
}
else
nInfo |= RTL_UNICODETOTEXT_INFO_DESTBUFFERTOSMALL;
}
}
if (pContext)
{
((ImplUnicodeToIso2022CnContext *) pContext)->m_nHighSurrogate
= nHighSurrogate;
((ImplUnicodeToIso2022CnContext *) pContext)->m_eSoDesignator
= eSoDesignator;
((ImplUnicodeToIso2022CnContext *) pContext)->m_b116432Designator
= b116432Designator;
((ImplUnicodeToIso2022CnContext *) pContext)->m_bSo = bSo;
}
if (pInfo)
*pInfo = nInfo;
if (pSrcCvtChars)
*pSrcCvtChars = nConverted;
return pDestBufPtr - pDestBuf;
}