1:
37:
38: package ;
39:
40: import ;
41: import ;
42: import ;
43: import ;
44:
45:
49: public class CoderResult
50: {
51: private static final int TYPE_MALFORMED = 0;
52: private static final int TYPE_OVERFLOW = 1;
53: private static final int TYPE_UNDERFLOW = 2;
54: private static final int TYPE_UNMAPPABLE = 3;
55:
56: public static final CoderResult OVERFLOW
57: = new CoderResult (TYPE_OVERFLOW, 0);
58: public static final CoderResult UNDERFLOW
59: = new CoderResult (TYPE_UNDERFLOW, 0);
60:
61: private static final String[] names
62: = { "MALFORMED", "OVERFLOW", "UNDERFLOW", "UNMAPPABLE" };
63:
64: private static final Cache malformedCache
65: = new Cache ()
66: {
67: protected CoderResult make (int length)
68: {
69: return new CoderResult (TYPE_MALFORMED, length);
70: }
71: };
72:
73: private static final Cache unmappableCache
74: = new Cache ()
75: {
76: protected CoderResult make (int length)
77: {
78: return new CoderResult (TYPE_UNMAPPABLE, length);
79: }
80: };
81:
82: private final int type;
83: private final int length;
84:
85:
86: CoderResult (int type, int length)
87: {
88: this.type = type;
89: this.length = length;
90: }
91:
92: public boolean isError ()
93: {
94: return length > 0;
95: }
96:
97: public boolean isMalformed ()
98: {
99: return type == TYPE_MALFORMED;
100: }
101:
102: public boolean isOverflow ()
103: {
104: return type == TYPE_OVERFLOW;
105: }
106:
107: public boolean isUnderflow ()
108: {
109: return type == TYPE_UNDERFLOW;
110: }
111:
112: public boolean isUnmappable ()
113: {
114: return type == TYPE_UNMAPPABLE;
115: }
116:
117: public int length ()
118: {
119: if (length <= 0)
120: throw new UnsupportedOperationException ();
121: else
122: return length;
123: }
124:
125: public static CoderResult malformedForLength (int length)
126: {
127: return malformedCache.get (length);
128: }
129:
130: public void throwException ()
131: throws CharacterCodingException
132: {
133: switch (type)
134: {
135: case TYPE_MALFORMED:
136: throw new MalformedInputException (length);
137: case TYPE_OVERFLOW:
138: throw new BufferOverflowException ();
139: case TYPE_UNDERFLOW:
140: throw new BufferUnderflowException ();
141: case TYPE_UNMAPPABLE:
142: throw new UnmappableCharacterException (length);
143: }
144: }
145:
146: public String toString ()
147: {
148: String name = names[type];
149: return (length > 0) ? name + '[' + length + ']' : name;
150: }
151:
152: public static CoderResult unmappableForLength (int length)
153: {
154: return unmappableCache.get (length);
155: }
156:
157: private abstract static class Cache
158: {
159: private final HashMap cache;
160:
161:
162: Cache ()
163: {
164: cache = new HashMap ();
165: }
166:
167:
168: synchronized CoderResult get (int length)
169: {
170: if (length <= 0)
171: throw new IllegalArgumentException ("Non-positive length");
172:
173: Integer len = Integer.valueOf (length);
174: CoderResult cr = null;
175: Object o;
176: if ((o = cache.get (len)) != null)
177: cr = (CoderResult) ((WeakReference) o).get ();
178: if (cr == null)
179: {
180: cr = make (length);
181: cache.put (len, new WeakReference (cr));
182: }
183:
184: return cr;
185: }
186:
187: protected abstract CoderResult make (int length);
188: }
189: }