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