OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libjava/] [classpath/] [java/] [nio/] [charset/] [CharsetDecoder.java] - Blame information for rev 771

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 771 jeremybenn
/* CharsetDecoder.java --
2
   Copyright (C) 2002 Free Software Foundation, Inc.
3
 
4
This file is part of GNU Classpath.
5
 
6
GNU Classpath is free software; you can redistribute it and/or modify
7
it under the terms of the GNU General Public License as published by
8
the Free Software Foundation; either version 2, or (at your option)
9
any later version.
10
 
11
GNU Classpath is distributed in the hope that it will be useful, but
12
WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
General Public License for more details.
15
 
16
You should have received a copy of the GNU General Public License
17
along with GNU Classpath; see the file COPYING.  If not, write to the
18
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19
02110-1301 USA.
20
 
21
Linking this library statically or dynamically with other modules is
22
making a combined work based on this library.  Thus, the terms and
23
conditions of the GNU General Public License cover the whole
24
combination.
25
 
26
As a special exception, the copyright holders of this library give you
27
permission to link this library with independent modules to produce an
28
executable, regardless of the license terms of these independent
29
modules, and to copy and distribute the resulting executable under
30
terms of your choice, provided that you also meet, for each linked
31
independent module, the terms and conditions of the license of that
32
module.  An independent module is a module which is not derived from
33
or based on this library.  If you modify this library, you may extend
34
this exception to your version of the library, but you are not
35
obligated to do so.  If you do not wish to do so, delete this
36
exception statement from your version. */
37
 
38
package java.nio.charset;
39
 
40
import java.nio.ByteBuffer;
41
import java.nio.CharBuffer;
42
 
43
/**
44
 * @author Jesse Rosenstock
45
 * @since 1.4
46
 */
47
public abstract class CharsetDecoder
48
{
49
  private static final int STATE_RESET   = 0;
50
  private static final int STATE_CODING  = 1;
51
  private static final int STATE_END     = 2;
52
  private static final int STATE_FLUSHED = 3;
53
 
54
  private static final String DEFAULT_REPLACEMENT = "\uFFFD";
55
 
56
  private final Charset charset;
57
  private final float averageCharsPerByte;
58
  private final float maxCharsPerByte;
59
  private String replacement;
60
 
61
  private int state = STATE_RESET;
62
 
63
  private CodingErrorAction malformedInputAction
64
    = CodingErrorAction.REPORT;
65
  private CodingErrorAction unmappableCharacterAction
66
    = CodingErrorAction.REPORT;
67
 
68
  private CharsetDecoder (Charset cs, float averageCharsPerByte,
69
                          float maxCharsPerByte, String replacement)
70
  {
71
    if (averageCharsPerByte <= 0.0f)
72
      throw new IllegalArgumentException ("Non-positive averageCharsPerByte");
73
    if (maxCharsPerByte <= 0.0f)
74
      throw new IllegalArgumentException ("Non-positive maxCharsPerByte");
75
 
76
    this.charset = cs;
77
    this.averageCharsPerByte
78
      = averageCharsPerByte;
79
    this.maxCharsPerByte
80
      = maxCharsPerByte;
81
    this.replacement = replacement;
82
    implReplaceWith (replacement);
83
  }
84
 
85
  protected CharsetDecoder (Charset cs, float averageCharsPerByte,
86
                            float maxCharsPerByte)
87
  {
88
    this (cs, averageCharsPerByte, maxCharsPerByte, DEFAULT_REPLACEMENT);
89
  }
90
 
91
  public final float averageCharsPerByte ()
92
  {
93
    return averageCharsPerByte;
94
  }
95
 
96
  public final Charset charset ()
97
  {
98
    return charset;
99
  }
100
 
101
  public final CharBuffer decode (ByteBuffer in)
102
    throws CharacterCodingException
103
  {
104
    // XXX: Sun's Javadoc seems to contradict itself saying an
105
    // IllegalStateException is thrown "if a decoding operation is already
106
    // in progress" and also that "it resets this Decoder".
107
    // Should we check to see that the state is reset, or should we
108
    // call reset()?
109
    if (state != STATE_RESET)
110
      throw new IllegalStateException ();
111
 
112
    // REVIEW: Using max instead of average may allocate a very large
113
    // buffer.  Maybe we should do something more efficient?
114
    int remaining = in.remaining ();
115
    int n = (int) (remaining * maxCharsPerByte ());
116
    CharBuffer out = CharBuffer.allocate (n);
117
 
118
    if (remaining == 0)
119
      {
120
        state = STATE_FLUSHED;
121
        return out;
122
      }
123
 
124
    CoderResult cr = decode (in, out, true);
125
    if (cr.isError ())
126
      cr.throwException ();
127
 
128
    cr = flush (out);
129
    if (cr.isError ())
130
      cr.throwException ();
131
 
132
    reset();
133
    out.flip ();
134
 
135
    // Unfortunately, resizing the actual charbuffer array is required.
136
    char[] resized = new char[out.remaining()];
137
    out.get(resized);
138
    return CharBuffer.wrap(resized);
139
  }
140
 
141
  public final CoderResult decode (ByteBuffer in, CharBuffer out,
142
                                   boolean endOfInput)
143
  {
144
    int newState = endOfInput ? STATE_END : STATE_CODING;
145
    // XXX: Need to check for "previous step was an invocation [not] of
146
    // this method with a value of true for the endOfInput parameter but
147
    // a return value indicating an incomplete decoding operation"
148
    // XXX: We will not check the previous return value, just
149
    // that the previous call passed true for endOfInput
150
    if (state != STATE_RESET && state != STATE_CODING
151
        && !(endOfInput && state == STATE_END))
152
      throw new IllegalStateException ();
153
    state = newState;
154
 
155
    for (;;)
156
      {
157
        CoderResult cr;
158
        try
159
          {
160
            cr = decodeLoop (in, out);
161
          }
162
        catch (RuntimeException e)
163
          {
164
            throw new CoderMalfunctionError (e);
165
          }
166
 
167
        if (cr.isOverflow ())
168
          return cr;
169
 
170
        if (cr.isUnderflow ())
171
          {
172
            if (endOfInput && in.hasRemaining ())
173
              cr = CoderResult.malformedForLength (in.remaining ());
174
            else
175
              return cr;
176
          }
177
 
178
        CodingErrorAction action = cr.isMalformed ()
179
                                     ? malformedInputAction
180
                                     : unmappableCharacterAction;
181
 
182
        if (action == CodingErrorAction.REPORT)
183
          return cr;
184
 
185
        if (action == CodingErrorAction.REPLACE)
186
          {
187
            if (out.remaining () < replacement.length ())
188
              return CoderResult.OVERFLOW;
189
            out.put (replacement);
190
          }
191
 
192
        in.position (in.position () + cr.length ());
193
      }
194
  }
195
 
196
  protected abstract CoderResult decodeLoop (ByteBuffer in, CharBuffer out);
197
 
198
  public Charset detectedCharset ()
199
  {
200
    throw new UnsupportedOperationException ();
201
  }
202
 
203
  public final CoderResult flush (CharBuffer out)
204
  {
205
    // It seems weird that you can flush after reset, but Sun's javadoc
206
    // says an IllegalStateException is thrown "If the previous step of the
207
    // current decoding operation was an invocation neither of the reset
208
    // method nor ... of the three-argument decode method with a value of
209
    // true for the endOfInput parameter."
210
    // Further note that flush() only requires that there not be
211
    // an IllegalStateException if the previous step was a call to
212
    // decode with true as the last argument.  It does not require
213
    // that the call succeeded.  decode() does require that it succeeded.
214
    // XXX: test this to see if reality matches javadoc
215
    if (state != STATE_RESET && state != STATE_END)
216
      throw new IllegalStateException ();
217
 
218
    state = STATE_FLUSHED;
219
    return implFlush (out);
220
  }
221
 
222
  protected CoderResult implFlush (CharBuffer out)
223
  {
224
    return CoderResult.UNDERFLOW;
225
  }
226
 
227
  public final CharsetDecoder onMalformedInput (CodingErrorAction newAction)
228
  {
229
    if (newAction == null)
230
      throw new IllegalArgumentException ("Null action");
231
 
232
    malformedInputAction = newAction;
233
    implOnMalformedInput (newAction);
234
    return this;
235
  }
236
 
237
  protected void implOnMalformedInput (CodingErrorAction newAction)
238
  {
239
    // default implementation does nothing
240
  }
241
 
242
  protected void implOnUnmappableCharacter (CodingErrorAction newAction)
243
  {
244
    // default implementation does nothing
245
  }
246
 
247
  protected void implReplaceWith (String newReplacement)
248
  {
249
    // default implementation does nothing
250
  }
251
 
252
  protected void implReset ()
253
  {
254
    // default implementation does nothing
255
  }
256
 
257
  public boolean isAutoDetecting ()
258
  {
259
    return false;
260
  }
261
 
262
  public boolean isCharsetDetected ()
263
  {
264
    throw new UnsupportedOperationException ();
265
  }
266
 
267
  public CodingErrorAction malformedInputAction ()
268
  {
269
    return malformedInputAction;
270
  }
271
 
272
  public final float maxCharsPerByte ()
273
  {
274
    return maxCharsPerByte;
275
  }
276
 
277
  public final CharsetDecoder onUnmappableCharacter
278
    (CodingErrorAction newAction)
279
  {
280
    if (newAction == null)
281
      throw new IllegalArgumentException ("Null action");
282
 
283
    unmappableCharacterAction = newAction;
284
    implOnUnmappableCharacter (newAction);
285
    return this;
286
  }
287
 
288
  public final String replacement ()
289
  {
290
    return replacement;
291
  }
292
 
293
  public final CharsetDecoder replaceWith (String newReplacement)
294
  {
295
    if (newReplacement == null)
296
      throw new IllegalArgumentException ("Null replacement");
297
    if (newReplacement.length () == 0)
298
      throw new IllegalArgumentException ("Empty replacement");
299
    // XXX: what about maxCharsPerByte?
300
 
301
    this.replacement = newReplacement;
302
    implReplaceWith (newReplacement);
303
    return this;
304
  }
305
 
306
  public final CharsetDecoder reset ()
307
  {
308
    state = STATE_RESET;
309
    implReset ();
310
    return this;
311
  }
312
 
313
  public CodingErrorAction unmappableCharacterAction ()
314
  {
315
    return unmappableCharacterAction;
316
  }
317
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.