summaryrefslogtreecommitdiff
path: root/libjava/gnu/gcj/convert/CharsetToBytesAdaptor.java
diff options
context:
space:
mode:
Diffstat (limited to 'libjava/gnu/gcj/convert/CharsetToBytesAdaptor.java')
-rw-r--r--libjava/gnu/gcj/convert/CharsetToBytesAdaptor.java156
1 files changed, 156 insertions, 0 deletions
diff --git a/libjava/gnu/gcj/convert/CharsetToBytesAdaptor.java b/libjava/gnu/gcj/convert/CharsetToBytesAdaptor.java
new file mode 100644
index 000000000..80e749cc8
--- /dev/null
+++ b/libjava/gnu/gcj/convert/CharsetToBytesAdaptor.java
@@ -0,0 +1,156 @@
+/* Copyright (C) 2005, 2006 Free Software Foundation
+
+This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+package gnu.gcj.convert;
+
+import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+import java.nio.charset.Charset;
+import java.nio.charset.CharsetEncoder;
+import java.nio.charset.CodingErrorAction;
+import java.nio.charset.CoderResult;
+import gnu.java.nio.charset.EncodingHelper;
+
+/**
+ * Adaptor class that allow any {@link Charset} to be used
+ * as a UnicodeToBytes converter.
+ */
+public class CharsetToBytesAdaptor extends UnicodeToBytes
+{
+ /**
+ * The CharsetEncoder that does all the work.
+ */
+ private final CharsetEncoder encoder;
+
+ /**
+ * ByteBuffer wrapper for this.buf.
+ */
+ private ByteBuffer outBuf;
+
+ /**
+ * True if we've told the CharsetEncoder that there are no more
+ * characters available.
+ */
+ private boolean closedEncoder;
+
+ /**
+ * True if there are bytes pending in the encoder.
+ */
+ private boolean hasBytes;
+
+ /**
+ * True if we're finished.
+ */
+ private boolean finished;
+
+ /**
+ * Create a new CharsetToBytesAdaptor for the given Charset.
+ *
+ * @param cs The Charset.
+ */
+ public CharsetToBytesAdaptor(Charset cs)
+ {
+ this(cs.newEncoder());
+ }
+
+ /**
+ * Create a new CharsetToBytesAdaptor for the given CharsetEncoder.
+ *
+ * @param enc The CharsetEncoder.
+ */
+ public CharsetToBytesAdaptor(CharsetEncoder enc)
+ {
+ encoder = enc;
+ // Use default replacments on bad input so that we don't have to
+ // deal with errors.
+ encoder.onMalformedInput(CodingErrorAction.REPLACE);
+ encoder.onUnmappableCharacter(CodingErrorAction.REPLACE);
+ }
+
+ /**
+ * Return the encoder's name. The backing Charset's name is
+ * returned.
+ *
+ * @return The name.
+ */
+ public String getName()
+ {
+ return EncodingHelper.getOldCanonical(encoder.charset().name());
+ }
+
+ public int write (char[] inbuffer, int inpos, int inlength)
+ {
+ // Wrap the char array so it can be used by the encoder.
+ CharBuffer b = CharBuffer.wrap(inbuffer, inpos, inlength);
+ write(b);
+ return b.position() - inpos; // Number of chars consumed.
+ }
+
+ public int write (String str, int inpos, int inlength, char work)
+ {
+ // Wrap the String so it can be used by the encoder.
+ CharBuffer b = CharBuffer.wrap(str, inpos, inlength);
+ write(b);
+ return b.position() - inpos; // Number of chars consumed.
+ }
+
+ /**
+ * Encode as much of inBuf as will fit in buf. The number of
+ * chars consumed is reflected by the new position of inBuf. The
+ * output is put in buf and count is incremented by the number of
+ * bytes written.
+ *
+ * @param inBuf The input.
+ */
+ private void write(CharBuffer inBuf)
+ {
+ // Reuse existing outBuf if it is still wrapping the same array
+ // it was created with.
+ if (outBuf == null || !outBuf.hasArray() || outBuf.array() != buf)
+ outBuf = ByteBuffer.wrap(buf);
+
+ // Set the current position.
+ outBuf.position(count);
+
+ // Do the conversion.
+ CoderResult result = encoder.encode(inBuf, outBuf, closedEncoder);
+ hasBytes = result == CoderResult.OVERFLOW;
+ if (closedEncoder)
+ {
+ result = encoder.flush(outBuf);
+ if (result == CoderResult.UNDERFLOW)
+ finished = true;
+ else
+ hasBytes = true;
+ }
+
+ // Mark the new end of buf.
+ count = outBuf.position();
+ }
+
+ /**
+ * Check for cached output in the converter.
+ *
+ * @return true if there is cached output that has not been
+ * written to buf.
+ */
+ public boolean havePendingBytes()
+ {
+ return hasBytes;
+ }
+
+ public void setFinished()
+ {
+ closedEncoder = true;
+ }
+
+ // These aren't cached.
+ public void done()
+ {
+ }
+}