Skip to content

Commit 63cb718

Browse files
author
Matthew L Daniel
committed
Refactor to InputStream instead of URL
InputStream is the common denominator and contains enough information to construct the ThreadBuffer (and thus the Reader).
1 parent 928cf3d commit 63cb718

3 files changed

Lines changed: 45 additions & 52 deletions

File tree

src/main/java/com/maxmind/db/Reader.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
import java.io.Closeable;
44
import java.io.File;
55
import java.io.IOException;
6+
import java.io.InputStream;
67
import java.net.InetAddress;
7-
import java.net.URL;
88
import java.nio.ByteBuffer;
99

1010
import com.fasterxml.jackson.databind.JsonNode;
@@ -56,12 +56,12 @@ public Reader(File database) throws IOException {
5656
/**
5757
* Constructs a Reader as if in mode {@link FileMode#MEMORY}, without using
5858
* a <code>File</code> instance.
59-
* @param source the URL that points to the MaxMind DB file.
59+
* @param source the InputStream that contains the MaxMind DB file.
6060
* @throws IOException
61-
* if there is an error opening or reading from the file.
61+
* if there is an error reading from the Stream.
6262
*/
63-
public Reader(URL source) throws IOException {
64-
this(ThreadBuffer.newInstance(source), source.getFile());
63+
public Reader(InputStream source) throws IOException {
64+
this(ThreadBuffer.newInstance(source), "an InputStream");
6565
}
6666

6767
/**

src/main/java/com/maxmind/db/ThreadBuffer.java

Lines changed: 15 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,37 @@
11
package com.maxmind.db;
22

3+
import java.io.ByteArrayOutputStream;
34
import java.io.Closeable;
45
import java.io.File;
56
import java.io.InputStream;
67
import java.io.IOException;
78
import java.io.RandomAccessFile;
8-
import java.net.URL;
9-
import java.net.URLConnection;
109
import java.nio.ByteBuffer;
11-
import java.nio.channels.Channels;
1210
import java.nio.channels.FileChannel;
1311
import java.nio.channels.FileChannel.MapMode;
14-
import java.nio.channels.ReadableByteChannel;
1512

1613
import com.maxmind.db.Reader.FileMode;
1714

1815
final class ThreadBuffer extends ThreadLocal<ByteBuffer> implements Closeable {
1916
/**
2017
* Construct a ThreadBuffer from the provided URL.
21-
* @param source the URL that I will read in and use as the source of my
22-
* bytes.
18+
* @param stream the source of my bytes.
2319
* @return a newly constructed instance based on the contents of your URL.
24-
* @throws IOException if unable to read from your source, or if your
25-
* source does not return all of its contents (short read).
20+
* @throws IOException if unable to read from your source.
21+
* @throws NullPointerException if you provide a NULL InputStream
2622
*/
27-
public static ThreadBuffer newInstance(URL source) throws IOException {
28-
final URLConnection conn = source.openConnection();
29-
conn.connect();
30-
31-
final InputStream stream = conn.getInputStream();
32-
final int length = conn.getContentLength();
33-
final ByteBuffer buffer = ByteBuffer.allocate(length);
34-
final ReadableByteChannel channel = Channels.newChannel(stream);
35-
int bytesRead = 0;
36-
while (true) {
37-
final int br = channel.read(buffer);
38-
if (-1 == br) {
39-
throw new IOException(String.format(
40-
"Short read from %s, wanted %d got %d", source, length, bytesRead));
41-
}
42-
bytesRead += br;
43-
if (length == bytesRead) {
44-
break;
45-
}
23+
public static ThreadBuffer newInstance(InputStream stream) throws IOException {
24+
if (null == stream) {
25+
throw new NullPointerException("Unable to use a NULL InputStream");
26+
}
27+
final ByteArrayOutputStream baos = new ByteArrayOutputStream();
28+
final byte[] buffer = new byte[16 * 1024];
29+
int br;
30+
while (-1 != (br = stream.read(buffer))) {
31+
baos.write(buffer, 0, br);
4632
}
47-
return new ThreadBuffer(buffer);
33+
final ByteBuffer bBuffer = ByteBuffer.wrap(baos.toByteArray());
34+
return new ThreadBuffer(bBuffer);
4835
}
4936

5037
// DO NOT PASS THESE OUTSIDE THIS CLASS. Doing so will remove thread

src/test/java/com/maxmind/db/ReaderTest.java

Lines changed: 25 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,10 @@
88

99
import java.io.File;
1010
import java.io.IOException;
11+
import java.io.InputStream;
1112
import java.math.BigInteger;
1213
import java.net.InetAddress;
1314
import java.net.URI;
14-
import java.net.URL;
1515
import java.net.URISyntaxException;
1616
import java.net.UnknownHostException;
1717
import java.util.HashMap;
@@ -63,9 +63,10 @@ public void testNoIpV4SearchTreeFile() throws IOException, URISyntaxException {
6363
}
6464
@Test
6565
public void testNoIpV4SearchTreeURL() throws IOException, URISyntaxException {
66-
URL resource = ReaderTest.class.getResource(
67-
"/maxmind-db/test-data/MaxMind-DB-no-ipv4-search-tree.mmdb");
68-
Reader reader = new Reader(resource);
66+
InputStream stream = ReaderTest.class.getResource(
67+
"/maxmind-db/test-data/MaxMind-DB-no-ipv4-search-tree.mmdb")
68+
.openStream();
69+
Reader reader = new Reader(stream);
6970
testNoIpV4SearchTree(reader);
7071
}
7172
private void testNoIpV4SearchTree(Reader reader) throws IOException, URISyntaxException {
@@ -87,10 +88,11 @@ public void testDecodingTypesFile() throws URISyntaxException, IOException {
8788
}
8889
@Test
8990
public void testDecodingTypesURL() throws URISyntaxException, IOException {
90-
URL resource = ReaderTest.class.getResource(
91-
"/maxmind-db/test-data/MaxMind-DB-test-decoder.mmdb");
91+
InputStream stream = ReaderTest.class.getResource(
92+
"/maxmind-db/test-data/MaxMind-DB-test-decoder.mmdb")
93+
.openStream();
9294

93-
Reader reader = new Reader(resource);
95+
Reader reader = new Reader(stream);
9496
testDecodingTypes(reader);
9597
}
9698
private void testDecodingTypes(Reader reader) throws URISyntaxException, IOException {
@@ -146,10 +148,11 @@ public void testZerosFile() throws URISyntaxException, IOException {
146148
}
147149
@Test
148150
public void testZerosURL() throws URISyntaxException, IOException {
149-
URL resource = ReaderTest.class.getResource(
150-
"/maxmind-db/test-data/MaxMind-DB-test-decoder.mmdb");
151+
InputStream stream = ReaderTest.class.getResource(
152+
"/maxmind-db/test-data/MaxMind-DB-test-decoder.mmdb")
153+
.openStream();
151154

152-
Reader reader = new Reader(resource);
155+
Reader reader = new Reader(stream);
153156
testZeros(reader);
154157
}
155158
private void testZeros(Reader reader) throws URISyntaxException, IOException {
@@ -191,11 +194,12 @@ public void testBrokenDatabaseFile() throws URISyntaxException, IOException {
191194
}
192195
@Test
193196
public void testBrokenDatabaseURL() throws URISyntaxException, IOException {
194-
URL resource = ReaderTest.class
197+
InputStream stream = ReaderTest.class
195198
.getResource(
196-
"/maxmind-db/test-data/GeoIP2-City-Test-Broken-Double-Format.mmdb");
199+
"/maxmind-db/test-data/GeoIP2-City-Test-Broken-Double-Format.mmdb")
200+
.openStream();
197201

198-
Reader reader = new Reader(resource);
202+
Reader reader = new Reader(stream);
199203
testBrokenDatabase(reader);
200204
}
201205
private void testBrokenDatabase(Reader reader) throws URISyntaxException, IOException {
@@ -221,11 +225,12 @@ public void testBrokenSearchTreePointerFile() throws URISyntaxException,
221225
@Test
222226
public void testBrokenSearchTreePointerURL() throws URISyntaxException,
223227
IOException {
224-
URL resource = ReaderTest.class
228+
InputStream stream = ReaderTest.class
225229
.getResource(
226-
"/maxmind-db/test-data/MaxMind-DB-test-broken-pointers-24.mmdb");
230+
"/maxmind-db/test-data/MaxMind-DB-test-broken-pointers-24.mmdb")
231+
.openStream();
227232

228-
Reader reader = new Reader(resource);
233+
Reader reader = new Reader(stream);
229234
testBrokenSearchTreePointer(reader);
230235
}
231236
private void testBrokenSearchTreePointer(Reader reader) throws URISyntaxException,
@@ -252,11 +257,12 @@ public void testBrokenDataPointerFile() throws UnknownHostException,
252257
@Test
253258
public void testBrokenDataPointerURL() throws UnknownHostException,
254259
IOException, URISyntaxException {
255-
URL resource = ReaderTest.class
260+
InputStream stream = ReaderTest.class
256261
.getResource(
257-
"/maxmind-db/test-data/MaxMind-DB-test-broken-pointers-24.mmdb");
262+
"/maxmind-db/test-data/MaxMind-DB-test-broken-pointers-24.mmdb")
263+
.openStream();
258264

259-
Reader reader = new Reader(resource);
265+
Reader reader = new Reader(stream);
260266
testBrokenDataPointer(reader);
261267
}
262268
private void testBrokenDataPointer(Reader reader) throws UnknownHostException,

0 commit comments

Comments
 (0)