diff --git a/src/main/java/com/maxmind/db/Decoder.java b/src/main/java/com/maxmind/db/Decoder.java index 090caa3a..dbb37b16 100644 --- a/src/main/java/com/maxmind/db/Decoder.java +++ b/src/main/java/com/maxmind/db/Decoder.java @@ -3,7 +3,9 @@ import java.io.IOException; import java.math.BigInteger; import java.nio.ByteBuffer; +import java.nio.charset.CharacterCodingException; import java.nio.charset.Charset; +import java.nio.charset.CharsetDecoder; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; @@ -15,6 +17,8 @@ * This class CANNOT be shared between threads */ final class Decoder { + private static final Charset UTF_8 = Charset.forName("UTF-8"); + // XXX - This is only for unit testings. We should possibly make a // constructor to set this boolean POINTER_TEST_HACK = false; @@ -22,6 +26,8 @@ final class Decoder { private final ObjectMapper objectMapper; + private final CharsetDecoder utfDecoder = UTF_8.newDecoder(); + private final ByteBuffer buffer; static enum Type { @@ -182,10 +188,12 @@ private Result decodePointer(int ctrlByte, int offset) { return new Result(new LongNode(pointer), offset + pointerSize); } - private String decodeString(int size) { - ByteBuffer buffer = this.buffer.slice(); - buffer.limit(size); - return Charset.forName("UTF-8").decode(buffer).toString(); + private String decodeString(int size) throws CharacterCodingException { + int oldLimit = buffer.limit(); + buffer.limit(buffer.position() + size); + String s = utfDecoder.decode(buffer).toString(); + buffer.limit(oldLimit); + return s; } private IntNode decodeUint16(int size) {