1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 #include "rtl/textcvt.h" 29 #include "gettextencodingdata.h" 30 #include "tenchelp.h" 31 32 /* ======================================================================= */ 33 34 static sal_Size ImplDummyToUnicode( const sal_Char* pSrcBuf, sal_Size nSrcBytes, 35 sal_Unicode* pDestBuf, sal_Size nDestChars, 36 sal_uInt32 nFlags, sal_uInt32* pInfo, 37 sal_Size* pSrcCvtBytes ) 38 { 39 sal_Unicode* pEndDestBuf; 40 const sal_Char* pEndSrcBuf; 41 42 if ( ((nFlags & RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_MASK) == RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_ERROR) || 43 ((nFlags & RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_MASK) == RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_ERROR) ) 44 { 45 *pInfo |= RTL_TEXTTOUNICODE_INFO_ERROR | 46 RTL_TEXTTOUNICODE_INFO_UNDEFINED | 47 RTL_TEXTTOUNICODE_INFO_MBUNDEFINED; 48 return 0; 49 } 50 51 *pInfo = 0; 52 pEndDestBuf = pDestBuf+nDestChars; 53 pEndSrcBuf = pSrcBuf+nSrcBytes; 54 while ( pSrcBuf < pEndSrcBuf ) 55 { 56 if ( pDestBuf == pEndDestBuf ) 57 { 58 *pInfo |= RTL_TEXTTOUNICODE_INFO_ERROR | RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOSMALL; 59 break; 60 } 61 62 *pDestBuf = (sal_Unicode)(sal_uChar)*pSrcBuf; 63 pDestBuf++; 64 pSrcBuf++; 65 } 66 67 *pSrcCvtBytes = nSrcBytes - (pEndSrcBuf-pSrcBuf); 68 return (nDestChars - (pEndDestBuf-pDestBuf)); 69 } 70 71 /* ----------------------------------------------------------------------- */ 72 73 static sal_Size ImplUnicodeToDummy( const sal_Unicode* pSrcBuf, sal_Size nSrcChars, 74 sal_Char* pDestBuf, sal_Size nDestBytes, 75 sal_uInt32 nFlags, sal_uInt32* pInfo, 76 sal_Size* pSrcCvtChars ) 77 { 78 sal_Char* pEndDestBuf; 79 const sal_Unicode* pEndSrcBuf; 80 81 if ( ((nFlags & RTL_UNICODETOTEXT_FLAGS_UNDEFINED_MASK) == RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR) ) 82 { 83 *pInfo |= RTL_UNICODETOTEXT_INFO_ERROR | 84 RTL_UNICODETOTEXT_INFO_UNDEFINED; 85 return 0; 86 } 87 88 *pInfo = 0; 89 pEndDestBuf = pDestBuf+nDestBytes; 90 pEndSrcBuf = pSrcBuf+nSrcChars; 91 while ( pSrcBuf < pEndSrcBuf ) 92 { 93 if ( pDestBuf == pEndDestBuf ) 94 { 95 *pInfo |= RTL_UNICODETOTEXT_INFO_ERROR | RTL_UNICODETOTEXT_INFO_DESTBUFFERTOSMALL; 96 break; 97 } 98 99 *pDestBuf = (sal_Char)(sal_uChar)(*pSrcBuf & 0x00FF); 100 pDestBuf++; 101 pSrcBuf++; 102 } 103 104 *pSrcCvtChars = nSrcChars - (pEndSrcBuf-pSrcBuf); 105 return (nDestBytes - (pEndDestBuf-pDestBuf)); 106 } 107 108 /* ======================================================================= */ 109 110 rtl_TextToUnicodeConverter SAL_CALL rtl_createTextToUnicodeConverter( rtl_TextEncoding eTextEncoding ) 111 { 112 const ImplTextEncodingData* pData = Impl_getTextEncodingData( eTextEncoding ); 113 if ( pData ) 114 return (rtl_TextToUnicodeConverter) &pData->maConverter; 115 else 116 return 0; 117 } 118 119 /* ----------------------------------------------------------------------- */ 120 121 void SAL_CALL rtl_destroyTextToUnicodeConverter( rtl_TextToUnicodeConverter hContext ) 122 { 123 (void) hContext; /* unused */ 124 } 125 126 /* ----------------------------------------------------------------------- */ 127 128 rtl_TextToUnicodeContext SAL_CALL rtl_createTextToUnicodeContext( rtl_TextToUnicodeConverter hConverter ) 129 { 130 const ImplTextConverter* pConverter = (const ImplTextConverter*)hConverter; 131 if ( !pConverter ) 132 return 0; 133 else if ( pConverter->mpCreateTextToUnicodeContext ) 134 return (rtl_TextToUnicodeContext)pConverter->mpCreateTextToUnicodeContext(); 135 else 136 return (rtl_TextToUnicodeContext)1; 137 } 138 139 /* ----------------------------------------------------------------------- */ 140 141 void SAL_CALL rtl_destroyTextToUnicodeContext( rtl_TextToUnicodeConverter hConverter, 142 rtl_TextToUnicodeContext hContext ) 143 { 144 const ImplTextConverter* pConverter = (const ImplTextConverter*)hConverter; 145 if ( pConverter && hContext && pConverter->mpDestroyTextToUnicodeContext ) 146 pConverter->mpDestroyTextToUnicodeContext( (void*)hContext ); 147 } 148 149 /* ----------------------------------------------------------------------- */ 150 151 void SAL_CALL rtl_resetTextToUnicodeContext( rtl_TextToUnicodeConverter hConverter, 152 rtl_TextToUnicodeContext hContext ) 153 { 154 const ImplTextConverter* pConverter = (const ImplTextConverter*)hConverter; 155 if ( pConverter && hContext && pConverter->mpResetTextToUnicodeContext ) 156 pConverter->mpResetTextToUnicodeContext( (void*)hContext ); 157 } 158 159 /* ----------------------------------------------------------------------- */ 160 161 sal_Size SAL_CALL rtl_convertTextToUnicode( rtl_TextToUnicodeConverter hConverter, 162 rtl_TextToUnicodeContext hContext, 163 const sal_Char* pSrcBuf, sal_Size nSrcBytes, 164 sal_Unicode* pDestBuf, sal_Size nDestChars, 165 sal_uInt32 nFlags, sal_uInt32* pInfo, 166 sal_Size* pSrcCvtBytes ) 167 { 168 const ImplTextConverter* pConverter = (const ImplTextConverter*)hConverter; 169 170 /* Only temporaer, because we don't want die, if we don't have a 171 converter, because not all converters are implemented yet */ 172 if ( !pConverter ) 173 { 174 return ImplDummyToUnicode( pSrcBuf, nSrcBytes, 175 pDestBuf, nDestChars, 176 nFlags, pInfo, pSrcCvtBytes ); 177 } 178 179 return pConverter->mpConvertTextToUnicodeProc( pConverter->mpConvertData, 180 (void*)hContext, 181 pSrcBuf, nSrcBytes, 182 pDestBuf, nDestChars, 183 nFlags, pInfo, 184 pSrcCvtBytes ); 185 } 186 187 /* ======================================================================= */ 188 189 rtl_UnicodeToTextConverter SAL_CALL rtl_createUnicodeToTextConverter( rtl_TextEncoding eTextEncoding ) 190 { 191 const ImplTextEncodingData* pData = Impl_getTextEncodingData( eTextEncoding ); 192 if ( pData ) 193 return (rtl_TextToUnicodeConverter) &pData->maConverter; 194 else 195 return 0; 196 } 197 198 /* ----------------------------------------------------------------------- */ 199 200 void SAL_CALL rtl_destroyUnicodeToTextConverter( rtl_UnicodeToTextConverter hConverter ) 201 { 202 (void) hConverter; /* unused */ 203 } 204 205 /* ----------------------------------------------------------------------- */ 206 207 rtl_UnicodeToTextContext SAL_CALL rtl_createUnicodeToTextContext( rtl_UnicodeToTextConverter hConverter ) 208 { 209 const ImplTextConverter* pConverter = (const ImplTextConverter*)hConverter; 210 if ( !pConverter ) 211 return 0; 212 else if ( pConverter->mpCreateUnicodeToTextContext ) 213 return (rtl_UnicodeToTextContext)pConverter->mpCreateUnicodeToTextContext(); 214 else 215 return (rtl_UnicodeToTextContext)1; 216 } 217 218 /* ----------------------------------------------------------------------- */ 219 220 void SAL_CALL rtl_destroyUnicodeToTextContext( rtl_UnicodeToTextConverter hConverter, 221 rtl_UnicodeToTextContext hContext ) 222 { 223 const ImplTextConverter* pConverter = (const ImplTextConverter*)hConverter; 224 if ( pConverter && hContext && pConverter->mpDestroyUnicodeToTextContext ) 225 pConverter->mpDestroyUnicodeToTextContext( (void*)hContext ); 226 } 227 228 /* ----------------------------------------------------------------------- */ 229 230 void SAL_CALL rtl_resetUnicodeToTextContext( rtl_UnicodeToTextConverter hConverter, 231 rtl_UnicodeToTextContext hContext ) 232 { 233 const ImplTextConverter* pConverter = (const ImplTextConverter*)hConverter; 234 if ( pConverter && hContext && pConverter->mpResetUnicodeToTextContext ) 235 pConverter->mpResetUnicodeToTextContext( (void*)hContext ); 236 } 237 238 /* ----------------------------------------------------------------------- */ 239 240 sal_Size SAL_CALL rtl_convertUnicodeToText( rtl_UnicodeToTextConverter hConverter, 241 rtl_UnicodeToTextContext hContext, 242 const sal_Unicode* pSrcBuf, sal_Size nSrcChars, 243 sal_Char* pDestBuf, sal_Size nDestBytes, 244 sal_uInt32 nFlags, sal_uInt32* pInfo, 245 sal_Size* pSrcCvtChars ) 246 { 247 const ImplTextConverter* pConverter = (const ImplTextConverter*)hConverter; 248 249 /* Only temporaer, because we don't want die, if we don't have a 250 converter, because not all converters are implemented yet */ 251 if ( !pConverter ) 252 { 253 return ImplUnicodeToDummy( pSrcBuf, nSrcChars, 254 pDestBuf, nDestBytes, 255 nFlags, pInfo, pSrcCvtChars ); 256 } 257 258 return pConverter->mpConvertUnicodeToTextProc( pConverter->mpConvertData, 259 (void*)hContext, 260 pSrcBuf, nSrcChars, 261 pDestBuf, nDestBytes, 262 nFlags, pInfo, 263 pSrcCvtChars ); 264 } 265