@@ -117,7 +117,7 @@ public Reader(File database, FileMode fileMode, NodeCache cache) throws IOExcept
117117 }
118118
119119 private Reader (BufferHolder bufferHolder , String name , NodeCache cache ) throws IOException {
120- this .bufferHolderReference = new AtomicReference <BufferHolder >(
120+ this .bufferHolderReference = new AtomicReference <>(
121121 bufferHolder );
122122
123123 if (cache == null ) {
@@ -135,52 +135,55 @@ private Reader(BufferHolder bufferHolder, String name, NodeCache cache) throws I
135135 }
136136
137137 /**
138- * Looks up the <code>address </code> in the MaxMind DB.
138+ * Looks up <code>ipAddress </code> in the MaxMind DB.
139139 *
140140 * @param ipAddress the IP address to look up.
141- * @return the record for the IP address.
141+ * @return the record data for the IP address.
142142 * @throws IOException if a file I/O error occurs.
143143 */
144144 public JsonNode get (InetAddress ipAddress ) throws IOException {
145- ByteBuffer buffer = this .getBufferHolder ().get ();
146- int pointer = this .findAddressInTree (buffer , ipAddress );
147- if (pointer == 0 ) {
148- return null ;
149- }
150- return this .resolveDataPointer (buffer , pointer );
151- }
152-
153- private BufferHolder getBufferHolder () throws ClosedDatabaseException {
154- BufferHolder bufferHolder = this .bufferHolderReference .get ();
155- if (bufferHolder == null ) {
156- throw new ClosedDatabaseException ();
157- }
158- return bufferHolder ;
145+ return getRecord (ipAddress ).getData ();
159146 }
147+ /**
148+ * Looks up <code>ipAddress</code> in the MaxMind DB.
149+ *
150+ * @param ipAddress the IP address to look up.
151+ * @return the record for the IP address. If there is no data for the
152+ * address, the non-null {@link Record} will still be returned.
153+ * @throws IOException if a file I/O error occurs.
154+ */
155+ public Record getRecord (InetAddress ipAddress )
156+ throws IOException {
157+ ByteBuffer buffer = this .getBufferHolder ().get ();
160158
161- private int findAddressInTree (ByteBuffer buffer , InetAddress address )
162- throws InvalidDatabaseException {
163- byte [] rawAddress = address .getAddress ();
159+ byte [] rawAddress = ipAddress .getAddress ();
164160
165161 int bitLength = rawAddress .length * 8 ;
166162 int record = this .startNode (bitLength );
163+ int nodeCount = this .metadata .getNodeCount ();
167164
168- for (int i = 0 ; i < bitLength ; i ++) {
169- if (record >= this .metadata .getNodeCount ()) {
170- break ;
171- }
172- int b = 0xFF & rawAddress [i / 8 ];
173- int bit = 1 & (b >> 7 - (i % 8 ));
165+ int pl = 0 ;
166+ for (; pl < bitLength && record < nodeCount ; pl ++) {
167+ int b = 0xFF & rawAddress [pl / 8 ];
168+ int bit = 1 & (b >> 7 - (pl % 8 ));
174169 record = this .readNode (buffer , record , bit );
175170 }
176- if (record == this .metadata .getNodeCount ()) {
177- // record is empty
178- return 0 ;
179- } else if (record > this .metadata .getNodeCount ()) {
171+
172+ JsonNode dataRecord = null ;
173+ if (record > nodeCount ) {
180174 // record is a data pointer
181- return record ;
175+ dataRecord = this . resolveDataPointer ( buffer , record ) ;
182176 }
183- throw new InvalidDatabaseException ("Something bad happened" );
177+
178+ return new Record (dataRecord , ipAddress , pl );
179+ }
180+
181+ private BufferHolder getBufferHolder () throws ClosedDatabaseException {
182+ BufferHolder bufferHolder = this .bufferHolderReference .get ();
183+ if (bufferHolder == null ) {
184+ throw new ClosedDatabaseException ();
185+ }
186+ return bufferHolder ;
184187 }
185188
186189 private int startNode (int bitLength ) {
0 commit comments