Skip to content

Instantly share code, notes, and snippets.

@willemsst
Last active December 20, 2015 12:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save willemsst/6129674 to your computer and use it in GitHub Desktop.
Save willemsst/6129674 to your computer and use it in GitHub Desktop.
Create a new String from a ByteBuffer with only one char[] (so no Array.copyOf()) It would be nice if we could get rid of the CharBuffer as well, but, it's a start. String has a packaged scoped constructor - which doesn't use Array.copyOf(). It can be accessed through reflection.
package be.idevelop.util;
/**
* MIT License http://opensource.org/licenses/MIT
*
* @author @willemsst
*/
import java.lang.reflect.*;
import java.nio.*;
import java.nio.charset.*;
public class ByteBufferToStringConverter {
private static final Constructor<String> PACKAGE_SCOPED_STRING_CONSTRUCTOR;
static {
try {
PACKAGE_SCOPED_STRING_CONSTRUCTOR = String.class.getDeclaredConstructor(char[].class, boolean.class);
PACKAGE_SCOPED_STRING_CONSTRUCTOR.setAccessible(true);
} catch (NoSuchMethodException e) {
throw new IllegalStateException("Packaged scope String constructor not found", e);
}
}
private ByteBufferToStringConverter() {
throw new UnsupportedOperationException("Util class. Can not be instantiated.");
}
public static String convert(ByteBuffer byteBuffer, Charset charset) {
return createNewString(convertToCharArray(byteBuffer, charset));
}
private static char[] convertToCharArray(ByteBuffer byteBuffer, Charset charset) {
char[] chars = new char[byteBuffer.remaining()];
if (byteBuffer.remaining() > 0) {
CharsetDecoder decoder = charset.newDecoder();
CharBuffer charBuffer;
try {
charBuffer = decoder.decode(byteBuffer);
} catch (CharacterCodingException e) {
throw new IllegalStateException("Character decoding failed for charset " + charset.displayName(), e);
}
chars = charBuffer.array();
}
return chars;
}
private static String createNewString(char[] chars) {
try {
return PACKAGE_SCOPED_STRING_CONSTRUCTOR.newInstance(chars, true);
} catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
throw new IllegalStateException("Could not invoke packaged scoped String constructor");
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment