2 *****************************************************************************
4 * Copyright (C) 1998-2004, International Business Machines
5 * Corporation and others. All Rights Reserved.
7 *****************************************************************************
10 * Implements error behaviour functions called by T_UConverter_{from,to}Unicode
15 * 06/29/2000 helena Major rewrite of the callback APIs.
18 #include "unicode/utypes.h"
20 #if !UCONFIG_NO_CONVERSION
22 #include "unicode/ucnv_err.h"
23 #include "unicode/ucnv_cb.h"
26 #include "unicode/ucnv.h"
29 #define VALUE_STRING_LENGTH 32
30 /*Magic # 32 = 4(number of char in value string) * 8(max number of bytes per char for any converter) */
31 #define UNICODE_PERCENT_SIGN_CODEPOINT 0x0025
32 #define UNICODE_U_CODEPOINT 0x0055
33 #define UNICODE_X_CODEPOINT 0x0058
34 #define UNICODE_RS_CODEPOINT 0x005C
35 #define UNICODE_U_LOW_CODEPOINT 0x0075
36 #define UNICODE_X_LOW_CODEPOINT 0x0078
37 #define UNICODE_AMP_CODEPOINT 0x0026
38 #define UNICODE_HASH_CODEPOINT 0x0023
39 #define UNICODE_SEMICOLON_CODEPOINT 0x003B
40 #define UNICODE_PLUS_CODEPOINT 0x002B
41 #define UNICODE_LEFT_CURLY_CODEPOINT 0x007B
42 #define UNICODE_RIGHT_CURLY_CODEPOINT 0x007D
43 #define UCNV_PRV_ESCAPE_ICU 0
44 #define UCNV_PRV_ESCAPE_C 'C'
45 #define UCNV_PRV_ESCAPE_XML_DEC 'D'
46 #define UCNV_PRV_ESCAPE_XML_HEX 'X'
47 #define UCNV_PRV_ESCAPE_JAVA 'J'
48 #define UCNV_PRV_ESCAPE_UNICODE 'U'
50 /*Function Pointer STOPS at the ILLEGAL_SEQUENCE */
52 UCNV_FROM_U_CALLBACK_STOP (
54 UConverterFromUnicodeArgs
*fromUArgs
,
55 const UChar
* codeUnits
,
58 UConverterCallbackReason reason
,
61 /* the caller must have set the error code accordingly */
66 /*Function Pointer STOPS at the ILLEGAL_SEQUENCE */
68 UCNV_TO_U_CALLBACK_STOP (
70 UConverterToUnicodeArgs
*toUArgs
,
71 const char* codePoints
,
73 UConverterCallbackReason reason
,
76 /* the caller must have set the error code accordingly */
81 UCNV_FROM_U_CALLBACK_SKIP (
83 UConverterFromUnicodeArgs
*fromUArgs
,
84 const UChar
* codeUnits
,
87 UConverterCallbackReason reason
,
92 if (reason
<= UCNV_IRREGULAR
)
99 else if(*(char*)context
=='i')
101 if(reason
!= UCNV_UNASSIGNED
)
103 /* the caller must have set
104 * the error code accordingly
116 U_CAPI
void U_EXPORT2
117 UCNV_FROM_U_CALLBACK_SUBSTITUTE (
119 UConverterFromUnicodeArgs
*fromArgs
,
120 const UChar
* codeUnits
,
123 UConverterCallbackReason reason
,
128 if (reason
> UCNV_IRREGULAR
)
134 ucnv_cbFromUWriteSub(fromArgs
, 0, err
);
137 else if(*((char*)context
)=='i')
139 if(reason
!= UCNV_UNASSIGNED
)
141 /* the caller must have set
142 * the error code accordingly
149 ucnv_cbFromUWriteSub(fromArgs
, 0, err
);
155 /*uses uprv_itou to get a unicode escape sequence of the offensive sequence,
156 *uses a clean copy (resetted) of the converter, to convert that unicode
157 *escape sequence to the target codepage (if conversion failure happens then
158 *we revert to substituting with subchar)
160 U_CAPI
void U_EXPORT2
161 UCNV_FROM_U_CALLBACK_ESCAPE (
163 UConverterFromUnicodeArgs
*fromArgs
,
164 const UChar
*codeUnits
,
167 UConverterCallbackReason reason
,
171 UChar valueString
[VALUE_STRING_LENGTH
];
172 int32_t valueStringLength
= 0;
175 const UChar
*myValueSource
= NULL
;
176 UErrorCode err2
= U_ZERO_ERROR
;
177 UConverterFromUCallback original
= NULL
;
178 const void *originalContext
;
180 UConverterFromUCallback ignoredCallback
= NULL
;
181 const void *ignoredContext
;
183 if (reason
> UCNV_IRREGULAR
)
188 ucnv_setFromUCallBack (fromArgs
->converter
,
189 (UConverterFromUCallback
) UCNV_FROM_U_CALLBACK_SUBSTITUTE
,
195 if (U_FAILURE (err2
))
204 valueString
[valueStringLength
++] = (UChar
) UNICODE_PERCENT_SIGN_CODEPOINT
; /* adding % */
205 valueString
[valueStringLength
++] = (UChar
) UNICODE_U_CODEPOINT
; /* adding U */
206 valueStringLength
+= uprv_itou (valueString
+ valueStringLength
, VALUE_STRING_LENGTH
- valueStringLength
, (uint16_t)codeUnits
[i
++], 16, 4);
211 switch(*((char*)context
))
213 case UCNV_PRV_ESCAPE_JAVA
:
216 valueString
[valueStringLength
++] = (UChar
) UNICODE_RS_CODEPOINT
; /* adding \ */
217 valueString
[valueStringLength
++] = (UChar
) UNICODE_U_LOW_CODEPOINT
; /* adding u */
218 valueStringLength
+= uprv_itou (valueString
+ valueStringLength
, VALUE_STRING_LENGTH
- valueStringLength
, (uint16_t)codeUnits
[i
++], 16, 4);
222 case UCNV_PRV_ESCAPE_C
:
223 valueString
[valueStringLength
++] = (UChar
) UNICODE_RS_CODEPOINT
; /* adding \ */
226 valueString
[valueStringLength
++] = (UChar
) UNICODE_U_CODEPOINT
; /* adding U */
227 valueStringLength
+= uprv_itou (valueString
+ valueStringLength
, VALUE_STRING_LENGTH
- valueStringLength
, codePoint
, 16, 8);
231 valueString
[valueStringLength
++] = (UChar
) UNICODE_U_LOW_CODEPOINT
; /* adding u */
232 valueStringLength
+= uprv_itou (valueString
+ valueStringLength
, VALUE_STRING_LENGTH
- valueStringLength
, (uint16_t)codeUnits
[0], 16, 4);
236 case UCNV_PRV_ESCAPE_XML_DEC
:
238 valueString
[valueStringLength
++] = (UChar
) UNICODE_AMP_CODEPOINT
; /* adding & */
239 valueString
[valueStringLength
++] = (UChar
) UNICODE_HASH_CODEPOINT
; /* adding # */
241 valueStringLength
+= uprv_itou (valueString
+ valueStringLength
, VALUE_STRING_LENGTH
- valueStringLength
, codePoint
, 10, 0);
244 valueStringLength
+= uprv_itou (valueString
+ valueStringLength
, VALUE_STRING_LENGTH
- valueStringLength
, (uint16_t)codeUnits
[0], 10, 0);
246 valueString
[valueStringLength
++] = (UChar
) UNICODE_SEMICOLON_CODEPOINT
; /* adding ; */
249 case UCNV_PRV_ESCAPE_XML_HEX
:
251 valueString
[valueStringLength
++] = (UChar
) UNICODE_AMP_CODEPOINT
; /* adding & */
252 valueString
[valueStringLength
++] = (UChar
) UNICODE_HASH_CODEPOINT
; /* adding # */
253 valueString
[valueStringLength
++] = (UChar
) UNICODE_X_LOW_CODEPOINT
; /* adding x */
255 valueStringLength
+= uprv_itou (valueString
+ valueStringLength
, VALUE_STRING_LENGTH
- valueStringLength
, codePoint
, 16, 0);
258 valueStringLength
+= uprv_itou (valueString
+ valueStringLength
, VALUE_STRING_LENGTH
- valueStringLength
, (uint16_t)codeUnits
[0], 16, 0);
260 valueString
[valueStringLength
++] = (UChar
) UNICODE_SEMICOLON_CODEPOINT
; /* adding ; */
263 case UCNV_PRV_ESCAPE_UNICODE
:
264 valueString
[valueStringLength
++] = (UChar
) UNICODE_LEFT_CURLY_CODEPOINT
; /* adding { */
265 valueString
[valueStringLength
++] = (UChar
) UNICODE_U_CODEPOINT
; /* adding U */
266 valueString
[valueStringLength
++] = (UChar
) UNICODE_PLUS_CODEPOINT
; /* adding + */
268 valueStringLength
+= uprv_itou (valueString
+ valueStringLength
, VALUE_STRING_LENGTH
- valueStringLength
, codePoint
, 16, 4);
270 valueStringLength
+= uprv_itou (valueString
+ valueStringLength
, VALUE_STRING_LENGTH
- valueStringLength
, (uint16_t)codeUnits
[0], 16, 4);
272 valueString
[valueStringLength
++] = (UChar
) UNICODE_RIGHT_CURLY_CODEPOINT
; /* adding } */
278 valueString
[valueStringLength
++] = (UChar
) UNICODE_PERCENT_SIGN_CODEPOINT
; /* adding % */
279 valueString
[valueStringLength
++] = (UChar
) UNICODE_U_CODEPOINT
; /* adding U */
280 valueStringLength
+= uprv_itou (valueString
+ valueStringLength
, VALUE_STRING_LENGTH
- valueStringLength
, (uint16_t)codeUnits
[i
++], 16, 4);
285 myValueSource
= valueString
;
287 /* reset the error */
290 ucnv_cbFromUWriteUChars(fromArgs
, &myValueSource
, myValueSource
+valueStringLength
, 0, err
);
292 ucnv_setFromUCallBack (fromArgs
->converter
,
298 if (U_FAILURE (err2
))
309 U_CAPI
void U_EXPORT2
310 UCNV_TO_U_CALLBACK_SKIP (
312 UConverterToUnicodeArgs
*toArgs
,
313 const char* codeUnits
,
315 UConverterCallbackReason reason
,
320 if (reason
<= UCNV_IRREGULAR
)
327 else if(*((char*)context
)=='i')
329 if(reason
!= UCNV_UNASSIGNED
)
331 /* the caller must have set
332 * the error code accordingly
344 U_CAPI
void U_EXPORT2
345 UCNV_TO_U_CALLBACK_SUBSTITUTE (
347 UConverterToUnicodeArgs
*toArgs
,
348 const char* codeUnits
,
350 UConverterCallbackReason reason
,
355 if (reason
> UCNV_IRREGULAR
)
361 ucnv_cbToUWriteSub(toArgs
,0,err
);
364 else if(*((char*)context
)=='i')
366 if(reason
!= UCNV_UNASSIGNED
)
368 /* the caller must have set
369 * the error code accordingly
376 ucnv_cbToUWriteSub(toArgs
,0,err
);
383 /*uses uprv_itou to get a unicode escape sequence of the offensive sequence,
384 *and uses that as the substitution sequence
386 U_CAPI
void U_EXPORT2
387 UCNV_TO_U_CALLBACK_ESCAPE (
389 UConverterToUnicodeArgs
*toArgs
,
390 const char* codeUnits
,
392 UConverterCallbackReason reason
,
395 UChar uniValueString
[VALUE_STRING_LENGTH
];
396 int32_t valueStringLength
= 0;
399 if (reason
> UCNV_IRREGULAR
)
408 uniValueString
[valueStringLength
++] = (UChar
) UNICODE_PERCENT_SIGN_CODEPOINT
; /* adding % */
409 uniValueString
[valueStringLength
++] = (UChar
) UNICODE_X_CODEPOINT
; /* adding X */
410 valueStringLength
+= uprv_itou (uniValueString
+ valueStringLength
, VALUE_STRING_LENGTH
- valueStringLength
, (uint8_t) codeUnits
[i
++], 16, 2);
415 switch(*((char*)context
))
417 case UCNV_PRV_ESCAPE_XML_DEC
:
420 uniValueString
[valueStringLength
++] = (UChar
) UNICODE_AMP_CODEPOINT
; /* adding & */
421 uniValueString
[valueStringLength
++] = (UChar
) UNICODE_HASH_CODEPOINT
; /* adding # */
422 valueStringLength
+= uprv_itou (uniValueString
+ valueStringLength
, VALUE_STRING_LENGTH
- valueStringLength
, (uint8_t)codeUnits
[i
++], 10, 0);
423 uniValueString
[valueStringLength
++] = (UChar
) UNICODE_SEMICOLON_CODEPOINT
; /* adding ; */
427 case UCNV_PRV_ESCAPE_XML_HEX
:
430 uniValueString
[valueStringLength
++] = (UChar
) UNICODE_AMP_CODEPOINT
; /* adding & */
431 uniValueString
[valueStringLength
++] = (UChar
) UNICODE_HASH_CODEPOINT
; /* adding # */
432 uniValueString
[valueStringLength
++] = (UChar
) UNICODE_X_LOW_CODEPOINT
; /* adding x */
433 valueStringLength
+= uprv_itou (uniValueString
+ valueStringLength
, VALUE_STRING_LENGTH
- valueStringLength
, (uint8_t)codeUnits
[i
++], 16, 0);
434 uniValueString
[valueStringLength
++] = (UChar
) UNICODE_SEMICOLON_CODEPOINT
; /* adding ; */
437 case UCNV_PRV_ESCAPE_C
:
440 uniValueString
[valueStringLength
++] = (UChar
) UNICODE_RS_CODEPOINT
; /* adding \ */
441 uniValueString
[valueStringLength
++] = (UChar
) UNICODE_X_LOW_CODEPOINT
; /* adding x */
442 valueStringLength
+= uprv_itou (uniValueString
+ valueStringLength
, VALUE_STRING_LENGTH
- valueStringLength
, (uint8_t)codeUnits
[i
++], 16, 2);
448 uniValueString
[valueStringLength
++] = (UChar
) UNICODE_PERCENT_SIGN_CODEPOINT
; /* adding % */
449 uniValueString
[valueStringLength
++] = (UChar
) UNICODE_X_CODEPOINT
; /* adding X */
450 uprv_itou (uniValueString
+ valueStringLength
, VALUE_STRING_LENGTH
- valueStringLength
, (uint8_t) codeUnits
[i
++], 16, 2);
451 valueStringLength
+= 2;
455 /* reset the error */
458 ucnv_cbToUWriteUChars(toArgs
, uniValueString
, valueStringLength
, 0, err
);