1*cdf0e10cSrcweir /************************************************************************* 2*cdf0e10cSrcweir * 3*cdf0e10cSrcweir * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4*cdf0e10cSrcweir * 5*cdf0e10cSrcweir * Copyright 2000, 2010 Oracle and/or its affiliates. 6*cdf0e10cSrcweir * 7*cdf0e10cSrcweir * OpenOffice.org - a multi-platform office productivity suite 8*cdf0e10cSrcweir * 9*cdf0e10cSrcweir * This file is part of OpenOffice.org. 10*cdf0e10cSrcweir * 11*cdf0e10cSrcweir * OpenOffice.org is free software: you can redistribute it and/or modify 12*cdf0e10cSrcweir * it under the terms of the GNU Lesser General Public License version 3 13*cdf0e10cSrcweir * only, as published by the Free Software Foundation. 14*cdf0e10cSrcweir * 15*cdf0e10cSrcweir * OpenOffice.org is distributed in the hope that it will be useful, 16*cdf0e10cSrcweir * but WITHOUT ANY WARRANTY; without even the implied warranty of 17*cdf0e10cSrcweir * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18*cdf0e10cSrcweir * GNU Lesser General Public License version 3 for more details 19*cdf0e10cSrcweir * (a copy is included in the LICENSE file that accompanied this code). 20*cdf0e10cSrcweir * 21*cdf0e10cSrcweir * You should have received a copy of the GNU Lesser General Public License 22*cdf0e10cSrcweir * version 3 along with OpenOffice.org. If not, see 23*cdf0e10cSrcweir * <http://www.openoffice.org/license.html> 24*cdf0e10cSrcweir * for a copy of the LGPLv3 License. 25*cdf0e10cSrcweir * 26*cdf0e10cSrcweir ************************************************************************/ 27*cdf0e10cSrcweir 28*cdf0e10cSrcweir #include "tenchelp.h" 29*cdf0e10cSrcweir #include "unichars.h" 30*cdf0e10cSrcweir 31*cdf0e10cSrcweir #ifndef _RTL_ALLOC_H 32*cdf0e10cSrcweir #include "rtl/alloc.h" 33*cdf0e10cSrcweir #endif 34*cdf0e10cSrcweir #include "rtl/textcvt.h" 35*cdf0e10cSrcweir 36*cdf0e10cSrcweir /* ======================================================================= */ 37*cdf0e10cSrcweir 38*cdf0e10cSrcweir static sal_uChar const aImplBase64Tab[64] = 39*cdf0e10cSrcweir { 40*cdf0e10cSrcweir /* A-Z */ 41*cdf0e10cSrcweir 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 42*cdf0e10cSrcweir 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 43*cdf0e10cSrcweir 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 44*cdf0e10cSrcweir 0x58, 0x59, 0x5A, 45*cdf0e10cSrcweir /* a-z */ 46*cdf0e10cSrcweir 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 47*cdf0e10cSrcweir 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 48*cdf0e10cSrcweir 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 49*cdf0e10cSrcweir 0x78, 0x79, 0x7A, 50*cdf0e10cSrcweir /* 0-9,+,/ */ 51*cdf0e10cSrcweir 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 52*cdf0e10cSrcweir 0x38, 0x39, 0x2B, 0x2F 53*cdf0e10cSrcweir }; 54*cdf0e10cSrcweir 55*cdf0e10cSrcweir /* Index in Base64Tab or 0xFF, when is a invalid character */ 56*cdf0e10cSrcweir static sal_uChar const aImplBase64IndexTab[128] = 57*cdf0e10cSrcweir { 58*cdf0e10cSrcweir 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* 0x00-0x07 */ 59*cdf0e10cSrcweir 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* 0x08-0x0F */ 60*cdf0e10cSrcweir 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* 0x10-0x17 */ 61*cdf0e10cSrcweir 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* 0x18-0x1F */ 62*cdf0e10cSrcweir 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* 0x20-0x27 !"#$%&' */ 63*cdf0e10cSrcweir 0xFF, 0xFF, 0xFF, 62, 0xFF, 0xFF, 0xFF, 63, /* 0x28-0x2F ()*+,-./ */ 64*cdf0e10cSrcweir 52, 53, 54, 55, 56, 57, 58, 59, /* 0x30-0x37 01234567 */ 65*cdf0e10cSrcweir 60, 61, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* 0x38-0x3F 89:;<=>? */ 66*cdf0e10cSrcweir 0xFF, 0, 1, 2, 3, 4, 5, 6, /* 0x40-0x47 @ABCDEFG */ 67*cdf0e10cSrcweir 7, 8, 9, 10, 11, 12, 13, 14, /* 0x48-0x4F HIJKLMNO */ 68*cdf0e10cSrcweir 15, 16, 17, 18, 19, 20, 21, 22, /* 0x50-0x57 PQRSTUVW */ 69*cdf0e10cSrcweir 23, 24, 25, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* 0x58-0x5F XYZ[\]^_ */ 70*cdf0e10cSrcweir 0xFF, 26, 27, 28, 29, 30, 31, 32, /* 0x60-0x67 `abcdefg */ 71*cdf0e10cSrcweir 33, 34, 35, 36, 37, 38, 39, 40, /* 0x68-0x6F hijklmno */ 72*cdf0e10cSrcweir 41, 42, 43, 44, 45, 46, 47, 48, /* 0x70-0x77 pqrstuvw */ 73*cdf0e10cSrcweir 49, 50, 51, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF /* 0x78-0x7F xyz{|}~ */ 74*cdf0e10cSrcweir }; 75*cdf0e10cSrcweir 76*cdf0e10cSrcweir static sal_uChar const aImplMustShiftTab[128] = 77*cdf0e10cSrcweir { 78*cdf0e10cSrcweir 1, 1, 1, 1, 1, 1, 1, 1, /* 0x00-0x07 */ 79*cdf0e10cSrcweir 1, 0, 0, 1, 0, 1, 1, 1, /* 0x08-0x0F 0x09 == HTAB, 0x0A == LF 0x0C == CR */ 80*cdf0e10cSrcweir 1, 1, 1, 1, 1, 1, 1, 1, /* 0x10-0x17 */ 81*cdf0e10cSrcweir 1, 1, 1, 1, 1, 1, 1, 1, /* 0x18-0x1F */ 82*cdf0e10cSrcweir 0, 1, 1, 1, 1, 1, 1, 0, /* 0x20-0x27 !"#$%&' */ 83*cdf0e10cSrcweir 0, 0, 1, 1, 0, 1, 0, 0, /* 0x28-0x2F ()*+,-./ */ 84*cdf0e10cSrcweir 0, 0, 0, 0, 0, 0, 0, 0, /* 0x30-0x37 01234567 */ 85*cdf0e10cSrcweir 0, 0, 0, 1, 1, 1, 1, 0, /* 0x38-0x3F 89:;<=>? */ 86*cdf0e10cSrcweir 1, 0, 0, 0, 0, 0, 0, 0, /* 0x40-0x47 @ABCDEFG */ 87*cdf0e10cSrcweir 0, 0, 0, 0, 0, 0, 0, 0, /* 0x48-0x4F HIJKLMNO */ 88*cdf0e10cSrcweir 0, 0, 0, 0, 0, 0, 0, 0, /* 0x50-0x57 PQRSTUVW */ 89*cdf0e10cSrcweir 0, 0, 0, 1, 1, 1, 1, 1, /* 0x58-0x5F XYZ[\]^_ */ 90*cdf0e10cSrcweir 1, 0, 0, 0, 0, 0, 0, 0, /* 0x60-0x67 `abcdefg */ 91*cdf0e10cSrcweir 0, 0, 0, 0, 0, 0, 0, 0, /* 0x68-0x6F hijklmno */ 92*cdf0e10cSrcweir 0, 0, 0, 0, 0, 0, 0, 0, /* 0x70-0x77 pqrstuvw */ 93*cdf0e10cSrcweir 0, 0, 0, 1, 1, 1, 1, 1 /* 0x78-0x7F xyz{|}~ */ 94*cdf0e10cSrcweir }; 95*cdf0e10cSrcweir 96*cdf0e10cSrcweir /* + */ 97*cdf0e10cSrcweir #define IMPL_SHIFT_IN_CHAR 0x2B 98*cdf0e10cSrcweir /* - */ 99*cdf0e10cSrcweir #define IMPL_SHIFT_OUT_CHAR 0x2D 100*cdf0e10cSrcweir 101*cdf0e10cSrcweir /* ----------------------------------------------------------------------- */ 102*cdf0e10cSrcweir 103*cdf0e10cSrcweir typedef struct 104*cdf0e10cSrcweir { 105*cdf0e10cSrcweir int mbShifted; 106*cdf0e10cSrcweir int mbFirst; 107*cdf0e10cSrcweir int mbWroteOne; 108*cdf0e10cSrcweir sal_uInt32 mnBitBuffer; 109*cdf0e10cSrcweir sal_uInt32 mnBufferBits; 110*cdf0e10cSrcweir } ImplUTF7ToUCContextData; 111*cdf0e10cSrcweir 112*cdf0e10cSrcweir /* ----------------------------------------------------------------------- */ 113*cdf0e10cSrcweir 114*cdf0e10cSrcweir void* ImplUTF7CreateUTF7TextToUnicodeContext( void ) 115*cdf0e10cSrcweir { 116*cdf0e10cSrcweir ImplUTF7ToUCContextData* pContextData; 117*cdf0e10cSrcweir pContextData = (ImplUTF7ToUCContextData*)rtl_allocateMemory( sizeof( ImplUTF7ToUCContextData ) ); 118*cdf0e10cSrcweir pContextData->mbShifted = sal_False; 119*cdf0e10cSrcweir pContextData->mbFirst = sal_False; 120*cdf0e10cSrcweir pContextData->mbWroteOne = sal_False; 121*cdf0e10cSrcweir pContextData->mnBitBuffer = 0; 122*cdf0e10cSrcweir pContextData->mnBufferBits = 0; 123*cdf0e10cSrcweir return (void*)pContextData; 124*cdf0e10cSrcweir } 125*cdf0e10cSrcweir 126*cdf0e10cSrcweir /* ----------------------------------------------------------------------- */ 127*cdf0e10cSrcweir 128*cdf0e10cSrcweir void ImplUTF7DestroyTextToUnicodeContext( void* pContext ) 129*cdf0e10cSrcweir { 130*cdf0e10cSrcweir rtl_freeMemory( pContext ); 131*cdf0e10cSrcweir } 132*cdf0e10cSrcweir 133*cdf0e10cSrcweir /* ----------------------------------------------------------------------- */ 134*cdf0e10cSrcweir 135*cdf0e10cSrcweir void ImplUTF7ResetTextToUnicodeContext( void* pContext ) 136*cdf0e10cSrcweir { 137*cdf0e10cSrcweir ImplUTF7ToUCContextData* pContextData = (ImplUTF7ToUCContextData*)pContext; 138*cdf0e10cSrcweir pContextData->mbShifted = sal_False; 139*cdf0e10cSrcweir pContextData->mbFirst = sal_False; 140*cdf0e10cSrcweir pContextData->mbWroteOne = sal_False; 141*cdf0e10cSrcweir pContextData->mnBitBuffer = 0; 142*cdf0e10cSrcweir pContextData->mnBufferBits = 0; 143*cdf0e10cSrcweir } 144*cdf0e10cSrcweir 145*cdf0e10cSrcweir /* ----------------------------------------------------------------------- */ 146*cdf0e10cSrcweir 147*cdf0e10cSrcweir sal_Size ImplUTF7ToUnicode( const ImplTextConverterData* pData, void* pContext, 148*cdf0e10cSrcweir const sal_Char* pSrcBuf, sal_Size nSrcBytes, 149*cdf0e10cSrcweir sal_Unicode* pDestBuf, sal_Size nDestChars, 150*cdf0e10cSrcweir sal_uInt32 nFlags, sal_uInt32* pInfo, 151*cdf0e10cSrcweir sal_Size* pSrcCvtBytes ) 152*cdf0e10cSrcweir { 153*cdf0e10cSrcweir ImplUTF7ToUCContextData* pContextData = (ImplUTF7ToUCContextData*)pContext; 154*cdf0e10cSrcweir sal_uChar c ='\0'; 155*cdf0e10cSrcweir sal_uChar nBase64Value = 0; 156*cdf0e10cSrcweir int bEnd = sal_False; 157*cdf0e10cSrcweir int bShifted; 158*cdf0e10cSrcweir int bFirst; 159*cdf0e10cSrcweir int bWroteOne; 160*cdf0e10cSrcweir int bBase64End; 161*cdf0e10cSrcweir sal_uInt32 nBitBuffer; 162*cdf0e10cSrcweir sal_uInt32 nBitBufferTemp; 163*cdf0e10cSrcweir sal_uInt32 nBufferBits; 164*cdf0e10cSrcweir sal_Unicode* pEndDestBuf; 165*cdf0e10cSrcweir const sal_Char* pEndSrcBuf; 166*cdf0e10cSrcweir 167*cdf0e10cSrcweir (void) pData; /* unused */ 168*cdf0e10cSrcweir 169*cdf0e10cSrcweir /* !!! Implementation not finnished !!! 170*cdf0e10cSrcweir if ( pContextData ) 171*cdf0e10cSrcweir { 172*cdf0e10cSrcweir bShifted = pContextData->mbShifted; 173*cdf0e10cSrcweir bFirst = pContextData->mbFirst; 174*cdf0e10cSrcweir bWroteOne = pContextData->mbWroteOne; 175*cdf0e10cSrcweir nBitBuffer = pContextData->mnBitBuffer; 176*cdf0e10cSrcweir nBufferBits = pContextData->mnBufferBits; 177*cdf0e10cSrcweir } 178*cdf0e10cSrcweir else 179*cdf0e10cSrcweir */ 180*cdf0e10cSrcweir { 181*cdf0e10cSrcweir bShifted = sal_False; 182*cdf0e10cSrcweir bFirst = sal_False; 183*cdf0e10cSrcweir bWroteOne = sal_False; 184*cdf0e10cSrcweir nBitBuffer = 0; 185*cdf0e10cSrcweir nBufferBits = 0; 186*cdf0e10cSrcweir } 187*cdf0e10cSrcweir 188*cdf0e10cSrcweir *pInfo = 0; 189*cdf0e10cSrcweir pEndDestBuf = pDestBuf+nDestChars; 190*cdf0e10cSrcweir pEndSrcBuf = pSrcBuf+nSrcBytes; 191*cdf0e10cSrcweir do 192*cdf0e10cSrcweir { 193*cdf0e10cSrcweir if ( pSrcBuf < pEndSrcBuf ) 194*cdf0e10cSrcweir { 195*cdf0e10cSrcweir c = (sal_uChar)*pSrcBuf; 196*cdf0e10cSrcweir 197*cdf0e10cSrcweir /* End, when not a base64 character */ 198*cdf0e10cSrcweir bBase64End = sal_False; 199*cdf0e10cSrcweir if ( c <= 0x7F ) 200*cdf0e10cSrcweir { 201*cdf0e10cSrcweir nBase64Value = aImplBase64IndexTab[c]; 202*cdf0e10cSrcweir if ( nBase64Value == 0xFF ) 203*cdf0e10cSrcweir bBase64End = sal_True; 204*cdf0e10cSrcweir } 205*cdf0e10cSrcweir } 206*cdf0e10cSrcweir else 207*cdf0e10cSrcweir { 208*cdf0e10cSrcweir bEnd = sal_True; 209*cdf0e10cSrcweir bBase64End = sal_True; 210*cdf0e10cSrcweir } 211*cdf0e10cSrcweir 212*cdf0e10cSrcweir if ( bShifted ) 213*cdf0e10cSrcweir { 214*cdf0e10cSrcweir if ( bBase64End ) 215*cdf0e10cSrcweir { 216*cdf0e10cSrcweir bShifted = sal_False; 217*cdf0e10cSrcweir 218*cdf0e10cSrcweir /* If the character causing us to drop out was SHIFT_IN */ 219*cdf0e10cSrcweir /* or SHIFT_OUT, it may be a special escape for SHIFT_IN. */ 220*cdf0e10cSrcweir /* The test for SHIFT_IN is not necessary, but allows */ 221*cdf0e10cSrcweir /* an alternate form of UTF-7 where SHIFT_IN is escaped */ 222*cdf0e10cSrcweir /* by SHIFT_IN. This only works for some values of */ 223*cdf0e10cSrcweir /* SHIFT_IN. It is so implemented, because this comes */ 224*cdf0e10cSrcweir /* from the officel unicode book (The Unicode Standard, */ 225*cdf0e10cSrcweir /* Version 2.0) and so I think, that someone of the */ 226*cdf0e10cSrcweir /* world has used this feature. */ 227*cdf0e10cSrcweir if ( !bEnd ) 228*cdf0e10cSrcweir { 229*cdf0e10cSrcweir if ( (c == IMPL_SHIFT_IN_CHAR) || (c == IMPL_SHIFT_OUT_CHAR) ) 230*cdf0e10cSrcweir { 231*cdf0e10cSrcweir /* If no base64 character, and the terminating */ 232*cdf0e10cSrcweir /* character of the shift sequence was the */ 233*cdf0e10cSrcweir /* SHIFT_OUT_CHAR, then it't a special escape */ 234*cdf0e10cSrcweir /* for SHIFT_IN_CHAR. */ 235*cdf0e10cSrcweir if ( bFirst && (c == IMPL_SHIFT_OUT_CHAR) ) 236*cdf0e10cSrcweir { 237*cdf0e10cSrcweir if ( pDestBuf >= pEndDestBuf ) 238*cdf0e10cSrcweir { 239*cdf0e10cSrcweir *pInfo |= RTL_TEXTTOUNICODE_INFO_ERROR | RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOSMALL; 240*cdf0e10cSrcweir break; 241*cdf0e10cSrcweir } 242*cdf0e10cSrcweir *pDestBuf = IMPL_SHIFT_IN_CHAR; 243*cdf0e10cSrcweir pDestBuf++; 244*cdf0e10cSrcweir bWroteOne = sal_True; 245*cdf0e10cSrcweir } 246*cdf0e10cSrcweir 247*cdf0e10cSrcweir /* Skip character */ 248*cdf0e10cSrcweir pSrcBuf++; 249*cdf0e10cSrcweir if ( pSrcBuf < pEndSrcBuf ) 250*cdf0e10cSrcweir c = (sal_uChar)*pSrcBuf; 251*cdf0e10cSrcweir else 252*cdf0e10cSrcweir bEnd = sal_True; 253*cdf0e10cSrcweir } 254*cdf0e10cSrcweir } 255*cdf0e10cSrcweir 256*cdf0e10cSrcweir /* Empty sequence not allowed, so when we don't write one */ 257*cdf0e10cSrcweir /* valid char, then the sequence is corrupt */ 258*cdf0e10cSrcweir if ( !bWroteOne ) 259*cdf0e10cSrcweir { 260*cdf0e10cSrcweir /* When no more bytes in the source buffer, then */ 261*cdf0e10cSrcweir /* this buffer may be to small */ 262*cdf0e10cSrcweir if ( bEnd ) 263*cdf0e10cSrcweir *pInfo |= RTL_TEXTTOUNICODE_INFO_ERROR | RTL_TEXTTOUNICODE_INFO_SRCBUFFERTOSMALL; 264*cdf0e10cSrcweir else 265*cdf0e10cSrcweir { 266*cdf0e10cSrcweir *pInfo |= RTL_TEXTTOUNICODE_INFO_INVALID; 267*cdf0e10cSrcweir if ( (nFlags & RTL_TEXTTOUNICODE_FLAGS_INVALID_MASK) == RTL_TEXTTOUNICODE_FLAGS_INVALID_ERROR ) 268*cdf0e10cSrcweir { 269*cdf0e10cSrcweir *pInfo |= RTL_TEXTTOUNICODE_INFO_ERROR; 270*cdf0e10cSrcweir break; 271*cdf0e10cSrcweir } 272*cdf0e10cSrcweir /* We insert here no default char, because I think */ 273*cdf0e10cSrcweir /* this is better to ignore this */ 274*cdf0e10cSrcweir } 275*cdf0e10cSrcweir } 276*cdf0e10cSrcweir } 277*cdf0e10cSrcweir else 278*cdf0e10cSrcweir { 279*cdf0e10cSrcweir /* Add 6 Bits from character to the bit buffer */ 280*cdf0e10cSrcweir nBufferBits += 6; 281*cdf0e10cSrcweir nBitBuffer |= ((sal_uInt32)(nBase64Value & 0x3F)) << (32-nBufferBits); 282*cdf0e10cSrcweir bFirst = sal_False; 283*cdf0e10cSrcweir } 284*cdf0e10cSrcweir 285*cdf0e10cSrcweir /* Extract as many full 16 bit characters as possible from the */ 286*cdf0e10cSrcweir /* bit buffer. */ 287*cdf0e10cSrcweir while ( (pDestBuf < pEndDestBuf) && (nBufferBits >= 16) ) 288*cdf0e10cSrcweir { 289*cdf0e10cSrcweir nBitBufferTemp = nBitBuffer >> (32-16); 290*cdf0e10cSrcweir *pDestBuf = (sal_Unicode)((nBitBufferTemp) & 0xFFFF); 291*cdf0e10cSrcweir pDestBuf++; 292*cdf0e10cSrcweir nBitBuffer <<= 16; 293*cdf0e10cSrcweir nBufferBits -= 16; 294*cdf0e10cSrcweir bWroteOne = sal_True; 295*cdf0e10cSrcweir } 296*cdf0e10cSrcweir 297*cdf0e10cSrcweir if ( nBufferBits >= 16 ) 298*cdf0e10cSrcweir { 299*cdf0e10cSrcweir *pInfo |= RTL_TEXTTOUNICODE_INFO_ERROR | RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOSMALL; 300*cdf0e10cSrcweir break; 301*cdf0e10cSrcweir } 302*cdf0e10cSrcweir 303*cdf0e10cSrcweir if ( bBase64End ) 304*cdf0e10cSrcweir { 305*cdf0e10cSrcweir /* Sequence ended and we have some bits, then the */ 306*cdf0e10cSrcweir /* sequence is corrupted */ 307*cdf0e10cSrcweir if ( nBufferBits && nBitBuffer ) 308*cdf0e10cSrcweir { 309*cdf0e10cSrcweir /* When no more bytes in the source buffer, then */ 310*cdf0e10cSrcweir /* this buffer may be to small */ 311*cdf0e10cSrcweir if ( bEnd ) 312*cdf0e10cSrcweir *pInfo |= RTL_TEXTTOUNICODE_INFO_ERROR | RTL_TEXTTOUNICODE_INFO_SRCBUFFERTOSMALL; 313*cdf0e10cSrcweir else 314*cdf0e10cSrcweir { 315*cdf0e10cSrcweir *pInfo |= RTL_TEXTTOUNICODE_INFO_INVALID; 316*cdf0e10cSrcweir if ( (nFlags & RTL_TEXTTOUNICODE_FLAGS_INVALID_MASK) == RTL_TEXTTOUNICODE_FLAGS_INVALID_ERROR ) 317*cdf0e10cSrcweir { 318*cdf0e10cSrcweir *pInfo |= RTL_TEXTTOUNICODE_INFO_ERROR; 319*cdf0e10cSrcweir break; 320*cdf0e10cSrcweir } 321*cdf0e10cSrcweir else if ( (nFlags & RTL_TEXTTOUNICODE_FLAGS_INVALID_MASK) != RTL_TEXTTOUNICODE_FLAGS_INVALID_IGNORE ) 322*cdf0e10cSrcweir { 323*cdf0e10cSrcweir if ( pDestBuf >= pEndDestBuf ) 324*cdf0e10cSrcweir { 325*cdf0e10cSrcweir *pInfo |= RTL_TEXTTOUNICODE_INFO_ERROR | RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOSMALL; 326*cdf0e10cSrcweir break; 327*cdf0e10cSrcweir } 328*cdf0e10cSrcweir *pDestBuf++ 329*cdf0e10cSrcweir = RTL_TEXTENC_UNICODE_REPLACEMENT_CHARACTER; 330*cdf0e10cSrcweir } 331*cdf0e10cSrcweir } 332*cdf0e10cSrcweir 333*cdf0e10cSrcweir } 334*cdf0e10cSrcweir 335*cdf0e10cSrcweir nBitBuffer = 0; 336*cdf0e10cSrcweir nBufferBits = 0; 337*cdf0e10cSrcweir } 338*cdf0e10cSrcweir } 339*cdf0e10cSrcweir 340*cdf0e10cSrcweir if ( !bEnd ) 341*cdf0e10cSrcweir { 342*cdf0e10cSrcweir if ( !bShifted ) 343*cdf0e10cSrcweir { 344*cdf0e10cSrcweir if ( c == IMPL_SHIFT_IN_CHAR ) 345*cdf0e10cSrcweir { 346*cdf0e10cSrcweir bShifted = sal_True; 347*cdf0e10cSrcweir bFirst = sal_True; 348*cdf0e10cSrcweir bWroteOne = sal_False; 349*cdf0e10cSrcweir } 350*cdf0e10cSrcweir else 351*cdf0e10cSrcweir { 352*cdf0e10cSrcweir /* No direct encoded charcater, then the buffer is */ 353*cdf0e10cSrcweir /* corrupt */ 354*cdf0e10cSrcweir if ( c > 0x7F ) 355*cdf0e10cSrcweir { 356*cdf0e10cSrcweir *pInfo |= RTL_TEXTTOUNICODE_INFO_INVALID; 357*cdf0e10cSrcweir if ( (nFlags & RTL_TEXTTOUNICODE_FLAGS_INVALID_MASK) == RTL_TEXTTOUNICODE_FLAGS_INVALID_ERROR ) 358*cdf0e10cSrcweir { 359*cdf0e10cSrcweir *pInfo |= RTL_TEXTTOUNICODE_INFO_ERROR; 360*cdf0e10cSrcweir break; 361*cdf0e10cSrcweir } 362*cdf0e10cSrcweir else if ( (nFlags & RTL_TEXTTOUNICODE_FLAGS_INVALID_MASK) != RTL_TEXTTOUNICODE_FLAGS_INVALID_IGNORE ) 363*cdf0e10cSrcweir { 364*cdf0e10cSrcweir if ( pDestBuf >= pEndDestBuf ) 365*cdf0e10cSrcweir { 366*cdf0e10cSrcweir *pInfo |= RTL_TEXTTOUNICODE_INFO_ERROR | RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOSMALL; 367*cdf0e10cSrcweir break; 368*cdf0e10cSrcweir } 369*cdf0e10cSrcweir *pDestBuf++ 370*cdf0e10cSrcweir = RTL_TEXTENC_UNICODE_REPLACEMENT_CHARACTER; 371*cdf0e10cSrcweir } 372*cdf0e10cSrcweir } 373*cdf0e10cSrcweir 374*cdf0e10cSrcweir /* Write char to unicode buffer */ 375*cdf0e10cSrcweir if ( pDestBuf >= pEndDestBuf ) 376*cdf0e10cSrcweir { 377*cdf0e10cSrcweir *pInfo |= RTL_TEXTTOUNICODE_INFO_ERROR | RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOSMALL; 378*cdf0e10cSrcweir break; 379*cdf0e10cSrcweir } 380*cdf0e10cSrcweir *pDestBuf = c; 381*cdf0e10cSrcweir pDestBuf++; 382*cdf0e10cSrcweir } 383*cdf0e10cSrcweir } 384*cdf0e10cSrcweir 385*cdf0e10cSrcweir pSrcBuf++; 386*cdf0e10cSrcweir } 387*cdf0e10cSrcweir } 388*cdf0e10cSrcweir while ( !bEnd ); 389*cdf0e10cSrcweir 390*cdf0e10cSrcweir if ( pContextData ) 391*cdf0e10cSrcweir { 392*cdf0e10cSrcweir pContextData->mbShifted = bShifted; 393*cdf0e10cSrcweir pContextData->mbFirst = bFirst; 394*cdf0e10cSrcweir pContextData->mbWroteOne = bWroteOne; 395*cdf0e10cSrcweir pContextData->mnBitBuffer = nBitBuffer; 396*cdf0e10cSrcweir pContextData->mnBufferBits = nBufferBits; 397*cdf0e10cSrcweir } 398*cdf0e10cSrcweir 399*cdf0e10cSrcweir *pSrcCvtBytes = nSrcBytes - (pEndSrcBuf-pSrcBuf); 400*cdf0e10cSrcweir return (nDestChars - (pEndDestBuf-pDestBuf)); 401*cdf0e10cSrcweir } 402*cdf0e10cSrcweir 403*cdf0e10cSrcweir /* ======================================================================= */ 404*cdf0e10cSrcweir 405*cdf0e10cSrcweir typedef struct 406*cdf0e10cSrcweir { 407*cdf0e10cSrcweir int mbShifted; 408*cdf0e10cSrcweir sal_uInt32 mnBitBuffer; 409*cdf0e10cSrcweir sal_uInt32 mnBufferBits; 410*cdf0e10cSrcweir } ImplUTF7FromUCContextData; 411*cdf0e10cSrcweir 412*cdf0e10cSrcweir /* ----------------------------------------------------------------------- */ 413*cdf0e10cSrcweir 414*cdf0e10cSrcweir void* ImplUTF7CreateUnicodeToTextContext( void ) 415*cdf0e10cSrcweir { 416*cdf0e10cSrcweir ImplUTF7FromUCContextData* pContextData; 417*cdf0e10cSrcweir pContextData = (ImplUTF7FromUCContextData*)rtl_allocateMemory( sizeof( ImplUTF7FromUCContextData ) ); 418*cdf0e10cSrcweir pContextData->mbShifted = sal_False; 419*cdf0e10cSrcweir pContextData->mnBitBuffer = 0; 420*cdf0e10cSrcweir pContextData->mnBufferBits = 0; 421*cdf0e10cSrcweir return (void*)pContextData; 422*cdf0e10cSrcweir } 423*cdf0e10cSrcweir 424*cdf0e10cSrcweir /* ----------------------------------------------------------------------- */ 425*cdf0e10cSrcweir 426*cdf0e10cSrcweir void ImplUTF7DestroyUnicodeToTextContext( void* pContext ) 427*cdf0e10cSrcweir { 428*cdf0e10cSrcweir rtl_freeMemory( pContext ); 429*cdf0e10cSrcweir } 430*cdf0e10cSrcweir 431*cdf0e10cSrcweir /* ----------------------------------------------------------------------- */ 432*cdf0e10cSrcweir 433*cdf0e10cSrcweir void ImplUTF7ResetUnicodeToTextContext( void* pContext ) 434*cdf0e10cSrcweir { 435*cdf0e10cSrcweir ImplUTF7FromUCContextData* pContextData = (ImplUTF7FromUCContextData*)pContext; 436*cdf0e10cSrcweir pContextData->mbShifted = sal_False; 437*cdf0e10cSrcweir pContextData->mnBitBuffer = 0; 438*cdf0e10cSrcweir pContextData->mnBufferBits = 0; 439*cdf0e10cSrcweir } 440*cdf0e10cSrcweir 441*cdf0e10cSrcweir /* ----------------------------------------------------------------------- */ 442*cdf0e10cSrcweir 443*cdf0e10cSrcweir sal_Size ImplUnicodeToUTF7( const ImplTextConverterData* pData, void* pContext, 444*cdf0e10cSrcweir const sal_Unicode* pSrcBuf, sal_Size nSrcChars, 445*cdf0e10cSrcweir sal_Char* pDestBuf, sal_Size nDestBytes, 446*cdf0e10cSrcweir sal_uInt32 nFlags, sal_uInt32* pInfo, 447*cdf0e10cSrcweir sal_Size* pSrcCvtChars ) 448*cdf0e10cSrcweir { 449*cdf0e10cSrcweir ImplUTF7FromUCContextData* pContextData = (ImplUTF7FromUCContextData*)pContext; 450*cdf0e10cSrcweir sal_Unicode c = '\0'; 451*cdf0e10cSrcweir int bEnd = sal_False; 452*cdf0e10cSrcweir int bShifted; 453*cdf0e10cSrcweir int bNeedShift; 454*cdf0e10cSrcweir sal_uInt32 nBitBuffer; 455*cdf0e10cSrcweir sal_uInt32 nBitBufferTemp; 456*cdf0e10cSrcweir sal_uInt32 nBufferBits; 457*cdf0e10cSrcweir sal_Char* pEndDestBuf; 458*cdf0e10cSrcweir const sal_Unicode* pEndSrcBuf; 459*cdf0e10cSrcweir 460*cdf0e10cSrcweir (void) pData; /* unused */ 461*cdf0e10cSrcweir (void) nFlags; /* unused */ 462*cdf0e10cSrcweir 463*cdf0e10cSrcweir /* !!! Implementation not finnished !!! 464*cdf0e10cSrcweir if ( pContextData ) 465*cdf0e10cSrcweir { 466*cdf0e10cSrcweir bShifted = pContextData->mbShifted; 467*cdf0e10cSrcweir nBitBuffer = pContextData->mnBitBuffer; 468*cdf0e10cSrcweir nBufferBits = pContextData->mnBufferBits; 469*cdf0e10cSrcweir } 470*cdf0e10cSrcweir else 471*cdf0e10cSrcweir */ 472*cdf0e10cSrcweir { 473*cdf0e10cSrcweir bShifted = sal_False; 474*cdf0e10cSrcweir nBitBuffer = 0; 475*cdf0e10cSrcweir nBufferBits = 0; 476*cdf0e10cSrcweir } 477*cdf0e10cSrcweir 478*cdf0e10cSrcweir *pInfo = 0; 479*cdf0e10cSrcweir pEndDestBuf = pDestBuf+nDestBytes; 480*cdf0e10cSrcweir pEndSrcBuf = pSrcBuf+nSrcChars; 481*cdf0e10cSrcweir do 482*cdf0e10cSrcweir { 483*cdf0e10cSrcweir if ( pSrcBuf < pEndSrcBuf ) 484*cdf0e10cSrcweir { 485*cdf0e10cSrcweir c = *pSrcBuf; 486*cdf0e10cSrcweir 487*cdf0e10cSrcweir bNeedShift = (c > 0x7F) || aImplMustShiftTab[c]; 488*cdf0e10cSrcweir if ( bNeedShift && !bShifted ) 489*cdf0e10cSrcweir { 490*cdf0e10cSrcweir if ( pDestBuf >= pEndDestBuf ) 491*cdf0e10cSrcweir { 492*cdf0e10cSrcweir *pInfo |= RTL_UNICODETOTEXT_INFO_DESTBUFFERTOSMALL; 493*cdf0e10cSrcweir break; 494*cdf0e10cSrcweir } 495*cdf0e10cSrcweir *pDestBuf = IMPL_SHIFT_IN_CHAR; 496*cdf0e10cSrcweir pDestBuf++; 497*cdf0e10cSrcweir /* Special case handling for SHIFT_IN_CHAR */ 498*cdf0e10cSrcweir if ( c == IMPL_SHIFT_IN_CHAR ) 499*cdf0e10cSrcweir { 500*cdf0e10cSrcweir if ( pDestBuf >= pEndDestBuf ) 501*cdf0e10cSrcweir { 502*cdf0e10cSrcweir *pInfo |= RTL_UNICODETOTEXT_INFO_DESTBUFFERTOSMALL; 503*cdf0e10cSrcweir break; 504*cdf0e10cSrcweir } 505*cdf0e10cSrcweir *pDestBuf = IMPL_SHIFT_OUT_CHAR; 506*cdf0e10cSrcweir pDestBuf++; 507*cdf0e10cSrcweir } 508*cdf0e10cSrcweir else 509*cdf0e10cSrcweir bShifted = sal_True; 510*cdf0e10cSrcweir } 511*cdf0e10cSrcweir } 512*cdf0e10cSrcweir else 513*cdf0e10cSrcweir { 514*cdf0e10cSrcweir bEnd = sal_True; 515*cdf0e10cSrcweir bNeedShift = sal_False; 516*cdf0e10cSrcweir } 517*cdf0e10cSrcweir 518*cdf0e10cSrcweir if ( bShifted ) 519*cdf0e10cSrcweir { 520*cdf0e10cSrcweir /* Write the character to the bit buffer, or pad the bit */ 521*cdf0e10cSrcweir /* buffer out to a full base64 character */ 522*cdf0e10cSrcweir if ( bNeedShift ) 523*cdf0e10cSrcweir { 524*cdf0e10cSrcweir nBufferBits += 16; 525*cdf0e10cSrcweir nBitBuffer |= ((sal_uInt32)c) << (32-nBufferBits); 526*cdf0e10cSrcweir } 527*cdf0e10cSrcweir else 528*cdf0e10cSrcweir nBufferBits += (6-(nBufferBits%6))%6; 529*cdf0e10cSrcweir 530*cdf0e10cSrcweir /* Flush out as many full base64 characters as possible */ 531*cdf0e10cSrcweir while ( (pDestBuf < pEndDestBuf) && (nBufferBits >= 6) ) 532*cdf0e10cSrcweir { 533*cdf0e10cSrcweir nBitBufferTemp = nBitBuffer >> (32-6); 534*cdf0e10cSrcweir *pDestBuf = aImplBase64Tab[nBitBufferTemp]; 535*cdf0e10cSrcweir pDestBuf++; 536*cdf0e10cSrcweir nBitBuffer <<= 6; 537*cdf0e10cSrcweir nBufferBits -= 6; 538*cdf0e10cSrcweir } 539*cdf0e10cSrcweir 540*cdf0e10cSrcweir if ( nBufferBits >= 6 ) 541*cdf0e10cSrcweir { 542*cdf0e10cSrcweir *pInfo |= RTL_UNICODETOTEXT_INFO_DESTBUFFERTOSMALL; 543*cdf0e10cSrcweir break; 544*cdf0e10cSrcweir } 545*cdf0e10cSrcweir 546*cdf0e10cSrcweir /* Write SHIFT_OUT_CHAR, when needed */ 547*cdf0e10cSrcweir if ( !bNeedShift ) 548*cdf0e10cSrcweir { 549*cdf0e10cSrcweir if ( pDestBuf >= pEndDestBuf ) 550*cdf0e10cSrcweir { 551*cdf0e10cSrcweir *pInfo |= RTL_UNICODETOTEXT_INFO_DESTBUFFERTOSMALL; 552*cdf0e10cSrcweir break; 553*cdf0e10cSrcweir } 554*cdf0e10cSrcweir *pDestBuf = IMPL_SHIFT_OUT_CHAR; 555*cdf0e10cSrcweir pDestBuf++; 556*cdf0e10cSrcweir bShifted = sal_False; 557*cdf0e10cSrcweir } 558*cdf0e10cSrcweir } 559*cdf0e10cSrcweir 560*cdf0e10cSrcweir if ( !bEnd ) 561*cdf0e10cSrcweir { 562*cdf0e10cSrcweir /* Character can be directly endcoded */ 563*cdf0e10cSrcweir if ( !bNeedShift ) 564*cdf0e10cSrcweir { 565*cdf0e10cSrcweir if ( pDestBuf >= pEndDestBuf ) 566*cdf0e10cSrcweir { 567*cdf0e10cSrcweir *pInfo |= RTL_UNICODETOTEXT_INFO_DESTBUFFERTOSMALL; 568*cdf0e10cSrcweir break; 569*cdf0e10cSrcweir } 570*cdf0e10cSrcweir *pDestBuf = (sal_Char)(sal_uChar)c; 571*cdf0e10cSrcweir pDestBuf++; 572*cdf0e10cSrcweir } 573*cdf0e10cSrcweir 574*cdf0e10cSrcweir pSrcBuf++; 575*cdf0e10cSrcweir } 576*cdf0e10cSrcweir } 577*cdf0e10cSrcweir while ( !bEnd ); 578*cdf0e10cSrcweir 579*cdf0e10cSrcweir if ( pContextData ) 580*cdf0e10cSrcweir { 581*cdf0e10cSrcweir pContextData->mbShifted = bShifted; 582*cdf0e10cSrcweir pContextData->mnBitBuffer = nBitBuffer; 583*cdf0e10cSrcweir pContextData->mnBufferBits = nBufferBits; 584*cdf0e10cSrcweir } 585*cdf0e10cSrcweir 586*cdf0e10cSrcweir *pSrcCvtChars = nSrcChars - (pEndSrcBuf-pSrcBuf); 587*cdf0e10cSrcweir return (nDestBytes - (pEndDestBuf-pDestBuf)); 588*cdf0e10cSrcweir } 589