/** * */ package org.unicode.cldr.draft; import java.nio.BufferUnderflowException; import java.nio.ByteBuffer; import java.nio.CharBuffer; import java.nio.charset.Charset; import java.nio.charset.CharsetDecoder; import java.nio.charset.CharsetEncoder; import java.nio.charset.CoderResult; import java.nio.charset.CodingErrorAction; public class CharEncoder { private boolean verifyRoundtrip; private boolean justCheck; private CharsetEncoder encoder; private CharsetDecoder decoder; private char[] chars = new char[2]; private char[] returnChars = new char[2]; private CharBuffer charBuffer = CharBuffer.wrap(chars); private ByteBuffer byteBuffer = ByteBuffer.allocate(5); private CharBuffer returnCharBuffer = CharBuffer.wrap(returnChars); public CharEncoder(Charset charset, boolean verifyRoundtrip, boolean justCheck) { this.verifyRoundtrip = verifyRoundtrip; this.justCheck = justCheck; encoder = charset.newEncoder() .onMalformedInput(CodingErrorAction.REPORT) .onUnmappableCharacter(CodingErrorAction.REPORT); decoder = charset.newDecoder() .onMalformedInput(CodingErrorAction.REPORT) .onUnmappableCharacter(CodingErrorAction.REPORT); } public boolean isVerifyRoundtrip() { return verifyRoundtrip; } /** * Convert the code point. Return -1 if fails. If justCheck, then return 1 if success. Otherwise return length of * the bytes * converted, and fill in the destination. In either case, if isVerifyRoundtrip() then check that the roundtrip * works. * * @param codepoint * @param destination * @param offset * @return * @throws BufferUnderflowException * if the supplied destination is too small. */ public int getValue(int codepoint, byte[] destination, int offset) { int byteLen; try { int len = Character.toChars(codepoint, chars, 0); charBuffer.limit(len); charBuffer.position(0); byteBuffer.clear(); CoderResult encodeResult = encoder.encode(charBuffer, byteBuffer, true); if (encodeResult.isError()) { return -1; } if (verifyRoundtrip) { byteBuffer.flip(); returnCharBuffer.clear(); CoderResult decodeResult = decoder.decode(byteBuffer, returnCharBuffer, true); if (decodeResult.isError()) { return -1; } int len2 = returnCharBuffer.position(); if (len != len2) { return -1; } if (chars[0] != returnChars[0]) { return -1; } if (len > 1 && chars[1] != returnChars[1]) { return -1; } } if (justCheck) return 1; byteBuffer.flip(); byteLen = byteBuffer.limit(); byteBuffer.get(destination, offset, byteLen); return byteLen; } catch (Exception e) { if (e instanceof BufferUnderflowException) { throw (BufferUnderflowException) e; } return -1; } } }