OSDN Git Service

libjava/ChangeLog:
[pf3gnuchains/gcc-fork.git] / libjava / classpath / gnu / java / nio / charset / ByteDecodeLoopHelper.java
1 /* ByteCharset.java -- Abstract class for generic 1-byte encodings.
2    Copyright (C) 2005 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 gnu.java.nio.charset;
39
40 import java.nio.ByteBuffer;
41 import java.nio.CharBuffer;
42 import java.nio.charset.CoderResult;
43
44 /**
45  * Helper class to deal with decoding loops that read a byte at a time
46  * 
47  * @author Ian Rogers
48  */
49 public abstract class ByteDecodeLoopHelper
50 {
51   /**
52    * @return can the given byte be encoded
53    */
54   protected abstract boolean isMappable(byte b);
55
56   /**
57    * Map the given byte to a char, the given byte is guaranteed to be mappable
58    */
59   protected abstract char mapToChar(byte b);
60
61   /**
62    * Encodes one or more characters into one or more bytes, mapping each
63    * character to only one byte
64    * 
65    * @param in character buffer to read from
66    * @param out byte buffer to write to
67    * @return the result state of the encoder
68    */
69   CoderResult decodeLoop(ByteBuffer in, CharBuffer out)
70   {
71     if (in.hasArray() && out.hasArray())
72       {
73         return arrayDecodeLoop(in, out);
74       } else
75       {
76         return normalDecodeLoop(in, out);
77       }
78   }
79
80   /**
81    * Encode loop using get and put operations
82    */
83   private CoderResult normalDecodeLoop(ByteBuffer in, CharBuffer out)
84   {
85     int outRemaining = out.remaining();
86     int inRemaining = in.remaining();
87     while (inRemaining > 0 && outRemaining > 0)
88       {
89         byte b = in.get();
90         inRemaining--;
91
92         if (!isMappable(b))
93           {
94             in.position(in.position() - 1);
95             return CoderResult.unmappableForLength(1);
96           }
97         char c = mapToChar(b);
98         out.put(c);
99         outRemaining--;
100       }
101     if (inRemaining > 0)
102       {
103         return CoderResult.OVERFLOW;
104       } else
105       {
106         return CoderResult.UNDERFLOW;
107       }
108   }
109
110   /**
111    * Encode loop using array read and write operations
112    */
113   private CoderResult arrayDecodeLoop(ByteBuffer in, CharBuffer out)
114   {
115     byte[] inArray = in.array();
116     char[] outArray = out.array();
117     int inPos = in.arrayOffset() + in.position();
118     int outPos = out.arrayOffset() + out.position();
119     int inRemaining = in.remaining();
120     int outRemaining = out.remaining();
121     CoderResult result;
122
123         bailOut:
124     if (inRemaining <= outRemaining)
125       {
126         for (int i = 0; i < inRemaining; i++)
127           {
128             byte b = inArray[inPos];
129             inPos++;
130             if (!isMappable(b))
131               {
132                 inPos--;
133                 result = CoderResult.unmappableForLength(1);
134                                 break bailOut;
135               }
136             char c = mapToChar(b);
137             outArray[outPos] = c;
138             outPos++;
139           }
140         result = CoderResult.UNDERFLOW;
141       }
142     else
143       {
144         for (int i = 0; i < outRemaining; i++)
145           {
146             byte b = inArray[inPos];
147             inPos++;
148             if (!isMappable(b))
149               {
150                 inPos--;
151                 result = CoderResult.unmappableForLength(1);
152                                 break bailOut;
153               }
154             char c = mapToChar(b);
155             outArray[outPos] = c;
156             outPos++;
157           }
158         result = CoderResult.OVERFLOW;
159       }
160     in.position(inPos - in.arrayOffset());
161     out.position(outPos - out.arrayOffset());
162     return result;
163   }
164 }