001: /**
002: *******************************************************************************
003: * Copyright (C) 2006, International Business Machines Corporation and *
004: * others. All Rights Reserved. *
005: *******************************************************************************
006: *
007: *******************************************************************************
008: */package com.ibm.icu.charset;
009:
010: import java.nio.ByteBuffer;
011: import java.nio.CharBuffer;
012: import java.nio.IntBuffer;
013: import java.nio.charset.CoderResult;
014:
015: /**
016: * <h2> Callback API for CharsetICU API </h2>
017: *
018: * CharsetCallback class defines some error behaviour functions called
019: * by CharsetDecoderICU and CharsetEncoderICU. The class also provides
020: * the facility by which clients can write their own callbacks.
021: *
022: * These functions, although public, should NEVER be called directly.
023: * They should be used as parameters to the onUmappableCharacter() and
024: * onMalformedInput() methods, to set the behaviour of a converter
025: * when it encounters UNMAPPED/INVALID sequences.
026: * Currently the only way to set callbacks is by using CodingErrorAction.
027: * In the future we will provide set methods on CharsetEncoder and CharsetDecoder
028: * that will accept CharsetCallback fields.
029: *
030: * @draft ICU 3.6
031: * @provisional This API might change or be removed in a future release.
032: */
033:
034: /*public*/class CharsetCallback {
035: /**
036: * FROM_U, TO_U context options for sub callback
037: * @draft ICU 3.6
038: * @provisional This API might change or be removed in a future release.
039: */
040: /*public*/static final String SUB_STOP_ON_ILLEGAL = "i";
041:
042: /**
043: * FROM_U, TO_U context options for skip callback
044: * @draft ICU 3.6
045: * @provisional This API might change or be removed in a future release.
046: */
047: /*public*/static final String SKIP_STOP_ON_ILLEGAL = "i";
048:
049: /**
050: * FROM_U_CALLBACK_ESCAPE context option to escape the code unit according to ICU (%UXXXX)
051: * @draft ICU 3.6
052: */
053: /*public*/static final String ESCAPE_ICU = null;
054: /**
055: * FROM_U_CALLBACK_ESCAPE context option to escape the code unit according to JAVA (\\uXXXX)
056: * @draft ICU 3.6
057: */
058: /*public*/static final String ESCAPE_JAVA = "J";
059: /**
060: * FROM_U_CALLBACK_ESCAPE context option to escape the code unit according to C (\\uXXXX \\UXXXXXXXX)
061: * TO_U_CALLBACK_ESCAPE option to escape the character value accoding to C (\\xXXXX)
062: * @draft ICU 3.6
063: * @provisional This API might change or be removed in a future release.
064: */
065: /*public*/static final String ESCAPE_C = "C";
066: /**
067: * FROM_U_CALLBACK_ESCAPE context option to escape the code unit according to XML Decimal escape \htmlonly(&#DDDD;)\endhtmlonly
068: * TO_U_CALLBACK_ESCAPE context option to escape the character value accoding to XML Decimal escape \htmlonly(&#DDDD;)\endhtmlonly
069: * @draft ICU 3.6
070: * @provisional This API might change or be removed in a future release.
071: */
072: /*public*/static final String ESCAPE_XML_DEC = "D";
073: /**
074: * FROM_U_CALLBACK_ESCAPE context option to escape the code unit according to XML Hex escape \htmlonly(&#xXXXX;)\endhtmlonly
075: * TO_U_CALLBACK_ESCAPE context option to escape the character value accoding to XML Hex escape \htmlonly(&#xXXXX;)\endhtmlonly
076: * @draft ICU 3.6
077: * @provisional This API might change or be removed in a future release.
078: */
079: /*public*/static final String ESCAPE_XML_HEX = "X";
080: /**
081: * FROM_U_CALLBACK_ESCAPE context option to escape teh code unit according to Unicode (U+XXXXX)
082: * @draft ICU 3.6
083: * @provisional This API might change or be removed in a future release.
084: */
085: /*public*/static final String ESCAPE_UNICODE = "U";
086:
087: /**
088: * Decoder Callback interface
089: * @draft ICU 3.6
090: * @provisional This API might change or be removed in a future release.
091: */
092: public interface Decoder {
093: /**
094: * This function is called when the bytes in the source cannot be handled,
095: * and this function is meant to handle or fix the error if possible.
096: *
097: * @return Result of decoding action. This returned object is set to an error
098: * if this function could not handle the conversion.
099: * @draft ICU 3.6
100: * @provisional This API might change or be removed in a future release.
101: */
102: public CoderResult call(CharsetDecoderICU decoder,
103: Object context, ByteBuffer source, CharBuffer target,
104: IntBuffer offsets, char[] buffer, int length,
105: CoderResult cr);
106: }
107:
108: /**
109: * Encoder Callback interface
110: * @draft ICU 3.6
111: * @provisional This API might change or be removed in a future release.
112: */
113: public interface Encoder {
114: /**
115: * This function is called when the Unicode characters in the source cannot be handled,
116: * and this function is meant to handle or fix the error if possible.
117: * @return Result of decoding action. This returned object is set to an error
118: * if this function could not handle the conversion.
119: * @draft ICU 3.6
120: * @provisional This API might change or be removed in a future release.
121: */
122: public CoderResult call(CharsetEncoderICU encoder,
123: Object context, CharBuffer source, ByteBuffer target,
124: IntBuffer offsets, char[] buffer, int length, int cp,
125: CoderResult cr);
126: }
127:
128: /**
129: * Skip callback
130: * @draft ICU 3.6
131: * @provisional This API might change or be removed in a future release.
132: */
133: public static final Encoder FROM_U_CALLBACK_SKIP = new Encoder() {
134: public CoderResult call(CharsetEncoderICU encoder,
135: Object context, CharBuffer source, ByteBuffer target,
136: IntBuffer offsets, char[] buffer, int length, int cp,
137: CoderResult cr) {
138: if (context == null) {
139: return CoderResult.UNDERFLOW;
140: } else if (((String) context).equals(SUB_STOP_ON_ILLEGAL)) {
141: if (!cr.isUnmappable()) {
142: return cr;
143: } else {
144: return CoderResult.UNDERFLOW;
145: }
146: }
147: return cr;
148: }
149: };
150: /**
151: * Skip callback
152: * @draft ICU 3.6
153: * @provisional This API might change or be removed in a future release.
154: */
155: public static final Decoder TO_U_CALLBACK_SKIP = new Decoder() {
156: public CoderResult call(CharsetDecoderICU decoder,
157: Object context, ByteBuffer source, CharBuffer target,
158: IntBuffer offsets, char[] buffer, int length,
159: CoderResult cr) {
160: if (context == null) {
161: return CoderResult.UNDERFLOW;
162: } else if (((String) context).equals(SUB_STOP_ON_ILLEGAL)) {
163: if (!cr.isUnmappable()) {
164: return cr;
165: } else {
166: return CoderResult.UNDERFLOW;
167: }
168: }
169: return cr;
170: }
171: };
172: /**
173: * Skip callback
174: * @draft ICU 3.6
175: * @provisional This API might change or be removed in a future release.
176: */
177: public static final Encoder FROM_U_CALLBACK_SUBSTITUTE = new Encoder() {
178: public CoderResult call(CharsetEncoderICU encoder,
179: Object context, CharBuffer source, ByteBuffer target,
180: IntBuffer offsets, char[] buffer, int length, int cp,
181: CoderResult cr) {
182: if (context == null) {
183: return encoder.cbFromUWriteSub(encoder, source, target,
184: offsets);
185: } else if (((String) context).equals(SUB_STOP_ON_ILLEGAL)) {
186: if (!cr.isUnmappable()) {
187: return cr;
188: } else {
189: return encoder.cbFromUWriteSub(encoder, source,
190: target, offsets);
191: }
192: }
193: return cr;
194: }
195: };
196: /**
197: * Skip callback
198: * @draft ICU 3.6
199: * @provisional This API might change or be removed in a future release.
200: */
201: public static final Decoder TO_U_CALLBACK_SUBSTITUTE = new Decoder() {
202: public CoderResult call(CharsetDecoderICU decoder,
203: Object context, ByteBuffer source, CharBuffer target,
204: IntBuffer offsets, char[] buffer, int length,
205: CoderResult cr) {
206:
207: char[] kSubstituteChar1 = new char[] { 0x1A };
208: char[] kSubstituteChar = new char[] { 0xFFFD };
209: CharsetICU cs = (CharsetICU) decoder.charset();
210: /* could optimize this case, just one uchar */
211: if (decoder.invalidCharLength == 1 && cs.subChar1 != 0) {
212: return CharsetDecoderICU.toUWriteUChars(decoder,
213: kSubstituteChar1, 0, 1, target, offsets, source
214: .position());
215: } else {
216: return CharsetDecoderICU.toUWriteUChars(decoder,
217: kSubstituteChar, 0, 1, target, offsets, source
218: .position());
219: }
220: }
221: };
222: /**
223: * Skip callback
224: * @draft ICU 3.6
225: * @provisional This API might change or be removed in a future release.
226: */
227: public static final Encoder FROM_U_CALLBACK_STOP = new Encoder() {
228: public CoderResult call(CharsetEncoderICU encoder,
229: Object context, CharBuffer source, ByteBuffer target,
230: IntBuffer offsets, char[] buffer, int length, int cp,
231: CoderResult cr) {
232: return cr;
233: }
234: };
235: /**
236: * Skip callback
237: * @draft ICU 3.6
238: * @provisional This API might change or be removed in a future release.
239: */
240: public static final Decoder TO_U_CALLBACK_STOP = new Decoder() {
241: public CoderResult call(CharsetDecoderICU decoder,
242: Object context, ByteBuffer source, CharBuffer target,
243: IntBuffer offsets, char[] buffer, int length,
244: CoderResult cr) {
245: return cr;
246: }
247: };
248: }
|