IBM Support

Character Conversion in Java 8

Technical Blog Post


Abstract

Character Conversion in Java 8

Body

Character Conversion in Java 8

This article will provide information about JRE 8 package java.nio.charset for the conversion from character to byte and from byte to character.

Starting from JRE 1.8 the package sun.io converter removed so user should use java.nio.charset package for character conversion in their application. This article is applicable in general and also for customer using Db2Connect Java driver "IBM Data Server driver for JDBC and SQLJ "

1) 
Example of Character to byte conversion while inserting characters to Server.

public class JavaNIOCharToByteConverter
{
 private java.nio.CharBuffer charBuffer;
 private java.nio.charset.CharsetEncoder encoder;
 private String encoding;
 private int nextByteIndex;
 private int nextCharIndex;
 protected
JavaNIOCharToByteConverter (String encoding, boolean doNotReportError) throws
   java.io.UnsupportedEncodingException
 {
   encoder = java.nio.charset.Charset.forName (encoding).newEncoder ();
   encoder.onMalformedInput (doNotReportError ? java.nio.charset.CodingErrorAction.REPLACE : java.nio.charset.CodingErrorAction.REPORT);
   encoder.onUnmappableCharacter (doNotReportError ? java.nio.charset.CodingErrorAction.REPLACE : java.nio.charset.CodingErrorAction.REPORT);
   encoding = encoding;
   nextByteIndex = 0;
   nextCharIndex = 0;
 }
 public int convert (char[] input, int inOff, int inEnd, byte[] output, int outOff, int outEnd) throws
   java.nio.charset.CharacterCodingException
 {
   int inputLength = inEnd - inOff;
   if (charBuffer == null) {
     charBuffer = java.nio.CharBuffer.allocate(inputLength);
   }
   else if (charBuffer.capacity() < inputLength)
   {
     charBuffer = java.nio.CharBuffer.allocate (inputLength);
   }
   // clear the buffer, position is 0, limit is the capacity
   charBuffer.clear();
   // position is the input (inEnd - inOff)
   charBuffer.put (input, inOff, inEnd);
   // limit is set to position, position is set to 0
   charBuffer.flip();
   nextCharIndex = inOff;
   nextByteIndex = outOff;
   java.nio.ByteBuffer byteBuffer = java.nio.ByteBuffer.wrap (output, outOff, outEnd-outOff).slice();
   java.nio.charset.CoderResult result = encoder.encode (charBuffer, byteBuffer, true);
   nextCharIndex += charBuffer.position();
   // limit is set to position, posiition is set to 0
   byteBuffer.flip();
   nextByteIndex += byteBuffer.limit();
   if (result.isError() || result.isOverflow())
     result.throwException();
   return byteBuffer.limit();
 }
 // called after convert call
 public int flush (byte[] outByteBuffer, int offset, int outEnd) throws
   java.nio.charset.CharacterCodingException
 {
   java.nio.ByteBuffer byteBuffer = java.nio.ByteBuffer.wrap(outByteBuffer, offset, outEnd-offset).slice();
   java.nio.charset.CoderResult result = encoder.flush (byteBuffer);
   // limit is set to position, posiition is set to 0
   byteBuffer.flip();
   nextByteIndex += byteBuffer.limit();
   if (result.isError() || result.isOverflow())
     result.throwException();
   return byteBuffer.limit();
 }
}

2) Example of Bytes to character conversion while reading characters from Server.

public class JavaNIOByteToCharConverters
{
 private java.nio.ByteBuffer byteBuffer;
 private java.nio.charset.CharsetDecoder decoder;
 private String encoding;
 private int nextByteIndex;
 private int nextCharIndex;
 protected JavaNIOByteToCharConverters (String encoding,boolean alternateUTF8Encoding, boolean doNotReportError) throws java.io.UnsupportedEncodingException
 {
   //JDK 8 follows strict UTF8 encoding ,"UTF8J" retains relaxed UTF8 encoding
   if(alternateUTF8Encoding==true &&
   (encoding.equalsIgnoreCase("UTF8" ) || encoding.equalsIgnoreCase("UTF-8" ) || encoding.equalsIgnoreCase("UTF_8" )) )
   encoding ="UTF8J";
   decoder = java.nio.charset.Charset.forName (encoding).newDecoder ();
   decoder.onMalformedInput (doNotReportError ? java.nio.charset.CodingErrorAction.REPLACE : java.nio.charset.CodingErrorAction.REPORT);
   decoder.onUnmappableCharacter (doNotReportError ? java.nio.charset.CodingErrorAction.REPLACE : java.nio.charset.CodingErrorAction.REPORT);
   encoding = encoding;
   nextByteIndex = 0;
   nextCharIndex = 0;
 }
 public int convert (byte[] rawBytes, int byteOffset, int byteEnd, char[] output, int charOffset, int charEnd) throws java.nio.charset.MalformedInputException, java.nio.BufferOverflowException, java.nio.charset.UnmappableCharacterException, java.nio.charset.CharacterCodingException
 {
   //first pass, initialize ByteBuffer
   if (byteBuffer == null) byteBuffer = java.nio.ByteBuffer.allocate (byteEnd - byteOffset + 3);
   int spareBytesPosition = byteBuffer.position ();
   //increase ByteBuffer if needed.
   if (byteBuffer.limit () < (byteEnd - byteOffset)) {
     java.nio.ByteBuffer newBB = java.nio.ByteBuffer.allocate (byteEnd - byteOffset + byteBuffer.position () + 3);
     byteBuffer.flip ();
     while (byteBuffer.position () < byteBuffer.limit ())
       newBB.put (byteBuffer.get ());
     byteBuffer = newBB;
   }
   byteBuffer.put (rawBytes, byteOffset, byteEnd - byteOffset);
   byteBuffer.flip ();
   java.nio.CharBuffer charBuffer = java.nio.CharBuffer.wrap (output, charOffset, charEnd - charOffset).slice ();
   java.nio.charset.CoderResult result = null;
   result = decoder.decode (byteBuffer, charBuffer, false);
   nextByteIndex = byteBuffer.position () + byteOffset - spareBytesPosition;
   if (result.isError ()) result.throwException ();
   if (result == java.nio.charset.CoderResult.UNDERFLOW && (byteBuffer.position () < (byteBuffer.limit ()))) {
     byte[] unconvertedBytes = new byte[byteBuffer.limit () - byteBuffer.position ()];
     byteBuffer.get (unconvertedBytes);
     nextByteIndex = byteBuffer.position () + byteOffset - spareBytesPosition;
     byteBuffer.clear ();
     byteBuffer.put (unconvertedBytes);
   }
   else {
     byteBuffer.clear ();
   }
   charBuffer.flip ();
   nextCharIndex = charBuffer.limit ();
   //to simulate sun.io.ConversionBufferFullException
   if (result == java.nio.charset.CoderResult.OVERFLOW) result.throwException ();
   return nextCharIndex;
 }
 public char[] convertAll (byte[] rawBytes) throws java.nio.charset.CharacterCodingException
 {
   java.nio.ByteBuffer byteBuffer = java.nio.ByteBuffer.wrap (rawBytes);
   java.nio.CharBuffer charBuffer = decoder.decode (byteBuffer);
   char[] returnVal = new char[charBuffer.limit ()];
   charBuffer.get (returnVal);
   return returnVal;
 }
}

JRE 1.7 or lower version contains sun.io packages so user can use it for character conversion. sun.io.CharToByteConverter is deprecated and removed from JRE 1.8 and higher.

1) Character to byte conversion .

public class SunIOCharToByteConverter
{
 private sun.io.CharToByteConverter ctbc;
 protected SunIOCharToByteConverter (String encoding) throws
   java.io.UnsupportedEncodingException
 {
   ctbc = sun.io.CharToByteConverter.getConverter (encoding);
 }
 public int convert (char[] input, int inOffset, int inEnd, byte[] output, int outOffset, int outEnd) throws
   java.nio.charset.CharacterCodingException
 {
   try {
     return ctbc.convert(input, inOffset, inEnd, output, outOffset, outEnd);
   }
   catch (sun.io.MalformedInputException ex) { }
   catch (sun.io.UnknownCharacterException ex) {  }
   catch (sun.io.ConversionBufferFullException ex) { }
   return -1;
 }
 public int flush (byte[] outByteBuffer, int offset, int outEnd) throws
   java.nio.charset.CharacterCodingException
 {
   try {
     return ctbc.flush (outByteBuffer, offset, outEnd);
   }
   catch (sun.io.MalformedInputException ex) {}
   catch (sun.io.ConversionBufferFullException ex)
   {}
   return -1;
 }
}

sun.io.ByteToCharConverter is deprecated and removed from JRE 1.8 and higher.

2) Bytes to character conversion while reading characters from Server.

public class SunIOByteToCharConverter
{
 private sun.io.ByteToCharConverter btcc;
 protected SunIOByteToCharConverter (String encoding) throws java.io.UnsupportedEncodingException
 {
   btcc = sun.io.ByteToCharConverter.getConverter (encoding);
 }
 public int convert (byte[] rawBytes, int byteOffset, int byteEnd, char[] output, int charOffset, int charEnd) throws java.nio.charset.CharacterCodingException
 {
   try{
   return btcc.convert (rawBytes, byteOffset, byteEnd, output, charOffset, charEnd);
   }
   catch (sun.io.MalformedInputException e) { }
   catch (sun.io.ConversionBufferFullException e){ }
   catch (sun.io.UnknownCharacterException e){ }
   return -1;
 }
 public char[] convertAll (byte[] rawBytes) throws java.nio.charset.MalformedInputException
 {
   try {
     return btcc.convertAll (rawBytes);
   }
   catch (sun.io.MalformedInputException e) {}
   return null;
 }
}

Authors:

Kollol k misra (kmisra@rocketsoftware.com)

Db2Connect Architect


Sujan S Ghosh ( sghosh@rocketsoftware.com)
Advisory software engineer, Db2Connect
 

[{"Business Unit":{"code":"BU053","label":"Cloud & Data Platform"},"Product":{"code":"SSEPDU","label":"DB2 Connect"},"Component":"","Platform":[{"code":"PF025","label":"Platform Independent"}],"Version":"","Edition":""}]

UID

ibm11142002