xref: /aosp_15_r20/external/unicode/CVTUTF7.C (revision c14be686ac162d87fd361a4e7a5439b56849c4f4)
1*c14be686SAndroid Build Coastguard Worker /* ================================================================ */
2*c14be686SAndroid Build Coastguard Worker /*
3*c14be686SAndroid Build Coastguard Worker File:   ConvertUTF7.c
4*c14be686SAndroid Build Coastguard Worker Author: David B. Goldsmith
5*c14be686SAndroid Build Coastguard Worker Copyright (C) 1994, 1996 IBM Corporation All rights reserved.
6*c14be686SAndroid Build Coastguard Worker Revisions: Header update only July, 2001.
7*c14be686SAndroid Build Coastguard Worker 
8*c14be686SAndroid Build Coastguard Worker This code is copyrighted. Under the copyright laws, this code may not
9*c14be686SAndroid Build Coastguard Worker be copied, in whole or part, without prior written consent of IBM Corporation.
10*c14be686SAndroid Build Coastguard Worker 
11*c14be686SAndroid Build Coastguard Worker IBM Corporation grants the right to use this code as long as this ENTIRE
12*c14be686SAndroid Build Coastguard Worker copyright notice is reproduced in the code.  The code is provided
13*c14be686SAndroid Build Coastguard Worker AS-IS, AND IBM CORPORATION DISCLAIMS ALL WARRANTIES, EITHER EXPRESS OR
14*c14be686SAndroid Build Coastguard Worker IMPLIED, INCLUDING, BUT NOT LIMITED TO IMPLIED WARRANTIES OF
15*c14be686SAndroid Build Coastguard Worker MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT
16*c14be686SAndroid Build Coastguard Worker WILL IBM CORPORATION BE LIABLE FOR ANY DAMAGES WHATSOEVER (INCLUDING,
17*c14be686SAndroid Build Coastguard Worker WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS, BUSINESS
18*c14be686SAndroid Build Coastguard Worker INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR OTHER PECUNIARY
19*c14be686SAndroid Build Coastguard Worker LOSS) ARISING OUT OF THE USE OR INABILITY TO USE THIS CODE, EVEN
20*c14be686SAndroid Build Coastguard Worker IF IBM CORPORATION HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
21*c14be686SAndroid Build Coastguard Worker BECAUSE SOME STATES DO NOT ALLOW THE EXCLUSION OR LIMITATION OF
22*c14be686SAndroid Build Coastguard Worker LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES, THE ABOVE
23*c14be686SAndroid Build Coastguard Worker LIMITATION MAY NOT APPLY TO YOU.
24*c14be686SAndroid Build Coastguard Worker 
25*c14be686SAndroid Build Coastguard Worker RESTRICTED RIGHTS LEGEND: Use, duplication, or disclosure by the
26*c14be686SAndroid Build Coastguard Worker government is subject to restrictions as set forth in subparagraph
27*c14be686SAndroid Build Coastguard Worker (c)(l)(ii) of the Rights in Technical Data and Computer Software
28*c14be686SAndroid Build Coastguard Worker clause at DFARS 252.227-7013 and FAR 52.227-19.
29*c14be686SAndroid Build Coastguard Worker 
30*c14be686SAndroid Build Coastguard Worker This code may be protected by one or more U.S. and International
31*c14be686SAndroid Build Coastguard Worker Patents.
32*c14be686SAndroid Build Coastguard Worker 
33*c14be686SAndroid Build Coastguard Worker */
34*c14be686SAndroid Build Coastguard Worker 
35*c14be686SAndroid Build Coastguard Worker #include "CVTUTF7.H"
36*c14be686SAndroid Build Coastguard Worker 
37*c14be686SAndroid Build Coastguard Worker static char base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
38*c14be686SAndroid Build Coastguard Worker static short invbase64[128];
39*c14be686SAndroid Build Coastguard Worker 
40*c14be686SAndroid Build Coastguard Worker static char direct[] =
41*c14be686SAndroid Build Coastguard Worker 	"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'(),-./:?";
42*c14be686SAndroid Build Coastguard Worker static char optional[] = "!\"#$%&*;<=>@[]^_`{|}";
43*c14be686SAndroid Build Coastguard Worker static char spaces[] = " \011\015\012";		/* space, tab, return, line feed */
44*c14be686SAndroid Build Coastguard Worker static char mustshiftsafe[128];
45*c14be686SAndroid Build Coastguard Worker static char mustshiftopt[128];
46*c14be686SAndroid Build Coastguard Worker 
47*c14be686SAndroid Build Coastguard Worker static int needtables = 1;
48*c14be686SAndroid Build Coastguard Worker 
49*c14be686SAndroid Build Coastguard Worker #define SHIFT_IN '+'
50*c14be686SAndroid Build Coastguard Worker #define SHIFT_OUT '-'
51*c14be686SAndroid Build Coastguard Worker 
52*c14be686SAndroid Build Coastguard Worker static void
tabinit()53*c14be686SAndroid Build Coastguard Worker tabinit()
54*c14be686SAndroid Build Coastguard Worker {
55*c14be686SAndroid Build Coastguard Worker 	int i, limit;
56*c14be686SAndroid Build Coastguard Worker 
57*c14be686SAndroid Build Coastguard Worker 	for (i = 0; i < 128; ++i)
58*c14be686SAndroid Build Coastguard Worker 	{
59*c14be686SAndroid Build Coastguard Worker 		mustshiftopt[i] = mustshiftsafe[i] = 1;
60*c14be686SAndroid Build Coastguard Worker 		invbase64[i] = -1;
61*c14be686SAndroid Build Coastguard Worker 	}
62*c14be686SAndroid Build Coastguard Worker 	limit = strlen(direct);
63*c14be686SAndroid Build Coastguard Worker 	for (i = 0; i < limit; ++i)
64*c14be686SAndroid Build Coastguard Worker 		mustshiftopt[direct[i]] = mustshiftsafe[direct[i]] = 0;
65*c14be686SAndroid Build Coastguard Worker 	limit = strlen(spaces);
66*c14be686SAndroid Build Coastguard Worker 	for (i = 0; i < limit; ++i)
67*c14be686SAndroid Build Coastguard Worker 		mustshiftopt[spaces[i]] = mustshiftsafe[spaces[i]] = 0;
68*c14be686SAndroid Build Coastguard Worker 	limit = strlen(optional);
69*c14be686SAndroid Build Coastguard Worker 	for (i = 0; i < limit; ++i)
70*c14be686SAndroid Build Coastguard Worker 		mustshiftopt[optional[i]] = 0;
71*c14be686SAndroid Build Coastguard Worker 	limit = strlen(base64);
72*c14be686SAndroid Build Coastguard Worker 	for (i = 0; i < limit; ++i)
73*c14be686SAndroid Build Coastguard Worker 		invbase64[base64[i]] = i;
74*c14be686SAndroid Build Coastguard Worker 
75*c14be686SAndroid Build Coastguard Worker 	needtables = 0;
76*c14be686SAndroid Build Coastguard Worker }
77*c14be686SAndroid Build Coastguard Worker 
78*c14be686SAndroid Build Coastguard Worker #define DECLARE_BIT_BUFFER register unsigned long BITbuffer = 0, buffertemp = 0; int bufferbits = 0
79*c14be686SAndroid Build Coastguard Worker #define BITS_IN_BUFFER bufferbits
80*c14be686SAndroid Build Coastguard Worker #define WRITE_N_BITS(x, n) ((BITbuffer |= ( ((x) & ~(-1L<<(n))) << (32-(n)-bufferbits) ) ), bufferbits += (n) )
81*c14be686SAndroid Build Coastguard Worker #define READ_N_BITS(n) ((buffertemp = (BITbuffer >> (32-(n)))), (BITbuffer <<= (n)), (bufferbits -= (n)), buffertemp)
82*c14be686SAndroid Build Coastguard Worker #define TARGETCHECK  {if (target >= targetEnd) {result = targetExhausted; break;}}
83*c14be686SAndroid Build Coastguard Worker 
ConvertUCS2toUTF7(UCS2 ** sourceStart,UCS2 * sourceEnd,char ** targetStart,char * targetEnd,int optional,int verbose)84*c14be686SAndroid Build Coastguard Worker ConversionResult ConvertUCS2toUTF7(
85*c14be686SAndroid Build Coastguard Worker                 UCS2** sourceStart, UCS2* sourceEnd,
86*c14be686SAndroid Build Coastguard Worker                 char** targetStart, char* targetEnd,
87*c14be686SAndroid Build Coastguard Worker                 int optional, int verbose)
88*c14be686SAndroid Build Coastguard Worker {
89*c14be686SAndroid Build Coastguard Worker 	ConversionResult result = ok;
90*c14be686SAndroid Build Coastguard Worker 	DECLARE_BIT_BUFFER;
91*c14be686SAndroid Build Coastguard Worker 	int shifted = 0, needshift = 0, done = 0;
92*c14be686SAndroid Build Coastguard Worker 	register UCS2 *source = *sourceStart;
93*c14be686SAndroid Build Coastguard Worker 	register char *target = *targetStart;
94*c14be686SAndroid Build Coastguard Worker 	char *mustshift;
95*c14be686SAndroid Build Coastguard Worker 
96*c14be686SAndroid Build Coastguard Worker 	if (needtables)
97*c14be686SAndroid Build Coastguard Worker 		tabinit();
98*c14be686SAndroid Build Coastguard Worker 
99*c14be686SAndroid Build Coastguard Worker 	if (optional)
100*c14be686SAndroid Build Coastguard Worker 		mustshift = mustshiftopt;
101*c14be686SAndroid Build Coastguard Worker 	else
102*c14be686SAndroid Build Coastguard Worker 		mustshift = mustshiftsafe;
103*c14be686SAndroid Build Coastguard Worker 
104*c14be686SAndroid Build Coastguard Worker 	do
105*c14be686SAndroid Build Coastguard Worker 	{
106*c14be686SAndroid Build Coastguard Worker 		register UCS2 r;
107*c14be686SAndroid Build Coastguard Worker 
108*c14be686SAndroid Build Coastguard Worker 		if (!(done = (source >= sourceEnd)))
109*c14be686SAndroid Build Coastguard Worker 			r = *source++;
110*c14be686SAndroid Build Coastguard Worker 		needshift = (!done && ((r > 0x7f) || mustshift[r]));
111*c14be686SAndroid Build Coastguard Worker 
112*c14be686SAndroid Build Coastguard Worker 		if (needshift && !shifted)
113*c14be686SAndroid Build Coastguard Worker 		{
114*c14be686SAndroid Build Coastguard Worker 			TARGETCHECK;
115*c14be686SAndroid Build Coastguard Worker 			*target++ = SHIFT_IN;
116*c14be686SAndroid Build Coastguard Worker 			/* Special case handling of the SHIFT_IN character */
117*c14be686SAndroid Build Coastguard Worker 			if (r == (UCS2)SHIFT_IN) {
118*c14be686SAndroid Build Coastguard Worker 				TARGETCHECK;
119*c14be686SAndroid Build Coastguard Worker 				*target++ = SHIFT_OUT;
120*c14be686SAndroid Build Coastguard Worker 			}
121*c14be686SAndroid Build Coastguard Worker 			else
122*c14be686SAndroid Build Coastguard Worker 				shifted = 1;
123*c14be686SAndroid Build Coastguard Worker 		}
124*c14be686SAndroid Build Coastguard Worker 
125*c14be686SAndroid Build Coastguard Worker 		if (shifted)
126*c14be686SAndroid Build Coastguard Worker 		{
127*c14be686SAndroid Build Coastguard Worker 			/* Either write the character to the bit buffer, or pad
128*c14be686SAndroid Build Coastguard Worker 			   the bit buffer out to a full base64 character.
129*c14be686SAndroid Build Coastguard Worker 			 */
130*c14be686SAndroid Build Coastguard Worker 			if (needshift)
131*c14be686SAndroid Build Coastguard Worker 				WRITE_N_BITS(r, 16);
132*c14be686SAndroid Build Coastguard Worker 			else
133*c14be686SAndroid Build Coastguard Worker 				WRITE_N_BITS(0, (6 - (BITS_IN_BUFFER % 6))%6);
134*c14be686SAndroid Build Coastguard Worker 
135*c14be686SAndroid Build Coastguard Worker 			/* Flush out as many full base64 characters as possible
136*c14be686SAndroid Build Coastguard Worker 			   from the bit buffer.
137*c14be686SAndroid Build Coastguard Worker 			 */
138*c14be686SAndroid Build Coastguard Worker 			while ((target < targetEnd) && BITS_IN_BUFFER >= 6)
139*c14be686SAndroid Build Coastguard Worker 			{
140*c14be686SAndroid Build Coastguard Worker 				*target++ = base64[READ_N_BITS(6)];
141*c14be686SAndroid Build Coastguard Worker 			}
142*c14be686SAndroid Build Coastguard Worker 
143*c14be686SAndroid Build Coastguard Worker 			if (BITS_IN_BUFFER >= 6)
144*c14be686SAndroid Build Coastguard Worker 				TARGETCHECK;
145*c14be686SAndroid Build Coastguard Worker 
146*c14be686SAndroid Build Coastguard Worker 			if (!needshift)
147*c14be686SAndroid Build Coastguard Worker 			{
148*c14be686SAndroid Build Coastguard Worker 				/* Write the explicit shift out character if
149*c14be686SAndroid Build Coastguard Worker 				   1) The caller has requested we always do it, or
150*c14be686SAndroid Build Coastguard Worker 				   2) The directly encoded character is in the
151*c14be686SAndroid Build Coastguard Worker 				   base64 set, or
152*c14be686SAndroid Build Coastguard Worker 				   3) The directly encoded character is SHIFT_OUT.
153*c14be686SAndroid Build Coastguard Worker 				 */
154*c14be686SAndroid Build Coastguard Worker 				if (verbose || ((!done) && (invbase64[r] >=0 || r == SHIFT_OUT)))
155*c14be686SAndroid Build Coastguard Worker 				{
156*c14be686SAndroid Build Coastguard Worker 					TARGETCHECK;
157*c14be686SAndroid Build Coastguard Worker 					*target++ = SHIFT_OUT;
158*c14be686SAndroid Build Coastguard Worker 				}
159*c14be686SAndroid Build Coastguard Worker 				shifted = 0;
160*c14be686SAndroid Build Coastguard Worker 			}
161*c14be686SAndroid Build Coastguard Worker 		}
162*c14be686SAndroid Build Coastguard Worker 
163*c14be686SAndroid Build Coastguard Worker 		/* The character can be directly encoded as ASCII. */
164*c14be686SAndroid Build Coastguard Worker 		if (!needshift && !done)
165*c14be686SAndroid Build Coastguard Worker 		{
166*c14be686SAndroid Build Coastguard Worker 			TARGETCHECK;
167*c14be686SAndroid Build Coastguard Worker 			*target++ = (char) r;
168*c14be686SAndroid Build Coastguard Worker 		}
169*c14be686SAndroid Build Coastguard Worker 
170*c14be686SAndroid Build Coastguard Worker 	}
171*c14be686SAndroid Build Coastguard Worker 	while (!done);
172*c14be686SAndroid Build Coastguard Worker 
173*c14be686SAndroid Build Coastguard Worker     *sourceStart = source;
174*c14be686SAndroid Build Coastguard Worker     *targetStart = target;
175*c14be686SAndroid Build Coastguard Worker     return result;
176*c14be686SAndroid Build Coastguard Worker }
177*c14be686SAndroid Build Coastguard Worker 
ConvertUTF7toUCS2(char ** sourceStart,char * sourceEnd,UCS2 ** targetStart,UCS2 * targetEnd)178*c14be686SAndroid Build Coastguard Worker ConversionResult ConvertUTF7toUCS2(
179*c14be686SAndroid Build Coastguard Worker                 char** sourceStart, char* sourceEnd,
180*c14be686SAndroid Build Coastguard Worker                 UCS2** targetStart, UCS2* targetEnd)
181*c14be686SAndroid Build Coastguard Worker {
182*c14be686SAndroid Build Coastguard Worker 	ConversionResult result = ok;
183*c14be686SAndroid Build Coastguard Worker 	DECLARE_BIT_BUFFER;
184*c14be686SAndroid Build Coastguard Worker 	int shifted = 0, first = 0, wroteone = 0, base64EOF, base64value, done;
185*c14be686SAndroid Build Coastguard Worker 	unsigned int c, prevc;
186*c14be686SAndroid Build Coastguard Worker 	unsigned long junk;
187*c14be686SAndroid Build Coastguard Worker 	register char *source = *sourceStart;
188*c14be686SAndroid Build Coastguard Worker 	register UCS2 *target = *targetStart;
189*c14be686SAndroid Build Coastguard Worker 
190*c14be686SAndroid Build Coastguard Worker 	if (needtables)
191*c14be686SAndroid Build Coastguard Worker 		tabinit();
192*c14be686SAndroid Build Coastguard Worker 
193*c14be686SAndroid Build Coastguard Worker 	do
194*c14be686SAndroid Build Coastguard Worker 	{
195*c14be686SAndroid Build Coastguard Worker 		/* read an ASCII character c */
196*c14be686SAndroid Build Coastguard Worker 		if (!(done = (source >= sourceEnd)))
197*c14be686SAndroid Build Coastguard Worker 			c = *source++;
198*c14be686SAndroid Build Coastguard Worker 		if (shifted)
199*c14be686SAndroid Build Coastguard Worker 		{
200*c14be686SAndroid Build Coastguard Worker 			/* We're done with a base64 string if we hit EOF, it's not a valid
201*c14be686SAndroid Build Coastguard Worker 			   ASCII character, or it's not in the base64 set.
202*c14be686SAndroid Build Coastguard Worker 			 */
203*c14be686SAndroid Build Coastguard Worker 			base64EOF = done || (c > 0x7f) || (base64value = invbase64[c]) < 0;
204*c14be686SAndroid Build Coastguard Worker 			if (base64EOF)
205*c14be686SAndroid Build Coastguard Worker 			{
206*c14be686SAndroid Build Coastguard Worker 				shifted = 0;
207*c14be686SAndroid Build Coastguard Worker 				/* If the character causing us to drop out was SHIFT_IN or
208*c14be686SAndroid Build Coastguard Worker 				   SHIFT_OUT, it may be a special escape for SHIFT_IN. The
209*c14be686SAndroid Build Coastguard Worker 				   test for SHIFT_IN is not necessary, but allows an alternate
210*c14be686SAndroid Build Coastguard Worker 				   form of UTF-7 where SHIFT_IN is escaped by SHIFT_IN. This
211*c14be686SAndroid Build Coastguard Worker 				   only works for some values of SHIFT_IN.
212*c14be686SAndroid Build Coastguard Worker 				 */
213*c14be686SAndroid Build Coastguard Worker 				if (!done && (c == SHIFT_IN || c == SHIFT_OUT))
214*c14be686SAndroid Build Coastguard Worker 				{
215*c14be686SAndroid Build Coastguard Worker 					/* get another character c */
216*c14be686SAndroid Build Coastguard Worker 					prevc = c;
217*c14be686SAndroid Build Coastguard Worker 					if (!(done = (source >= sourceEnd)))
218*c14be686SAndroid Build Coastguard Worker 						c = *source++;
219*c14be686SAndroid Build Coastguard Worker 					/* If no base64 characters were encountered, and the
220*c14be686SAndroid Build Coastguard Worker 					   character terminating the shift sequence was
221*c14be686SAndroid Build Coastguard Worker 					   SHIFT_OUT, then it's a special escape for SHIFT_IN.
222*c14be686SAndroid Build Coastguard Worker 					 */
223*c14be686SAndroid Build Coastguard Worker 					if (first && prevc == SHIFT_OUT)
224*c14be686SAndroid Build Coastguard Worker 					{
225*c14be686SAndroid Build Coastguard Worker 						/* write SHIFT_IN unicode */
226*c14be686SAndroid Build Coastguard Worker 						TARGETCHECK;
227*c14be686SAndroid Build Coastguard Worker 						*target++ = (UCS2)SHIFT_IN;
228*c14be686SAndroid Build Coastguard Worker 					}
229*c14be686SAndroid Build Coastguard Worker 					else if (!wroteone)
230*c14be686SAndroid Build Coastguard Worker 					{
231*c14be686SAndroid Build Coastguard Worker 						result = sourceCorrupt;
232*c14be686SAndroid Build Coastguard Worker 						/* fprintf(stderr, "UTF7: empty sequence near byte %ld in input\n", source-sourceStart) */;
233*c14be686SAndroid Build Coastguard Worker 					}
234*c14be686SAndroid Build Coastguard Worker 				}
235*c14be686SAndroid Build Coastguard Worker 				else if (!wroteone)
236*c14be686SAndroid Build Coastguard Worker 				{
237*c14be686SAndroid Build Coastguard Worker 					result = sourceCorrupt;
238*c14be686SAndroid Build Coastguard Worker 					/* fprintf(stderr, "UTF7: empty sequence near byte %ld in input\n", source-sourceStart) */;
239*c14be686SAndroid Build Coastguard Worker 				}
240*c14be686SAndroid Build Coastguard Worker 			}
241*c14be686SAndroid Build Coastguard Worker 			else
242*c14be686SAndroid Build Coastguard Worker 			{
243*c14be686SAndroid Build Coastguard Worker 				/* Add another 6 bits of base64 to the bit buffer. */
244*c14be686SAndroid Build Coastguard Worker 				WRITE_N_BITS(base64value, 6);
245*c14be686SAndroid Build Coastguard Worker 				first = 0;
246*c14be686SAndroid Build Coastguard Worker 			}
247*c14be686SAndroid Build Coastguard Worker 
248*c14be686SAndroid Build Coastguard Worker 			/* Extract as many full 16 bit characters as possible from the
249*c14be686SAndroid Build Coastguard Worker 			   bit buffer.
250*c14be686SAndroid Build Coastguard Worker 			 */
251*c14be686SAndroid Build Coastguard Worker 			while (BITS_IN_BUFFER >= 16 && (target < targetEnd))
252*c14be686SAndroid Build Coastguard Worker 			{
253*c14be686SAndroid Build Coastguard Worker 				/* write a unicode */
254*c14be686SAndroid Build Coastguard Worker 				*target++ = READ_N_BITS(16);
255*c14be686SAndroid Build Coastguard Worker 				wroteone = 1;
256*c14be686SAndroid Build Coastguard Worker 			}
257*c14be686SAndroid Build Coastguard Worker 
258*c14be686SAndroid Build Coastguard Worker 			if (BITS_IN_BUFFER >= 16)
259*c14be686SAndroid Build Coastguard Worker 				TARGETCHECK;
260*c14be686SAndroid Build Coastguard Worker 
261*c14be686SAndroid Build Coastguard Worker 			if (base64EOF)
262*c14be686SAndroid Build Coastguard Worker 			{
263*c14be686SAndroid Build Coastguard Worker 				junk = READ_N_BITS(BITS_IN_BUFFER);
264*c14be686SAndroid Build Coastguard Worker 				if (junk)
265*c14be686SAndroid Build Coastguard Worker 				{
266*c14be686SAndroid Build Coastguard Worker 					result = sourceCorrupt;
267*c14be686SAndroid Build Coastguard Worker 					/* fprintf(stderr, "UTF7: non-zero pad bits near byte %ld in input\n", source-sourceStart) */;
268*c14be686SAndroid Build Coastguard Worker 				}
269*c14be686SAndroid Build Coastguard Worker 			}
270*c14be686SAndroid Build Coastguard Worker 		}
271*c14be686SAndroid Build Coastguard Worker 
272*c14be686SAndroid Build Coastguard Worker 		if (!shifted && !done)
273*c14be686SAndroid Build Coastguard Worker 		{
274*c14be686SAndroid Build Coastguard Worker 			if (c == SHIFT_IN)
275*c14be686SAndroid Build Coastguard Worker 			{
276*c14be686SAndroid Build Coastguard Worker 				shifted = 1;
277*c14be686SAndroid Build Coastguard Worker 				first = 1;
278*c14be686SAndroid Build Coastguard Worker 				wroteone = 0;
279*c14be686SAndroid Build Coastguard Worker 			}
280*c14be686SAndroid Build Coastguard Worker 			else
281*c14be686SAndroid Build Coastguard Worker 			{
282*c14be686SAndroid Build Coastguard Worker 				/* It must be a directly encoded character. */
283*c14be686SAndroid Build Coastguard Worker 				if (c > 0x7f)
284*c14be686SAndroid Build Coastguard Worker 				{
285*c14be686SAndroid Build Coastguard Worker 					result = sourceCorrupt;
286*c14be686SAndroid Build Coastguard Worker 					/* fprintf(stderr, "UTF7: non-ASCII character near byte %ld in input\n", source-sourceStart) */;
287*c14be686SAndroid Build Coastguard Worker 				}
288*c14be686SAndroid Build Coastguard Worker 				/* write a unicode */
289*c14be686SAndroid Build Coastguard Worker 				TARGETCHECK;
290*c14be686SAndroid Build Coastguard Worker 				*target++ = c;
291*c14be686SAndroid Build Coastguard Worker 			}
292*c14be686SAndroid Build Coastguard Worker 		}
293*c14be686SAndroid Build Coastguard Worker 	}
294*c14be686SAndroid Build Coastguard Worker 	while (!done);
295*c14be686SAndroid Build Coastguard Worker 
296*c14be686SAndroid Build Coastguard Worker     *sourceStart = source;
297*c14be686SAndroid Build Coastguard Worker     *targetStart = target;
298*c14be686SAndroid Build Coastguard Worker     return result;
299*c14be686SAndroid Build Coastguard Worker }
300