diff --git a/maker/java/pom.xml b/maker/java/pom.xml index d98eb1d..614c506 100644 --- a/maker/java/pom.xml +++ b/maker/java/pom.xml @@ -4,7 +4,7 @@ org.lionsoul ip2region-maker - 1.0.0 + 3.0.0 jar ip2region diff --git a/maker/java/src/main/java/org/lionsoul/ip2region/MakerTest.java b/maker/java/src/main/java/org/lionsoul/ip2region/MakerTest.java index a99080b..bf0fecc 100644 --- a/maker/java/src/main/java/org/lionsoul/ip2region/MakerTest.java +++ b/maker/java/src/main/java/org/lionsoul/ip2region/MakerTest.java @@ -10,6 +10,7 @@ package org.lionsoul.ip2region; import org.lionsoul.ip2region.xdb.IndexPolicy; import org.lionsoul.ip2region.xdb.Log; import org.lionsoul.ip2region.xdb.Maker; +import org.lionsoul.ip2region.xdb.Version; import java.util.ArrayList; import java.util.Arrays; @@ -29,6 +30,7 @@ public class MakerTest { System.out.println("options:"); System.out.println(" --src string source ip text file path"); System.out.println(" --dst string destination binary xdb file path"); + System.out.println(" --version string IP version, options: ipv4/ipv6, specify this flag so you don't get confused"); System.out.println(" --field-list string field index list imploded with ',' eg: 0,1,2,3-6,7"); System.out.println(" --log-level string set the log level, options: debug/info/warn/error"); } @@ -108,7 +110,7 @@ public class MakerTest { } public static void genDb(String[] args) throws Exception { - String srcFile = "", dstFile = ""; + String srcFile = "", dstFile = "", ipVersion = ""; String fieldList = "", logLevel = "info"; int indexPolicy = IndexPolicy.Vector; for (final String r : args) { @@ -133,8 +135,10 @@ public class MakerTest { srcFile = val; } else if ("dst".equals(key)) { dstFile = val; + } else if ("version".equals(key)) { + ipVersion = val; } else if ("field-list".equals(key)) { - fieldList = val; + fieldList = val; } else if ("log-level".equals(key)) { logLevel = val; } else { @@ -148,6 +152,9 @@ public class MakerTest { return; } + // IP version + final Version version = Version.fromName(ipVersion); + final int[] fields = getFieldList(fieldList); if (fields == null) { return; @@ -155,7 +162,7 @@ public class MakerTest { // check and make the field list long tStart = System.currentTimeMillis(); - final Maker maker = new Maker(indexPolicy, srcFile, dstFile, fields); + final Maker maker = new Maker(version, indexPolicy, srcFile, dstFile, fields); log.infof("Generating xdb with src=%s, dst=%s, logLevel=%s", srcFile, dstFile, logLevel); Maker.log.setLevel(logLevel); maker.init(); diff --git a/maker/java/src/main/java/org/lionsoul/ip2region/UtilTest.java b/maker/java/src/main/java/org/lionsoul/ip2region/UtilTest.java deleted file mode 100644 index 2149875..0000000 --- a/maker/java/src/main/java/org/lionsoul/ip2region/UtilTest.java +++ /dev/null @@ -1,79 +0,0 @@ -// Copyright 2022 The Ip2Region Authors. All rights reserved. -// Use of this source code is governed by a Apache2.0-style -// license that can be found in the LICENSE file. -// -// @Author Lion -// @Date 2022/07/15 - -package org.lionsoul.ip2region; - -import org.lionsoul.ip2region.xdb.IndexPolicy; -import org.lionsoul.ip2region.xdb.Log; -import org.lionsoul.ip2region.xdb.Segment; -import org.lionsoul.ip2region.xdb.Util; - -import java.util.regex.Matcher; - -public class UtilTest { - - public static final Log log = Log.getLogger(UtilTest.class); - - public static void testSegment() { - final String[] t_segs = { - "1.1.0.0|1.3.3.24|中国|广东|深圳|电信", - "0.0.0.0|1.255.225.254|0|0|0|内网IP|内网IP", - "28.201.224.0|29.34.191.255|美国|0|0|0|0" - }; - - for (String str : t_segs) { - try { - final Segment seg = Segment.parse(str); - log.infof("segment(%s)=%s, split: ", str, seg.toString()); - for (Segment s : seg.split()) { - log.debugf(s.toString()); - } - } catch (Exception e) { - log.errorf("failed to parse segment `%s`: %s", str, e.getMessage()); - } - } - } - - public static void testFieldFilter() { - final String reg = "0|16777215|保留|保留|保留|保留|||||||||||"; - final String[] fs = reg.split("\\|", -1); - log.infof("length: %d", fs.length); - for (String s : fs) { - log.infof("%s", s); - } - } - - public static void testIndexParse() { - final String[] ss = new String[]{"1", "2-3", "23", "3-", "x-", "3-x", "4x"}; - for (String s : ss) { - log.infof("parse: %s", s); - final Matcher m = MakerTest.p.matcher(s); - if (m.matches()) { - for (int i = 0; i < m.groupCount(); i++) { - log.infof("match: %d/%d, str: %s", i, m.groupCount(), m.group(i)); - } - } else { - log.infof("no match for: %s", s); - } - } - } - - public static void main(String[] args) { - System.out.println("+-- testing segments"); - testSegment(); - System.out.println(); - - System.out.println("+-- testing field filter"); - testFieldFilter(); - System.out.println(); - - System.out.println("+-- testing index parse"); - testIndexParse(); - System.out.println(); - } - -} diff --git a/maker/java/src/main/java/org/lionsoul/ip2region/xdb/Maker.java b/maker/java/src/main/java/org/lionsoul/ip2region/xdb/Maker.java index fb587f7..f1a5fb0 100644 --- a/maker/java/src/main/java/org/lionsoul/ip2region/xdb/Maker.java +++ b/maker/java/src/main/java/org/lionsoul/ip2region/xdb/Maker.java @@ -19,6 +19,8 @@ // -- 4bytes: generate unix timestamp (version) // -- 4bytes: index block start ptr // -- 4bytes: index block end ptr +// -- 2bytes: ip version number (4/6 since IPv6 supporting) +// -- 2bytes: runtime ptr bytes // // // 2. data block : region or whatever data info. @@ -57,19 +59,24 @@ import java.util.*; public class Maker { // constants define - public static final int VersionNo = 2; - public static final int HeaderInfoLength = 256; - public static final int VectorIndexRows = 256; - public static final int VectorIndexCols = 256; - public static final int VectorIndexSize = 8; - public static final int SegmentIndexSize = 14; + public static final int VersionNo = 3; // 2 for XDB 2.0, 3 for XDB 3.0 + public static final int HeaderInfoLength = 256; + public static final int VectorIndexRows = 256; + public static final int VectorIndexCols = 256; + public static final int VectorIndexSize = 8; // in bytes + public static final int RuntimePtrSize = 4; // in bytes + public static final long MaxFilePointer = (1L << (RuntimePtrSize * 8)) - 1; public static final int VectorIndexLength = VectorIndexRows * VectorIndexCols * VectorIndexSize; public static final Log log = Log.getLogger(Maker.class); + // IP version since xdb 3.0 + private final Version version; + // source text file handle private final File srcFile; private final int[] fields; + private final List segments; private final Charset bytesCharset; @@ -85,13 +92,14 @@ public class Maker { // vector index raw bytes private final byte[] vectorIndex; - public Maker(int policy, String srcPath, String dstPath, int[] fields) throws IOException { + public Maker(Version version, int policy, String srcPath, String dstPath, int[] fields) throws IOException { this.srcFile = new File(srcPath); if (!this.srcFile.exists()) { throw new FileNotFoundException("source text file `" + srcPath + "` not found"); } - this.fields = fields; + this.version = version; + this.fields = fields; /// check and delete the target xdb file if it exists /// final File dstFile = new File(dstPath); @@ -119,40 +127,31 @@ public class Maker { final byte[] header = new byte[HeaderInfoLength]; // encode the data - Util.write(header, 0, VersionNo, 2); - Util.write(header, 2, indexPolicy, 2); - Util.write(header, 4, System.currentTimeMillis() / 1000, 4); - Util.write(header, 8, 0, 4); // start index ptr - Util.write(header, 12, 0, 4); // end index ptr + // 1, data version number + LittleEndian.put(header, 0, VersionNo, 2); + + // 2, index policy code + LittleEndian.put(header, 2, indexPolicy, 2); + + // 3, generate unix timestamp + LittleEndian.put(header, 4, System.currentTimeMillis() / 1000, 4); + + // 4, index block start ptr + LittleEndian.put(header, 8, 0, 4); // start index ptr + + // 5, index block end ptr + LittleEndian.put(header, 12, 0, 4); // end index ptr + + // since xdb 3.0 + // 6, IP version + LittleEndian.put(header, 16, version.id, 2); // IP version + + // 7, runtime ptr bytes + LittleEndian.put(header, 18, RuntimePtrSize, 2); // runtime ptr bytes dstHandle.write(header); } - // internal method to apply the region fields filter - private String getFilteredRegion(String region) { - if (this.fields.length == 0) { - return region; - } - - final String[] fs = region.split("\\|", -1); - final StringBuilder sb = new StringBuilder(); - final int tailing = this.fields.length - 1; - for (int i = 0; i < this.fields.length; i++) { - final int idx = this.fields[i]; - if (idx >= fs.length) { - throw new IllegalArgumentException("field index `" - + idx + "` exceeded the max length `" + fs.length + "`"); - } - - sb.append(fs[idx]); - if (sb.length() > 0 && i < tailing) { - sb.append("|"); - } - } - - return sb.toString(); - } - // load all the segments private void loadSegments() throws Exception { log.infof("try to load the segments ... "); @@ -170,9 +169,9 @@ public class Maker { throw new Exception("invalid ip segment line `"+ps[0]+"`"); } - final long sip = Util.checkIP(ps[0]); - final long eip = Util.checkIP(ps[1]); - if (sip > eip) { + final byte[] sip = Util.parseIP(ps[0]); + final byte[] eip = Util.parseIP(ps[1]); + if (Util.ipCompare(sip, eip) > 0) { br.close(); throw new Exception("start ip("+ps[0]+") should not be greater than end ip("+ps[1]+")"); } @@ -182,15 +181,21 @@ public class Maker { throw new Exception("empty region info in segment line `"+ps[2]+"`"); } + // ip version check + if (version.bytes != sip.length) { + br.close(); + throw new InvalidInetAddressException("invalid ip segment(" + version.name + " expected)"); + } + // check the continuity of the data segment if (last != null) { - if (last.endIP + 1 != sip) { + if (Util.ipCompare(Util.ipAddOne(last.endIP), sip) != 0) { br.close(); throw new Exception("discontinuous data segment: last.eip+1("+sip+") != seg.sip("+eip+", "+ps[0]+")"); } } - final Segment seg = new Segment(sip, eip, getFilteredRegion(ps[2])); + final Segment seg = new Segment(sip, eip, Util.regionFiltering(ps[2], this.fields)); segments.add(seg); last = seg; } @@ -209,16 +214,16 @@ public class Maker { } // set the vector index info of the specified ip - private void setVectorIndex(long ip, long ptr) { - final int il0 = (int) ((ip >> 24) & 0xFF); - final int il1 = (int) ((ip >> 16) & 0xFF); + private void setVectorIndex(final byte[] ip, long ptr) { + final int il0 = (int) (ip[0] & 0xFF); + final int il1 = (int) (ip[1] & 0xFF); final int idx = il0 * VectorIndexCols * VectorIndexSize + il1 * VectorIndexSize; - final long sPtr = Util.getIntLong(vectorIndex, idx); + final long sPtr = LittleEndian.getUint32(vectorIndex, idx); if (sPtr == 0) { - Util.write(vectorIndex, idx, ptr, 4); - Util.write(vectorIndex, idx + 4, ptr + SegmentIndexSize, 4); + LittleEndian.put(vectorIndex, idx, ptr, 4); + LittleEndian.put(vectorIndex, idx + 4, ptr + version.segmentIndexSize, 4); } else { - Util.write(vectorIndex, idx + 4, ptr + SegmentIndexSize, 4); + LittleEndian.put(vectorIndex, idx + 4, ptr + version.segmentIndexSize, 4); } } @@ -232,7 +237,7 @@ public class Maker { dstHandle.seek(HeaderInfoLength + VectorIndexLength); log.infof("try to write the data block ... "); - for (Segment seg : segments) { + for (final Segment seg : segments) { log.debugf("try to write region `%s` ... ", seg.region); final DataEntry e = regionPool.get(seg.region); if (e != null) { @@ -252,6 +257,11 @@ public class Maker { final long pos = dstHandle.getFilePointer(); dstHandle.write(regionBuff); + // @TODO: remove this if the long ptr operation were supported + if (pos >= MaxFilePointer) { + throw new IOException("region ptr exceed the max length of '" + MaxFilePointer + "'"); + } + // record the mapping regionPool.put(seg.region, new DataEntry(regionBuff.length, pos)); log.debugf(" --[Added] with ptr=%d", pos); @@ -261,24 +271,34 @@ public class Maker { log.infof("try to write the segment index block ... "); int counter = 0; long startIndexPtr = -1, endIndexPtr = -1; - final byte[] indexBuff = new byte[SegmentIndexSize]; // 4 + 4 + 2 + 4 + final byte[] indexBuff = new byte[version.segmentIndexSize]; for (Segment seg : segments) { // we need the region ptr - DataEntry e = regionPool.get(seg.region); + final DataEntry e = regionPool.get(seg.region); if (e == null) { throw new Exception("missing ptr cache for region `"+seg.region+"`"); } + int _offset = 0; List segList = seg.split(); log.debugf("try to index segment(%d splits) %s ... ", segList.size(), seg); - for (Segment s : segList) { + for (final Segment s : segList) { long pos = dstHandle.getFilePointer(); - // encode the segment index info - Util.write(indexBuff, 0, s.startIP, 4); - Util.write(indexBuff, 4, s.endIP, 4); - Util.write(indexBuff, 8, e.length, 2); - Util.write(indexBuff, 10, e.ptr, 4); + // @TODO: remove this if the long ptr operation were supported + if (pos >= MaxFilePointer) { + throw new IOException("region ptr exceed the max length of '" + MaxFilePointer + "'"); + } + + // encode the segment index info. + // @Note: in order to compatible with the old searcher implementation we choose to keep + // encode the IPv4 bytes with little endian. + // for IPv6 we choose the Network byte order (Big endian). + version.putBytes(indexBuff, 0, s.startIP); + version.putBytes(indexBuff, s.startIP.length, s.endIP); + _offset = s.startIP.length + s.endIP.length; + LittleEndian.put(indexBuff, _offset, e.length, 2); + LittleEndian.put(indexBuff, _offset + 2, e.ptr, 4); dstHandle.write(indexBuff); log.debugf("|-segment index: %d, ptr: %d, segment: %s", counter, pos, s); @@ -301,8 +321,8 @@ public class Maker { // 4, synchronize the segment index info log.infof("try to write the segment index ptr ... "); - Util.write(indexBuff, 0, startIndexPtr, 4); - Util.write(indexBuff, 4, endIndexPtr, 4); + LittleEndian.put(indexBuff, 0, startIndexPtr, 4); + LittleEndian.put(indexBuff, 4, endIndexPtr, 4); dstHandle.seek(8); dstHandle.write(indexBuff, 0, 8); diff --git a/maker/java/src/main/java/org/lionsoul/ip2region/xdb/Segment.java b/maker/java/src/main/java/org/lionsoul/ip2region/xdb/Segment.java index 1d809d1..9c6db14 100644 --- a/maker/java/src/main/java/org/lionsoul/ip2region/xdb/Segment.java +++ b/maker/java/src/main/java/org/lionsoul/ip2region/xdb/Segment.java @@ -11,27 +11,11 @@ import java.util.ArrayList; import java.util.List; public class Segment { - public final long startIP; - public final long endIP; + public final byte[] startIP; + public final byte[] endIP; public final String region; - // parser the Segment from an input string - public static Segment parse(String input) throws Exception { - final String[] ps = input.trim().split("\\|", 3); - if (ps.length != 3) { - throw new Exception("invalid ip segment `"+input+"`"); - } - - long sip = Util.checkIP(ps[0]); - long eip = Util.checkIP(ps[1]); - if (sip > eip) { - throw new Exception("start ip `"+ps[0]+"` should not be greater than end ip `"+ps[1]+"`"); - } - - return new Segment(sip, eip, ps[2]); - } - - public Segment(long startIP, long endIP, String region) { + public Segment(final byte[] startIP, final byte[] endIP, String region) { this.startIP = startIP; this.endIP = endIP; this.region = region; @@ -39,39 +23,61 @@ public class Segment { // split the current segment for vector index public List split() { - final long sByte1 = (int) ((startIP >> 24) & 0xFF); - final long eByte1 = (int) ((endIP >> 24) & 0xFF); - long nSip = startIP; + final int sByte1 = (int) (startIP[0] & 0xFF); + final int eByte1 = (int) (endIP[0] & 0xFF); final List tList = new ArrayList(); - for (long i = sByte1; i <= eByte1; i++) { - long sip = (i << 24) | (nSip & 0xFFFFFF); - long eip = (i << 24) | 0xFFFFFF; - if (eip < endIP) { - nSip = (i + 1) << 24; + for (int i = sByte1; i <= eByte1; i++) { + final byte[] sip = new byte[startIP.length]; + final byte[] eip = new byte[startIP.length]; + + if (i == sByte1) { + System.arraycopy(startIP, 0, sip, 0, sip.length); } else { - eip = endIP; + sip[0] = (byte) (i & 0xFF); } - // append the new segment + if (i == eByte1) { + System.arraycopy(endIP, 0, eip, 0, eip.length); + } else { + eip[0] = (byte)(i & 0xFF); + // fill the rest buffer with 0xFF + for (int j = 1; j < eip.length; j++) { + eip[j] = (byte) (0xFF); + } + } + + // append the new segment: + // @Note: Don't bother to copy the region. tList.add(new Segment(sip, eip, null)); } // 2, split the segments with the second byte final List segList = new ArrayList(); for (Segment seg : tList) { - final long base = seg.startIP & 0xFF000000; - final long sb2 = (seg.startIP >> 16) & 0xFF; - final long eb2 = (seg.endIP >> 16) & 0xFF; - long tSip = seg.startIP; - for (long i = sb2; i <= eb2; i++) { - long sip = base | (i << 16) | (tSip & 0xFFFF); - long eip = base | (i << 16) | 0xFFFF; - if (eip < seg.endIP) { - tSip = 0; + final int sByte2 = (int) (seg.startIP[1] & 0xFF); + final int eByte2 = (int) (seg.endIP[1] & 0xFF); + for (int i = sByte2; i <= eByte2; i++) { + final byte[] sip = new byte[seg.startIP.length]; + final byte[] eip = new byte[seg.startIP.length]; + sip[0] = seg.startIP[0]; + eip[0] = seg.startIP[0]; + + if (i == sByte2) { + System.arraycopy(seg.startIP, 0, sip, 0, seg.startIP.length); } else { - eip = seg.endIP; + sip[1] = (byte) (i & 0xFF); } + if (i == eByte2) { + System.arraycopy(seg.endIP, 0, eip, 0, seg.endIP.length); + } else { + eip[1] = (byte) (i & 0xFF); + for (int j = 2; j < seg.endIP.length; j++) { + eip[j] = (byte) 0xFF; + } + } + + // append the new segment segList.add(new Segment(sip, eip, region)); } } @@ -80,6 +86,23 @@ public class Segment { } @Override public String toString() { - return Util.long2ip(startIP) + "|" + Util.long2ip(endIP) + "|" + region; + return Util.ipToString(startIP) + "|" + Util.ipToString(endIP) + "|" + region; } + + // parser the Segment from an input string + public static Segment parse(String input) throws Exception { + final String[] ps = input.trim().split("\\|", 3); + if (ps.length != 3) { + throw new Exception("invalid ip segment `"+input+"`"); + } + + final byte[] sip = Util.parseIP(ps[0]); + final byte[] eip = Util.parseIP(ps[1]); + if (Util.ipCompare(sip, eip) > 0) { + throw new Exception("start ip `"+ps[0]+"` should not be greater than end ip `"+ps[1]+"`"); + } + + return new Segment(sip, eip, ps[2]); + } + } diff --git a/maker/java/src/main/java/org/lionsoul/ip2region/xdb/Util.java b/maker/java/src/main/java/org/lionsoul/ip2region/xdb/Util.java index 71a8fa4..1dc1ddf 100644 --- a/maker/java/src/main/java/org/lionsoul/ip2region/xdb/Util.java +++ b/maker/java/src/main/java/org/lionsoul/ip2region/xdb/Util.java @@ -24,15 +24,15 @@ public class Util } // convert the byte[] ip to string ip address - public static String ipToString(final byte[] ip) throws InvalidInetAddressException { + public static String ipToString(final byte[] ip) { if (ip.length != 4 && ip.length != 16) { - throw new InvalidInetAddressException("invalid ip address length `"+ip.length+"`"); + return String.format("invalid-ip-address-length: %d", ip.length); } try { return InetAddress.getByAddress(ip).getHostAddress(); } catch (UnknownHostException e) { - throw new InvalidInetAddressException("invalid ip address `"+ipArrayString(ip)+"`"); + return String.format("invalid-ip-address `%s`", ipArrayString(ip)); } } @@ -101,65 +101,29 @@ public class Util return r; } - - // write specified bytes into a byte array start from offset - public static void write( byte[] b, int offset, long v, int bytes) { - for ( int i = 0; i < bytes; i++ ) { - b[offset++] = (byte)((v >>> (8 * i)) & 0xFF); - } - } - - // write a int to a byte array - public static void writeIntLong(byte[] b, int offset, long v) { - b[offset++] = (byte)((v ) & 0xFF); - b[offset++] = (byte)((v >> 8) & 0xFF); - b[offset++] = (byte)((v >> 16) & 0xFF); - b[offset ] = (byte)((v >> 24) & 0xFF); - } - - // get an int from a byte array start from the specified offset - public static long getIntLong(byte[] b, int offset) { - return ( - ((b[offset++] & 0x000000FFL)) | - ((b[offset++] << 8) & 0x0000FF00L) | - ((b[offset++] << 16) & 0x00FF0000L) | - ((b[offset ] << 24) & 0xFF000000L) - ); - } - - public static int getInt2(byte[] b, int offset) { - return ( - ((b[offset++]) & 0x000000FF) | - ((b[offset ] << 8) & 0x0000FF00) - ); - } - - /* long int to ip string */ - public static String long2ip( long ip ) { - return String.valueOf((ip >> 24) & 0xFF) + '.' + - ((ip >> 16) & 0xFF) + '.' + ((ip >> 8) & 0xFF) + '.' + ((ip) & 0xFF); - } - - public static final byte[] shiftIndex = {24, 16, 8, 0}; - - /* check the specified ip address */ - public static long checkIP(String ip) throws Exception { - final String[] ps = ip.split("\\."); - if (ps.length != 4) { - throw new Exception("invalid ip address `" + ip + "`"); + // region filtering + public static String regionFiltering(String region, int[] fields) { + if (fields.length == 0) { + return region; } - long ipDst = 0; - for (int i = 0; i < ps.length; i++) { - int val = Integer.parseInt(ps[i]); - if (val > 255) { - throw new Exception("ip part `"+ps[i]+"` should be less then 256"); + final String[] fs = region.split("\\|", -1); + final StringBuilder sb = new StringBuilder(); + final int tailing = fields.length - 1; + for (int i = 0; i < fields.length; i++) { + final int idx = fields[i]; + if (idx >= fs.length) { + throw new IllegalArgumentException("field index `" + + idx + "` exceeded the max length `" + fs.length + "`"); } - ipDst |= ((long) val << shiftIndex[i]); + sb.append(fs[idx]); + if (sb.length() > 0 && i < tailing) { + sb.append("|"); + } } - return ipDst & 0xFFFFFFFFL; + return sb.toString(); } } diff --git a/maker/java/src/test/java/org/lionsoul/ip2region/xdb/LittleEndianTest.java b/maker/java/src/test/java/org/lionsoul/ip2region/xdb/LittleEndianTest.java index e0196d3..9b216a3 100644 --- a/maker/java/src/test/java/org/lionsoul/ip2region/xdb/LittleEndianTest.java +++ b/maker/java/src/test/java/org/lionsoul/ip2region/xdb/LittleEndianTest.java @@ -6,6 +6,8 @@ import org.junit.Test; public class LittleEndianTest { + private static final Log log = Log.getLogger(LittleEndianTest.class).setLevel(Log.DEBUG); + @Test public void testAll() { final byte[] buff = new byte[14]; @@ -25,10 +27,10 @@ public class LittleEndianTest { assertEquals(LittleEndian.getInt2(buff, 8), 24); assertEquals(LittleEndian.getUint32(buff, 10), 1024); - System.out.printf("uint32(buff, 0): %d\n", LittleEndian.getUint32(buff, 0)); - System.out.printf("uint32(buff, 4): %d\n", LittleEndian.getUint32(buff, 4)); - System.out.printf("int2(buff, 8): %d\n", LittleEndian.getInt2(buff, 8)); - System.out.printf("uint32(buff, 10): %d\n", LittleEndian.getUint32(buff, 10)); + log.debugf("uint32(buff, 0): %d", LittleEndian.getUint32(buff, 0)); + log.debugf("uint32(buff, 4): %d", LittleEndian.getUint32(buff, 4)); + log.debugf("int2(buff, 8): %d", LittleEndian.getInt2(buff, 8)); + log.debugf("uint32(buff, 10): %d", LittleEndian.getUint32(buff, 10)); } } diff --git a/maker/java/src/test/java/org/lionsoul/ip2region/xdb/SegmentTest.java b/maker/java/src/test/java/org/lionsoul/ip2region/xdb/SegmentTest.java new file mode 100644 index 0000000..2d5682e --- /dev/null +++ b/maker/java/src/test/java/org/lionsoul/ip2region/xdb/SegmentTest.java @@ -0,0 +1,39 @@ +package org.lionsoul.ip2region.xdb; + +import org.junit.Test; + +public class SegmentTest { + + private final static Log log = Log.getLogger(SegmentTest.class).setLevel(Log.DEBUG); + + @Test + public void testParse() throws Exception { + final String[] strs = { + "1.1.0.0|1.3.3.24|中国|广东|深圳|电信", + "28.201.224.0|29.34.191.255|美国|0|0|0|0", + "2001:4:112::|2001:4:112:ffff:ffff:ffff:ffff:ffff|德国|黑森|美因河畔法兰克福|专线用户" + }; + + for (final String str : strs) { + final Segment seg = Segment.parse(str); + log.debugf("seg: %s", seg.toString()); + } + } + + @Test + public void testSplit() throws Exception { + final String[] t_segs = { + "1.1.0.0|1.3.3.24|中国|广东|深圳|电信", + "28.201.224.0|29.34.191.255|美国|0|0|0|0", + "fec0::|ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff|瑞士|弗里堡州||专线用户|IANA" + }; + + for (String str : t_segs) { + final Segment seg = Segment.parse(str); + log.infof("segment(%s)->split: ", seg.toString()); + for (final Segment s : seg.split()) { + log.debugf(s.toString()); + } + } + } +} \ No newline at end of file diff --git a/maker/java/src/test/java/org/lionsoul/ip2region/xdb/UtilTest.java b/maker/java/src/test/java/org/lionsoul/ip2region/xdb/UtilTest.java index 87663cf..7038dba 100644 --- a/maker/java/src/test/java/org/lionsoul/ip2region/xdb/UtilTest.java +++ b/maker/java/src/test/java/org/lionsoul/ip2region/xdb/UtilTest.java @@ -4,7 +4,7 @@ import org.junit.Test; public class UtilTest { - public static final Log log = Log.getLogger(UtilTest.class).setLevel(Log.DEBUG); + private static final Log log = Log.getLogger(UtilTest.class).setLevel(Log.DEBUG); @Test public void testCheckIP() throws InvalidInetAddressException { @@ -75,4 +75,18 @@ public class UtilTest { log.debugf("ipSubOne(%s): %s", ip, Util.ipToString(Util.ipSubOne(ipBytes))); } } + + @Test + public void testRegionFiltering() { + final String[] regions = new String[]{ + "亚洲|中国|广东|深圳|宝安|电信|113.88311|22.55371|440306|0755|518100|Asia/Shanghai|CNY|11|CHXX0120", + "大洲|国家|省份|城市|区县|ISP|经度|纬度|0|0|0|0|0" + }; + + final int[] fields = new int[] {1,2,3,4,6,7}; + for (String region : regions) { + log.infof("filtering: %s", Util.regionFiltering(region, fields)); + } + } + } diff --git a/maker/java/src/test/java/org/lionsoul/ip2region/xdb/VersionTest.java b/maker/java/src/test/java/org/lionsoul/ip2region/xdb/VersionTest.java index c38e41b..8c38773 100644 --- a/maker/java/src/test/java/org/lionsoul/ip2region/xdb/VersionTest.java +++ b/maker/java/src/test/java/org/lionsoul/ip2region/xdb/VersionTest.java @@ -5,6 +5,9 @@ import static org.junit.Assert.assertEquals; import org.junit.Test; public class VersionTest { + + private static final Log log = Log.getLogger(VersionTest.class).setLevel(Log.DEBUG); + @Test public void testFromName() throws Exception { final String[] vers = new String[]{"IPv4", "IPv6"}; @@ -13,7 +16,7 @@ public class VersionTest { final Version v6 = Version.fromName(vers[1]); assertEquals(v6.name, vers[1]); - System.out.printf("v4: %s\n", v4); - System.out.printf("v6: %s\n", v6); + log.debugf("v4: %s", v4); + log.debugf("v6: %s", v6); } }