• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Licensed to the Apache Software Foundation (ASF) under one or more
2  * contributor license agreements.  See the NOTICE file distributed with
3  * this work for additional information regarding copyright ownership.
4  * The ASF licenses this file to You under the Apache License, Version 2.0
5  * (the "License"); you may not use this file except in compliance with
6  * the License.  You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package java.nio.charset;
18 
19 import java.nio.BufferOverflowException;
20 import java.nio.BufferUnderflowException;
21 import java.util.WeakHashMap;
22 
23 /**
24  * Used to indicate the result of encoding/decoding. There are four types of
25  * results:
26  * <ol>
27  * <li>UNDERFLOW indicates that all input has been processed but more input is
28  * required. It is represented by the unique object
29  * <code>CoderResult.UNDERFLOW</code>.
30  * <li>OVERFLOW indicates an insufficient output buffer size. It is represented
31  * by the unique object <code>CoderResult.OVERFLOW</code>.
32  * <li>A malformed-input error indicates that an unrecognizable sequence of
33  * input units has been encountered. Get an instance of this type of result by
34  * calling <code>CoderResult.malformedForLength(int)</code> with the length of
35  * the malformed-input.
36  * <li>An unmappable-character error indicates that a sequence of input units
37  * can not be mapped to the output charset. Get an instance of this type of
38  * result by calling <code>CoderResult.unmappableForLength(int)</code> with
39  * the input sequence size indicating the identity of the unmappable character.
40  * </ol>
41  */
42 public class CoderResult {
43 
44     // indicating underflow error type
45     private static final int TYPE_UNDERFLOW = 1;
46 
47     // indicating overflow error type
48     private static final int TYPE_OVERFLOW = 2;
49 
50     // indicating malformed-input error type
51     private static final int TYPE_MALFORMED_INPUT = 3;
52 
53     // indicating unmappable character error type
54     private static final int TYPE_UNMAPPABLE_CHAR = 4;
55 
56     /**
57      * Result object indicating that there is insufficient data in the
58      * encoding/decoding buffer or that additional data is required.
59      */
60     public static final CoderResult UNDERFLOW = new CoderResult(TYPE_UNDERFLOW,
61             0);
62 
63     /**
64      * Result object used to indicate that the output buffer does not have
65      * enough space available to store the result of the encoding/decoding.
66      */
67     public static final CoderResult OVERFLOW = new CoderResult(TYPE_OVERFLOW, 0);
68 
69     /*
70      * Stores unique result objects for each malformed-input error of a certain
71      * length
72      */
73     private static WeakHashMap<Integer, CoderResult> _malformedErrors = new WeakHashMap<Integer, CoderResult>();
74 
75     /*
76      * Stores unique result objects for each unmappable-character error of a
77      * certain length
78      */
79     private static WeakHashMap<Integer, CoderResult> _unmappableErrors = new WeakHashMap<Integer, CoderResult>();
80 
81     // the type of this result
82     private final int type;
83 
84     // the length of the erroneous input
85     private final int length;
86 
87     /**
88      * Constructs a <code>CoderResult</code> object with its text description.
89      *
90      * @param type
91      *            the type of this result
92      * @param length
93      *            the length of the erroneous input
94      */
CoderResult(int type, int length)95     private CoderResult(int type, int length) {
96         this.type = type;
97         this.length = length;
98     }
99 
100     /**
101      * Gets a <code>CoderResult</code> object indicating a malformed-input
102      * error.
103      *
104      * @param length
105      *            the length of the malformed-input.
106      * @return a <code>CoderResult</code> object indicating a malformed-input
107      *         error.
108      * @throws IllegalArgumentException
109      *             if <code>length</code> is non-positive.
110      */
malformedForLength(int length)111     public static synchronized CoderResult malformedForLength(int length)
112             throws IllegalArgumentException {
113         if (length > 0) {
114             Integer key = Integer.valueOf(length);
115             synchronized (_malformedErrors) {
116                 CoderResult r = _malformedErrors.get(key);
117                 if (r == null) {
118                     r = new CoderResult(TYPE_MALFORMED_INPUT, length);
119                     _malformedErrors.put(key, r);
120                 }
121                 return r;
122             }
123         }
124         throw new IllegalArgumentException("length <= 0: " + length);
125     }
126 
127     /**
128      * Gets a <code>CoderResult</code> object indicating an unmappable
129      * character error.
130      *
131      * @param length
132      *            the length of the input unit sequence denoting the unmappable
133      *            character.
134      * @return a <code>CoderResult</code> object indicating an unmappable
135      *         character error.
136      * @throws IllegalArgumentException
137      *             if <code>length</code> is non-positive.
138      */
unmappableForLength(int length)139     public static synchronized CoderResult unmappableForLength(int length)
140             throws IllegalArgumentException {
141         if (length > 0) {
142             Integer key = Integer.valueOf(length);
143             synchronized (_unmappableErrors) {
144                 CoderResult r = _unmappableErrors.get(key);
145                 if (r == null) {
146                     r = new CoderResult(TYPE_UNMAPPABLE_CHAR, length);
147                     _unmappableErrors.put(key, r);
148                 }
149                 return r;
150             }
151         }
152         throw new IllegalArgumentException("length <= 0: " + length);
153     }
154 
155     /**
156      * Returns true if this result is an underflow condition.
157      */
isUnderflow()158     public boolean isUnderflow() {
159         return this.type == TYPE_UNDERFLOW;
160     }
161 
162     /**
163      * Returns true if this result represents a malformed-input error or an
164      * unmappable-character error.
165      */
isError()166     public boolean isError() {
167         return this.type == TYPE_MALFORMED_INPUT || this.type == TYPE_UNMAPPABLE_CHAR;
168     }
169 
170     /**
171      * Returns true if this result represents a malformed-input error.
172      */
isMalformed()173     public boolean isMalformed() {
174         return this.type == TYPE_MALFORMED_INPUT;
175     }
176 
177     /**
178      * Returns true if this result is an overflow condition.
179      */
isOverflow()180     public boolean isOverflow() {
181         return this.type == TYPE_OVERFLOW;
182     }
183 
184     /**
185      * Returns true if this result represents an unmappable-character error.
186      */
isUnmappable()187     public boolean isUnmappable() {
188         return this.type == TYPE_UNMAPPABLE_CHAR;
189     }
190 
191     /**
192      * Returns the length of the erroneous input. The length is only meaningful for
193      * a malformed-input error or an unmappable character error.
194      *
195      * @throws UnsupportedOperationException
196      *             if this result is an overflow or underflow.
197      */
length()198     public int length() throws UnsupportedOperationException {
199         if (this.type == TYPE_MALFORMED_INPUT || this.type == TYPE_UNMAPPABLE_CHAR) {
200             return this.length;
201         }
202         throw new UnsupportedOperationException("length meaningless for " + toString());
203     }
204 
205     /**
206      * Throws an exception corresponding to this coder result.
207      *
208      * @throws BufferUnderflowException
209      *             in case this is an underflow.
210      * @throws BufferOverflowException
211      *             in case this is an overflow.
212      * @throws UnmappableCharacterException
213      *             in case this is an unmappable-character error.
214      * @throws MalformedInputException
215      *             in case this is a malformed-input error.
216      * @throws CharacterCodingException
217      *             the default exception.
218      */
throwException()219     public void throwException() throws BufferUnderflowException,
220             BufferOverflowException, UnmappableCharacterException,
221             MalformedInputException, CharacterCodingException {
222         switch (this.type) {
223             case TYPE_UNDERFLOW:
224                 throw new BufferUnderflowException();
225             case TYPE_OVERFLOW:
226                 throw new BufferOverflowException();
227             case TYPE_UNMAPPABLE_CHAR:
228                 throw new UnmappableCharacterException(this.length);
229             case TYPE_MALFORMED_INPUT:
230                 throw new MalformedInputException(this.length);
231             default:
232                 throw new CharacterCodingException();
233         }
234     }
235 
236     /**
237      * Returns a text description of this result.
238      *
239      * @return a text description of this result.
240      */
241     @Override
toString()242     public String toString() {
243         String dsc = null;
244         switch (this.type) {
245             case TYPE_UNDERFLOW:
246                 dsc = "UNDERFLOW error";
247                 break;
248             case TYPE_OVERFLOW:
249                 dsc = "OVERFLOW error";
250                 break;
251             case TYPE_UNMAPPABLE_CHAR:
252                 dsc = "Unmappable-character error with erroneous input length "
253                         + this.length;
254                 break;
255             case TYPE_MALFORMED_INPUT:
256                 dsc = "Malformed-input error with erroneous input length "
257                         + this.length;
258                 break;
259             default:
260                 dsc = "";
261                 break;
262         }
263         return getClass().getName() + "[" + dsc + "]";
264     }
265 }
266