diff --git a/src/main/java/com/maxmind/db/Decoder.java b/src/main/java/com/maxmind/db/Decoder.java
index 34863a29..55936c66 100644
--- a/src/main/java/com/maxmind/db/Decoder.java
+++ b/src/main/java/com/maxmind/db/Decoder.java
@@ -58,34 +58,6 @@ public static Type fromControlByte(int b) {
}
}
- static class Result {
- private final JsonNode node;
- private int offset;
-
- Result(JsonNode node, int offset) {
- this.node = node;
- this.offset = offset;
- }
-
- JsonNode getNode() {
- return this.node;
- }
-
- int getOffset() {
- return this.offset;
- }
-
- void setOffset(int offset) {
- this.offset = offset;
- }
-
- @Override
- public String toString() {
- return "Result[" + offset + " " + node.getNodeType() + " " + node.asText() + "]";
- }
-
- }
-
Decoder(NodeCache cache, ByteBuffer buffer, long pointerBase) {
this.cache = cache;
this.pointerBase = pointerBase;
@@ -95,11 +67,11 @@ public String toString() {
private final NodeCache.Loader cacheLoader = new NodeCache.Loader() {
@Override
public JsonNode load(int key) throws IOException {
- return decode(key).getNode();
+ return decode(key);
}
};
- Result decode(int offset) throws IOException {
+ JsonNode decode(int offset) throws IOException {
if (offset >= this.buffer.capacity()) {
throw new InvalidDatabaseException(
"The MaxMind DB file's data section contains bad data: "
@@ -107,8 +79,11 @@ Result decode(int offset) throws IOException {
}
this.buffer.position(offset);
+ return decode();
+ }
+
+ JsonNode decode() throws IOException {
int ctrlByte = 0xFF & this.buffer.get();
- offset++;
Type type = Type.fromControlByte(ctrlByte);
@@ -120,16 +95,17 @@ Result decode(int offset) throws IOException {
int base = pointerSize == 4 ? (byte) 0 : (byte) (ctrlByte & 0x7);
int packed = this.decodeInteger(base, pointerSize);
long pointer = packed + this.pointerBase + POINTER_VALUE_OFFSETS[pointerSize];
- int newOffset = offset + pointerSize;
// for unit testing
if (this.POINTER_TEST_HACK) {
- return new Result(new LongNode(pointer), newOffset);
+ return new LongNode(pointer);
}
int targetOffset = (int) pointer;
+ int position = buffer.position();
JsonNode node = cache.get(targetOffset, cacheLoader);
- return new Result(node, newOffset);
+ buffer.position(position);
+ return node;
}
if (type.equals(Type.EXTENDED)) {
@@ -145,7 +121,6 @@ Result decode(int offset) throws IOException {
}
type = Type.get(typeNum);
- offset++;
}
int size = ctrlByte & 0x1f;
@@ -162,49 +137,38 @@ Result decode(int offset) throws IOException {
default:
size = 65821 + (i & (0x0FFFFFFF >>> 32 - 8 * bytesToRead));
}
- offset += bytesToRead;
}
- return this.decodeByType(type, offset, size);
+ return this.decodeByType(type, size);
}
- private Result decodeByType(Type type, int offset, int size)
+ private JsonNode decodeByType(Type type, int size)
throws IOException {
- // MAP, ARRAY, and BOOLEAN do not use newOffset as we don't read the
- // next size bytes. For all other types, we do.
- int newOffset = offset + size;
switch (type) {
case MAP:
- return this.decodeMap(size, offset);
+ return this.decodeMap(size);
case ARRAY:
- return this.decodeArray(size, offset);
+ return this.decodeArray(size);
case BOOLEAN:
- return new Result(Decoder.decodeBoolean(size), offset);
+ return Decoder.decodeBoolean(size);
case UTF8_STRING:
- TextNode s = new TextNode(this.decodeString(size));
- return new Result(s, newOffset);
+ return new TextNode(this.decodeString(size));
case DOUBLE:
- return new Result(this.decodeDouble(size), newOffset);
+ return this.decodeDouble(size);
case FLOAT:
- return new Result(this.decodeFloat(size), newOffset);
+ return this.decodeFloat(size);
case BYTES:
- BinaryNode b = new BinaryNode(this.getByteArray(size));
- return new Result(b, newOffset);
+ return new BinaryNode(this.getByteArray(size));
case UINT16:
- IntNode i = this.decodeUint16(size);
- return new Result(i, newOffset);
+ return this.decodeUint16(size);
case UINT32:
- LongNode l = this.decodeUint32(size);
- return new Result(l, newOffset);
+ return this.decodeUint32(size);
case INT32:
- IntNode int32 = this.decodeInt32(size);
- return new Result(int32, newOffset);
+ return this.decodeInt32(size);
case UINT64:
- BigIntegerNode bi = this.decodeBigInteger(size);
- return new Result(bi, newOffset);
+ return this.decodeBigInteger(size);
case UINT128:
- BigIntegerNode uint128 = this.decodeBigInteger(size);
- return new Result(uint128, newOffset);
+ return this.decodeBigInteger(size);
default:
throw new InvalidDatabaseException(
"Unknown or unexpected type: " + type.name());
@@ -292,34 +256,27 @@ private static BooleanNode decodeBoolean(int size)
}
}
- private Result decodeArray(int size, int offset) throws IOException {
+ private JsonNode decodeArray(int size) throws IOException {
ArrayNode array = OBJECT_MAPPER.createArrayNode();
for (int i = 0; i < size; i++) {
- Result r = this.decode(offset);
- offset = r.getOffset();
- array.add(r.getNode());
+ JsonNode r = this.decode();
+ array.add(r);
}
- return new Result(array, offset);
+ return array;
}
- private Result decodeMap(int size, int offset) throws IOException {
+ private JsonNode decodeMap(int size) throws IOException {
ObjectNode map = OBJECT_MAPPER.createObjectNode();
for (int i = 0; i < size; i++) {
- Result keyResult = this.decode(offset);
- String key = keyResult.getNode().asText();
- offset = keyResult.getOffset();
-
- Result valueResult = this.decode(offset);
- JsonNode value = valueResult.getNode();
- offset = valueResult.getOffset();
-
+ String key = this.decode().asText();
+ JsonNode value = this.decode();
map.set(key, value);
}
- return new Result(map, offset);
+ return map;
}
private byte[] getByteArray(int length) {
diff --git a/src/main/java/com/maxmind/db/Reader.java b/src/main/java/com/maxmind/db/Reader.java
index 004e3268..198f0ff3 100644
--- a/src/main/java/com/maxmind/db/Reader.java
+++ b/src/main/java/com/maxmind/db/Reader.java
@@ -131,7 +131,7 @@ private Reader(BufferHolder bufferHolder, String name, NodeCache cache) throws I
int start = this.findMetadataStart(buffer, name);
Decoder metadataDecoder = new Decoder(this.cache, buffer, start);
- this.metadata = new Metadata(metadataDecoder.decode(start).getNode());
+ this.metadata = new Metadata(metadataDecoder.decode(start));
this.ipV4Start = this.findIpV4StartNode(buffer);
}
@@ -251,7 +251,7 @@ private JsonNode resolveDataPointer(ByteBuffer buffer, int pointer)
// found.
Decoder decoder = new Decoder(this.cache, buffer,
this.metadata.getSearchTreeSize() + DATA_SECTION_SEPARATOR_SIZE);
- return decoder.decode(resolved).getNode();
+ return decoder.decode(resolved);
}
/*
diff --git a/src/test/java/com/maxmind/db/DecoderTest.java b/src/test/java/com/maxmind/db/DecoderTest.java
index ec8ca0c6..dc5ef462 100644
--- a/src/test/java/com/maxmind/db/DecoderTest.java
+++ b/src/test/java/com/maxmind/db/DecoderTest.java
@@ -430,36 +430,28 @@ private static void testTypeDecoding(Decoder.Type type, Map tests
// XXX - this could be streamlined
if (type.equals(Decoder.Type.BYTES)) {
- assertArrayEquals(desc, (byte[]) expect, decoder.decode(0)
- .getNode().binaryValue());
+ assertArrayEquals(desc, (byte[]) expect, decoder.decode(0).binaryValue());
} else if (type.equals(Decoder.Type.ARRAY)) {
- assertEquals(desc, expect, decoder.decode(0).getNode());
+ assertEquals(desc, expect, decoder.decode(0));
} else if (type.equals(Decoder.Type.UINT16)
|| type.equals(Decoder.Type.INT32)) {
- assertEquals(desc, expect, decoder.decode(0).getNode()
- .asInt());
+ assertEquals(desc, expect, decoder.decode(0).asInt());
} else if (type.equals(Decoder.Type.UINT32)
|| type.equals(Decoder.Type.POINTER)) {
- assertEquals(desc, expect, decoder.decode(0).getNode()
- .asLong());
+ assertEquals(desc, expect, decoder.decode(0).asLong());
} else if (type.equals(Decoder.Type.UINT64)
|| type.equals(Decoder.Type.UINT128)) {
- assertEquals(desc, expect, decoder.decode(0).getNode()
- .bigIntegerValue());
+ assertEquals(desc, expect, decoder.decode(0).bigIntegerValue());
} else if (type.equals(Decoder.Type.DOUBLE)) {
- assertEquals(desc, expect, decoder.decode(0).getNode()
- .asDouble());
+ assertEquals(desc, expect, decoder.decode(0).asDouble());
} else if (type.equals(Decoder.Type.FLOAT)) {
- assertEquals(desc, new FloatNode((Float) expect), decoder
- .decode(0).getNode());
+ assertEquals(desc, new FloatNode((Float) expect), decoder.decode(0));
} else if (type.equals(Decoder.Type.UTF8_STRING)) {
- assertEquals(desc, expect, decoder.decode(0).getNode()
- .asText());
+ assertEquals(desc, expect, decoder.decode(0).asText());
} else if (type.equals(Decoder.Type.BOOLEAN)) {
- assertEquals(desc, expect, decoder.decode(0).getNode()
- .asBoolean());
+ assertEquals(desc, expect, decoder.decode(0).asBoolean());
} else {
- assertEquals(desc, expect, decoder.decode(0).getNode());
+ assertEquals(desc, expect, decoder.decode(0));
}
} finally {
fc.close();
diff --git a/src/test/java/com/maxmind/db/PointerTest.java b/src/test/java/com/maxmind/db/PointerTest.java
index 717260e4..54531987 100644
--- a/src/test/java/com/maxmind/db/PointerTest.java
+++ b/src/test/java/com/maxmind/db/PointerTest.java
@@ -23,26 +23,26 @@ public void testWithPointers() throws IOException {
ObjectNode map = om.createObjectNode();
map.put("long_key", "long_value1");
- assertEquals(map, decoder.decode(0).getNode());
+ assertEquals(map, decoder.decode(0));
map = om.createObjectNode();
map.put("long_key", "long_value2");
- assertEquals(map, decoder.decode(22).getNode());
+ assertEquals(map, decoder.decode(22));
map = om.createObjectNode();
map.put("long_key2", "long_value1");
- assertEquals(map, decoder.decode(37).getNode());
+ assertEquals(map, decoder.decode(37));
map = om.createObjectNode();
map.put("long_key2", "long_value2");
- assertEquals(map, decoder.decode(50).getNode());
+ assertEquals(map, decoder.decode(50));
map = om.createObjectNode();
map.put("long_key", "long_value1");
- assertEquals(map, decoder.decode(55).getNode());
+ assertEquals(map, decoder.decode(55));
map = om.createObjectNode();
map.put("long_key2", "long_value2");
- assertEquals(map, decoder.decode(57).getNode());
+ assertEquals(map, decoder.decode(57));
}
}