001: /* Licensed to the Apache Software Foundation (ASF) under one or more
002: * contributor license agreements. See the NOTICE file distributed with
003: * this work for additional information regarding copyright ownership.
004: * The ASF licenses this file to You under the Apache License, Version 2.0
005: * (the "License"); you may not use this file except in compliance with
006: * the License. You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016:
017: package java.nio.charset;
018:
019: import java.nio.BufferOverflowException;
020: import java.nio.BufferUnderflowException;
021: import java.util.WeakHashMap;
022:
023: import org.apache.harmony.niochar.internal.nls.Messages;
024:
025: /**
026: * Used to indicate the result of encoding/decoding. There are four types of
027: * results:
028: * <ol>
029: * <li>UNDERFLOW indicates all input has been processed, or more input is
030: * required. It is represented by the unique object
031: * <code>CoderResult.UNDERFLOW</code>.
032: * <li>OVERFLOW indicates insufficient output buffer. It is represented by the
033: * unique object <code>CoderResult.OVERFLOW</code>.
034: * <li>A malformed-input error indicates an unrecognizable sequence of input
035: * units has been encountered. Get an instance of this type of result by calling
036: * <code>CoderResult.malformedForLength(int)</code> with the length of the
037: * malformed-input.
038: * <li>An unmappable-character error indicates a sequence of input units can
039: * not be mapped to the output charset. Get an instance of this type of result
040: * by calling <code>CoderResult.unmappableForLength(int)</code> with the input
041: * sequence size indicating the identity of the unmappable character.
042: * </ol>
043: *
044: */
045: public class CoderResult {
046:
047: // indicating underflow error type
048: private static final int TYPE_UNDERFLOW = 1;
049:
050: // indicating overflow error type
051: private static final int TYPE_OVERFLOW = 2;
052:
053: // indicating malformed-input error type
054: private static final int TYPE_MALFORMED_INPUT = 3;
055:
056: // indicating unmappable character error type
057: private static final int TYPE_UNMAPPABLE_CHAR = 4;
058:
059: /**
060: * Result object indicating that there is insufficient data in the
061: * encoding/decoding buffer or that additional data is required.
062: */
063: public static final CoderResult UNDERFLOW = new CoderResult(
064: TYPE_UNDERFLOW, 0);
065:
066: /**
067: * Result object used to signify that the out buffer does not have enough
068: * space available in it to store the result of the encoding/decoding.
069: */
070: public static final CoderResult OVERFLOW = new CoderResult(
071: TYPE_OVERFLOW, 0);
072:
073: /*
074: * Stores unique result objects for each malformed-input error of a certain
075: * length
076: */
077: private static WeakHashMap<Integer, CoderResult> _malformedErrors = new WeakHashMap<Integer, CoderResult>();
078:
079: /*
080: * Stores unique result objects for each unmappable-character error of a
081: * certain length
082: */
083: private static WeakHashMap<Integer, CoderResult> _unmappableErrors = new WeakHashMap<Integer, CoderResult>();
084:
085: // the type this result
086: private final int type;
087:
088: // the length of the erroneous input
089: private final int length;
090:
091: /**
092: * Construct a <code>CoderResult</code> object with its text description.
093: *
094: * @param type
095: * the type of this result
096: * @param length
097: * the length of the erroneous input
098: */
099: private CoderResult(int type, int length) {
100: super ();
101: this .type = type;
102: this .length = length;
103: }
104:
105: /**
106: * Gets a <code>CoderResult</code> object indicating a malformed-input
107: * error.
108: *
109: * @param length
110: * the length of the malformed-input
111: * @return a <code>CoderResult</code> object indicating a malformed-input
112: * error
113: * @throws IllegalArgumentException
114: * If <code>length</code> is non-positive.
115: */
116: public static synchronized CoderResult malformedForLength(int length)
117: throws IllegalArgumentException {
118: if (length > 0) {
119: Integer key = Integer.valueOf(length);
120: synchronized (_malformedErrors) {
121: CoderResult r = _malformedErrors.get(key);
122: if (null == r) {
123: r = new CoderResult(TYPE_MALFORMED_INPUT, length);
124: _malformedErrors.put(key, r);
125: }
126: return r;
127: }
128: }
129: // niochar.08=The length must be positive: {0}.
130: throw new IllegalArgumentException(Messages.getString(
131: "niochar.08", length)); //$NON-NLS-1$
132: }
133:
134: /**
135: * Gets a <code>CoderResult</code> object indicating an unmappable
136: * character error.
137: *
138: * @param length
139: * the length of the input unit sequence denoting the unmappable
140: * character
141: * @return a <code>CoderResult</code> object indicating an unmappable
142: * character error
143: * @throws IllegalArgumentException
144: * If <code>length</code> is non-positive.
145: */
146: public static synchronized CoderResult unmappableForLength(
147: int length) throws IllegalArgumentException {
148: if (length > 0) {
149: Integer key = Integer.valueOf(length);
150: synchronized (_unmappableErrors) {
151: CoderResult r = _unmappableErrors.get(key);
152: if (null == r) {
153: r = new CoderResult(TYPE_UNMAPPABLE_CHAR, length);
154: _unmappableErrors.put(key, r);
155: }
156: return r;
157: }
158: }
159: // niochar.08=The length must be positive: {0}.
160: throw new IllegalArgumentException(Messages.getString(
161: "niochar.08", length)); //$NON-NLS-1$
162: }
163:
164: /**
165: * Answers true if this result is an underflow condition.
166: *
167: * @return true if an underflow, otherwise false
168: */
169: public boolean isUnderflow() {
170: return this .type == TYPE_UNDERFLOW;
171: }
172:
173: /**
174: * Answers true if this result represents a malformed-input error or an
175: * unmappable-character error.
176: *
177: * @return true if a malformed-input error or an unmappable-character error,
178: * otherwise false
179: */
180: public boolean isError() {
181: return this .type == TYPE_MALFORMED_INPUT
182: || this .type == TYPE_UNMAPPABLE_CHAR;
183: }
184:
185: /**
186: * Answers true if this result represents a malformed-input error.
187: *
188: * @return true if a malformed-input error, otherwise false
189: */
190: public boolean isMalformed() {
191: return this .type == TYPE_MALFORMED_INPUT;
192: }
193:
194: /**
195: * Answers true if this result is an overflow condition.
196: *
197: * @return true if an overflow, otherwise false
198: */
199: public boolean isOverflow() {
200: return this .type == TYPE_OVERFLOW;
201: }
202:
203: /**
204: * Answers true if this result represents an unmappable-character error.
205: *
206: * @return true if an unmappable-character error, otherwise false
207: */
208: public boolean isUnmappable() {
209: return this .type == TYPE_UNMAPPABLE_CHAR;
210: }
211:
212: /**
213: * Gets the length of the erroneous input. The length is only meaningful to
214: * a malformed-input error or an unmappble character error.
215: *
216: * @return the length, as an integer, of this object's erroneous input
217: * @throws UnsupportedOperationException
218: * If this result is an overflow or underflow.
219: */
220: public int length() throws UnsupportedOperationException {
221: if (this .type == TYPE_MALFORMED_INPUT
222: || this .type == TYPE_UNMAPPABLE_CHAR) {
223: return this .length;
224: }
225: // niochar.09=The length of the erroneous input is only meaningful to
226: // a malformed-input error or an unmappble character error
227: throw new UnsupportedOperationException(Messages
228: .getString("niochar.09")); //$NON-NLS-1$
229: }
230:
231: /**
232: * Throws an exception corresponding to this coder result.
233: *
234: * @throws BufferUnderflowException
235: * If an underflow.
236: * @throws BufferOverflowException
237: * If an overflow.
238: * @throws UnmappableCharacterException
239: * If an unmappable-character error.
240: * @throws MalformedInputException
241: * If a malformed-input error.
242: * @throws CharacterCodingException
243: * The default exception.
244: */
245: public void throwException() throws BufferUnderflowException,
246: BufferOverflowException, UnmappableCharacterException,
247: MalformedInputException, CharacterCodingException {
248: switch (this .type) {
249: case TYPE_UNDERFLOW:
250: throw new BufferUnderflowException();
251: case TYPE_OVERFLOW:
252: throw new BufferOverflowException();
253: case TYPE_UNMAPPABLE_CHAR:
254: throw new UnmappableCharacterException(this .length);
255: case TYPE_MALFORMED_INPUT:
256: throw new MalformedInputException(this .length);
257: default:
258: throw new CharacterCodingException();
259: }
260: }
261:
262: /*
263: * -------------------------------------------------------------------
264: * Methods overriding parent class Object
265: * -------------------------------------------------------------------
266: */
267:
268: /**
269: * Returns a text description of this result.
270: *
271: * @return a text description of this result
272: */
273: public String toString() {
274: String dsc = null;
275: switch (this .type) {
276: case TYPE_UNDERFLOW:
277: dsc = "UNDERFLOW error"; //$NON-NLS-1$
278: break;
279: case TYPE_OVERFLOW:
280: dsc = "OVERFLOW error"; //$NON-NLS-1$
281: break;
282: case TYPE_UNMAPPABLE_CHAR:
283: dsc = "Unmappable-character error with erroneous input length " //$NON-NLS-1$
284: + this .length;
285: break;
286: case TYPE_MALFORMED_INPUT:
287: dsc = "Malformed-input error with erroneous input length " //$NON-NLS-1$
288: + this .length;
289: break;
290: default:
291: dsc = ""; //$NON-NLS-1$
292: break;
293: }
294: return "CoderResult[" + dsc + "]"; //$NON-NLS-1$ //$NON-NLS-2$
295:
296: }
297:
298: }
|