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