| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| |
| #include "tenchelp.h" |
| #include "unichars.h" |
| #include "rtl/textcvt.h" |
| #include "sal/types.h" |
| |
| static sal_Bool ImplGetUndefinedAsciiMultiByte(sal_uInt32 nFlags, |
| sal_Char * pBuf, |
| sal_Size nMaxLen); |
| |
| static sal_Bool ImplGetInvalidAsciiMultiByte(sal_uInt32 nFlags, |
| sal_Char * pBuf, |
| sal_Size nMaxLen); |
| |
| static int ImplIsUnicodeIgnoreChar(sal_Unicode c, sal_uInt32 nFlags); |
| |
| sal_Bool ImplGetUndefinedAsciiMultiByte(sal_uInt32 nFlags, |
| sal_Char * pBuf, |
| sal_Size nMaxLen) |
| { |
| if (nMaxLen == 0) |
| return sal_False; |
| switch (nFlags & RTL_UNICODETOTEXT_FLAGS_UNDEFINED_MASK) |
| { |
| case RTL_UNICODETOTEXT_FLAGS_UNDEFINED_0: |
| *pBuf = 0x00; |
| break; |
| |
| case RTL_UNICODETOTEXT_FLAGS_UNDEFINED_QUESTIONMARK: |
| default: /* RTL_UNICODETOTEXT_FLAGS_UNDEFINED_DEFAULT */ |
| *pBuf = 0x3F; |
| break; |
| |
| case RTL_UNICODETOTEXT_FLAGS_UNDEFINED_UNDERLINE: |
| *pBuf = 0x5F; |
| break; |
| } |
| return sal_True; |
| } |
| |
| sal_Bool ImplGetInvalidAsciiMultiByte(sal_uInt32 nFlags, |
| sal_Char * pBuf, |
| sal_Size nMaxLen) |
| { |
| if (nMaxLen == 0) |
| return sal_False; |
| switch (nFlags & RTL_UNICODETOTEXT_FLAGS_UNDEFINED_MASK) |
| { |
| case RTL_UNICODETOTEXT_FLAGS_INVALID_0: |
| *pBuf = 0x00; |
| break; |
| |
| case RTL_UNICODETOTEXT_FLAGS_INVALID_QUESTIONMARK: |
| default: /* RTL_UNICODETOTEXT_FLAGS_INVALID_DEFAULT */ |
| *pBuf = 0x3F; |
| break; |
| |
| case RTL_UNICODETOTEXT_FLAGS_INVALID_UNDERLINE: |
| *pBuf = 0x5F; |
| break; |
| } |
| return sal_True; |
| } |
| |
| int ImplIsUnicodeIgnoreChar( sal_Unicode c, sal_uInt32 nFlags ) |
| { |
| return |
| ((nFlags & RTL_UNICODETOTEXT_FLAGS_NONSPACING_IGNORE) != 0 |
| && ImplIsZeroWidth(c)) |
| || ((nFlags & RTL_UNICODETOTEXT_FLAGS_CONTROL_IGNORE) != 0 |
| && ImplIsControlOrFormat(c)) |
| || ((nFlags & RTL_UNICODETOTEXT_FLAGS_PRIVATE_IGNORE) != 0 |
| && ImplIsPrivateUse(c)); |
| } |
| |
| /* ======================================================================= */ |
| |
| sal_Unicode ImplGetUndefinedUnicodeChar(sal_uChar cChar, sal_uInt32 nFlags) |
| { |
| return ((nFlags & RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_MASK) |
| == RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_MAPTOPRIVATE) ? |
| RTL_TEXTCVT_BYTE_PRIVATE_START + cChar : |
| RTL_TEXTENC_UNICODE_REPLACEMENT_CHARACTER; |
| } |
| |
| /* ----------------------------------------------------------------------- */ |
| |
| sal_Bool |
| ImplHandleUndefinedUnicodeToTextChar(ImplTextConverterData const * pData, |
| sal_Unicode const ** ppSrcBuf, |
| sal_Unicode const * pEndSrcBuf, |
| sal_Char ** ppDestBuf, |
| sal_Char const * pEndDestBuf, |
| sal_uInt32 nFlags, |
| sal_uInt32 * pInfo) |
| { |
| sal_Unicode c = **ppSrcBuf; |
| |
| (void) pData; /* unused */ |
| |
| /* Should the private character map to one byte */ |
| if ( (c >= RTL_TEXTCVT_BYTE_PRIVATE_START) && (c <= RTL_TEXTCVT_BYTE_PRIVATE_END) ) |
| { |
| if ( nFlags & RTL_UNICODETOTEXT_FLAGS_PRIVATE_MAPTO0 ) |
| { |
| **ppDestBuf = (sal_Char)(sal_uChar)(c-RTL_TEXTCVT_BYTE_PRIVATE_START); |
| (*ppDestBuf)++; |
| (*ppSrcBuf)++; |
| return sal_True; |
| } |
| } |
| |
| /* Should this character ignored (Private, Non Spacing, Control) */ |
| if ( ImplIsUnicodeIgnoreChar( c, nFlags ) ) |
| { |
| (*ppSrcBuf)++; |
| return sal_True; |
| } |
| |
| /* Surrogates Characters should result in */ |
| /* one replacement character */ |
| if (ImplIsHighSurrogate(c)) |
| { |
| if ( *ppSrcBuf == pEndSrcBuf ) |
| { |
| *pInfo |= RTL_UNICODETOTEXT_INFO_ERROR | RTL_UNICODETOTEXT_INFO_SRCBUFFERTOSMALL; |
| return sal_False; |
| } |
| |
| c = *((*ppSrcBuf)+1); |
| if (ImplIsLowSurrogate(c)) |
| (*ppSrcBuf)++; |
| else |
| { |
| *pInfo |= RTL_UNICODETOTEXT_INFO_INVALID; |
| if ( (nFlags & RTL_UNICODETOTEXT_FLAGS_INVALID_MASK) == RTL_UNICODETOTEXT_FLAGS_INVALID_ERROR ) |
| { |
| *pInfo |= RTL_UNICODETOTEXT_INFO_ERROR; |
| return sal_False; |
| } |
| else if ( (nFlags & RTL_UNICODETOTEXT_FLAGS_INVALID_MASK) == RTL_UNICODETOTEXT_FLAGS_INVALID_IGNORE ) |
| { |
| (*ppSrcBuf)++; |
| return sal_True; |
| } |
| else if (ImplGetInvalidAsciiMultiByte(nFlags, |
| *ppDestBuf, |
| pEndDestBuf - *ppDestBuf)) |
| { |
| ++*ppSrcBuf; |
| ++*ppDestBuf; |
| return sal_True; |
| } |
| else |
| { |
| *pInfo |= RTL_UNICODETOTEXT_INFO_ERROR |
| | RTL_UNICODETOTEXT_INFO_DESTBUFFERTOSMALL; |
| return sal_False; |
| } |
| } |
| } |
| |
| *pInfo |= RTL_UNICODETOTEXT_INFO_UNDEFINED; |
| if ( (nFlags & RTL_UNICODETOTEXT_FLAGS_UNDEFINED_MASK) == RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR ) |
| { |
| *pInfo |= RTL_UNICODETOTEXT_INFO_ERROR; |
| return sal_False; |
| } |
| else if ( (nFlags & RTL_UNICODETOTEXT_FLAGS_UNDEFINED_MASK) == RTL_UNICODETOTEXT_FLAGS_UNDEFINED_IGNORE ) |
| (*ppSrcBuf)++; |
| else if (ImplGetUndefinedAsciiMultiByte(nFlags, |
| *ppDestBuf, |
| pEndDestBuf - *ppDestBuf)) |
| { |
| ++*ppSrcBuf; |
| ++*ppDestBuf; |
| } |
| else |
| { |
| *pInfo |= RTL_UNICODETOTEXT_INFO_ERROR |
| | RTL_UNICODETOTEXT_INFO_DESTBUFFERTOSMALL; |
| return sal_False; |
| } |
| |
| return sal_True; |
| } |
| |