summaryrefslogtreecommitdiff
path: root/gnu/java/nio/charset/UTF_16Encoder.java
diff options
context:
space:
mode:
authorMichael Koch <konqueror@gmx.de>2002-11-08 12:15:32 +0000
committerMichael Koch <konqueror@gmx.de>2002-11-08 12:15:32 +0000
commit03e7fa338ecf4ad04592db8ac84e175646416213 (patch)
tree672c51dbc3e6331a6ee29c1dedb7031495f3436b /gnu/java/nio/charset/UTF_16Encoder.java
parent607c7096d2fe8bef1455b837ccb8d4ed7ae2e083 (diff)
downloadclasspath-03e7fa338ecf4ad04592db8ac84e175646416213.tar.gz
2002-11-08 Jesse Rosenstock <jmr@fulcrummicro.com>
* java/nio/charset/CharacterCodingException.java: This class must be public. * java/nio/charset/Charset.java: Implemented whole class. * java/nio/charset/CharsetDecoder.java: Implemented whole class. * java/nio/charset/CharsetEncoder.java: Implemented whole class. * java/nio/charset/CoderMalfunctionError.java: This class must be public. * java/nio/charset/CoderResult.java: Implemented whole class. * java/nio/charset/CodingErrorAction.java: This class must be public. * java/nio/charset/IllegalCharsetNameException.java: This class must be public, better implementation. * java/nio/charset/MalformedInputException.java: This class must be public, better implementation. * java/nio/charset/UnmappableCharacterException.java: This class must be public, better implementation. * java/nio/charset/UnsupportedCharsetException.java: This class must be public, better implementation. * gnu/java/nio/charset/ISO_8859_1.java, gnu/java/nio/charset/Provider.java, gnu/java/nio/charset/US_ASCII.java, gnu/java/nio/charset/UTF_16.java, gnu/java/nio/charset/UTF_16BE.java, gnu/java/nio/charset/UTF_16Decoder.java, gnu/java/nio/charset/UTF_16Encoder.java, gnu/java/nio/charset/UTF_16LE.java, gnu/java/nio/charset/UTF_8.java, gnu/java/nio/charset/Makefile.am, gnu/java/nio/charset/.cvsignore: New files. * gnu/java/nio/Makefile.am: Add new subdir charset. * configure.in: Added gnu/java/nio/charset/Makefile to AC_OUTPUT.
Diffstat (limited to 'gnu/java/nio/charset/UTF_16Encoder.java')
-rw-r--r--gnu/java/nio/charset/UTF_16Encoder.java116
1 files changed, 116 insertions, 0 deletions
diff --git a/gnu/java/nio/charset/UTF_16Encoder.java b/gnu/java/nio/charset/UTF_16Encoder.java
new file mode 100644
index 000000000..b181ae0cc
--- /dev/null
+++ b/gnu/java/nio/charset/UTF_16Encoder.java
@@ -0,0 +1,116 @@
+package gnu.java.nio.charset;
+
+import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+import java.nio.charset.Charset;
+import java.nio.charset.CharsetEncoder;
+import java.nio.charset.CoderResult;
+
+/**
+ * Encoder for UTF-16, UTF-15LE, and UTF-16BE.
+ *
+ * @author Jesse Rosenstock
+ */
+final class UTF_16Encoder extends CharsetEncoder
+{
+ // byte orders
+ static final int BIG_ENDIAN = 0;
+ static final int LITTLE_ENDIAN = 1;
+
+ private static final char BYTE_ORDER_MARK = '\uFEFF';
+
+ private final int byteOrder;
+ private final boolean useByteOrderMark;
+ private boolean needsByteOrderMark;
+
+ UTF_16Encoder (Charset cs, int byteOrder, boolean useByteOrderMark)
+ {
+ super (cs, 2.0f,
+ useByteOrderMark ? 4.0f : 2.0f,
+ byteOrder == BIG_ENDIAN
+ ? new byte[] { (byte) 0xFF, (byte) 0xFD }
+ : new byte[] { (byte) 0xFD, (byte) 0xFF });
+ this.byteOrder = byteOrder;
+ this.useByteOrderMark = useByteOrderMark;
+ this.needsByteOrderMark = useByteOrderMark;
+ }
+
+ protected CoderResult encodeLoop (CharBuffer in, ByteBuffer out)
+ {
+ // TODO: Optimize this in the case in.hasArray() / out.hasArray()
+
+ if (needsByteOrderMark)
+ {
+ if (out.remaining () < 2)
+ return CoderResult.OVERFLOW;
+ put (out, BYTE_ORDER_MARK);
+ needsByteOrderMark = false;
+ }
+
+ int inPos = in.position ();
+ try
+ {
+ while (in.hasRemaining ())
+ {
+ char c = in.get ();
+
+ if (0xD800 <= c && c <= 0xDFFF)
+ {
+ // c is a surrogate
+
+ // make sure c is a high surrogate
+ if (c > 0xDBFF)
+ return CoderResult.malformedForLength (1);
+ if (in.remaining () < 1)
+ return CoderResult.UNDERFLOW;
+ char d = in.get ();
+ // make sure d is a low surrogate
+ if (d < 0xDC00 || d > 0xDFFF)
+ return CoderResult.malformedForLength (1);
+ put (out, c);
+ put (out, d);
+ inPos += 2;
+ }
+ else
+ {
+ if (out.remaining () < 2)
+ return CoderResult.OVERFLOW;
+ put (out, c);
+ inPos++;
+ }
+ }
+
+ return CoderResult.UNDERFLOW;
+ }
+ finally
+ {
+ in.position (inPos);
+ }
+ }
+
+ /**
+ * Writes <code>c</code> to <code>out</code> in the byte order
+ * specified by <code>byteOrder</code>.
+ **/
+ private void put (ByteBuffer out, char c)
+ {
+ if (byteOrder == BIG_ENDIAN)
+ {
+ out.put ((byte) (c >> 8));
+ out.put ((byte) (c & 0xFF));
+ }
+ else
+ {
+ out.put ((byte) (c & 0xFF));
+ out.put ((byte) (c >> 8));
+ }
+ }
+
+ protected void implReset ()
+ {
+ needsByteOrderMark = useByteOrderMark;
+ }
+
+ // TODO: override canEncode(char) and canEncode(CharSequence)
+ // for performance
+}