OSDN Git Service

PR libgcj/9715, PR libgcj/19132:
[pf3gnuchains/gcc-fork.git] / libjava / gnu / gcj / convert / CharsetToBytesAdaptor.java
1 /* Copyright (C) 2005, 2006  Free Software Foundation
2
3 This file is part of libgcj.
4
5 This software is copyrighted work licensed under the terms of the
6 Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
7 details.  */
8
9 package gnu.gcj.convert; 
10
11 import java.nio.ByteBuffer;
12 import java.nio.CharBuffer;
13 import java.nio.charset.Charset;
14 import java.nio.charset.CharsetEncoder;
15 import java.nio.charset.CodingErrorAction;
16 import java.nio.charset.CoderResult;
17 import gnu.java.nio.charset.EncodingHelper;
18
19 /**
20  * Adaptor class that allow any {@link Charset} to be used
21  * as a UnicodeToBytes converter.
22  */
23 public class CharsetToBytesAdaptor extends UnicodeToBytes
24 {
25   /**
26    * The CharsetEncoder that does all the work.
27    */
28   private final CharsetEncoder encoder;
29
30   /**
31    * ByteBuffer wrapper for this.buf.
32    */
33   private ByteBuffer outBuf;
34
35   /**
36    * True if we've told the CharsetEncoder that there are no more
37    * characters available.
38    */
39   private boolean closedEncoder;
40
41   /**
42    * True if we're finished.
43    */
44   private boolean finished;
45
46   /**
47    * Create a new CharsetToBytesAdaptor for the given Charset.
48    *
49    * @param cs The Charset.
50    */
51   public CharsetToBytesAdaptor(Charset cs)
52   {
53     this(cs.newEncoder());
54   }
55
56   /**
57    * Create a new CharsetToBytesAdaptor for the given CharsetEncoder.
58    *
59    * @param enc The CharsetEncoder.
60    */
61   public CharsetToBytesAdaptor(CharsetEncoder enc)
62   {
63     encoder = enc;
64     // Use default replacments on bad input so that we don't have to
65     // deal with errors.
66     encoder.onMalformedInput(CodingErrorAction.REPLACE);
67     encoder.onUnmappableCharacter(CodingErrorAction.REPLACE);
68   }
69
70   /**
71    * Return the encoder's name.  The backing Charset's name is
72    * returned.
73    *
74    * @return The name.
75    */
76   public String getName()
77   {
78     return EncodingHelper.getOldCanonical(encoder.charset().name());
79   }
80
81   public int write (char[] inbuffer, int inpos, int inlength)
82   {
83     // Wrap the char array so it can be used by the encoder.
84     CharBuffer b = CharBuffer.wrap(inbuffer, inpos, inlength);
85     write(b);
86     return b.position() - inpos; // Number of chars consumed.
87   }
88
89   public int write (String str, int inpos, int inlength, char work)
90   {
91     // Wrap the String so it can be used by the encoder.
92     CharBuffer b = CharBuffer.wrap(str, inpos, inlength);
93     write(b);
94     return b.position() - inpos; // Number of chars consumed.
95   }
96
97   /**
98    * Encode as much of inBuf as will fit in buf.  The number of
99    * chars consumed is reflected by the new position of inBuf.  The
100    * output is put in buf and count is incremented by the number of
101    * bytes written.
102    *
103    * @param inBuf The input.
104    */
105   private void write(CharBuffer inBuf)
106   {
107     // Reuse existing outBuf if it is still wrapping the same array
108     // it was created with.
109     if (outBuf == null || !outBuf.hasArray() || outBuf.array() != buf)
110       outBuf = ByteBuffer.wrap(buf);
111
112     // Set the current position.
113     outBuf.position(count);
114
115     // If we've already said that there is no more input available,
116     // then we simply try to flush again.
117     if (closedEncoder)
118       {
119         CoderResult result = encoder.flush(outBuf);
120         if (result == CoderResult.UNDERFLOW)
121           finished = true;
122        }
123     else
124       {
125         // Do the conversion.  If there are no characters to write,
126         // then we are finished.
127         closedEncoder = ! inBuf.hasRemaining();
128         encoder.encode(inBuf, outBuf, closedEncoder);
129       }
130
131     // Mark the new end of buf.
132     count = outBuf.position();
133   }
134
135   /**
136    * Check for cached output in the converter.
137    *
138    * @return true if there is cached output that has not been
139    * written to buf.
140    */
141   public boolean havePendingBytes()
142   {
143     return ! finished;
144   }
145
146   // These aren't cached.
147   public void done()
148   {
149   }
150 }