use the ESM standard
This commit is contained in:
parent
4507c2f706
commit
5a8d7c4152
|
|
@ -5,3 +5,6 @@
|
||||||
// ip2region.js
|
// ip2region.js
|
||||||
// @Author Lion <chenxin619315@gmail.com>
|
// @Author Lion <chenxin619315@gmail.com>
|
||||||
|
|
||||||
|
// Re-export all utilities and searcher functions
|
||||||
|
export * from './util.js';
|
||||||
|
export * from './searcher.js';
|
||||||
|
|
@ -5,7 +5,7 @@
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"main": "ip2region.js",
|
"main": "ip2region.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "jest"
|
"test": "NODE_OPTIONS='--experimental-vm-modules --no-warnings' jest"
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
|
|
|
||||||
|
|
@ -5,14 +5,14 @@
|
||||||
// searcher implementation
|
// searcher implementation
|
||||||
// @Author Lion <chenxin619315@gmail.com>
|
// @Author Lion <chenxin619315@gmail.com>
|
||||||
|
|
||||||
const fs = require('fs');
|
import fs from 'fs';
|
||||||
const {
|
import {
|
||||||
parseIP,
|
parseIP,
|
||||||
HeaderInfoLength, VectorIndexCols, VectorIndexSize,
|
HeaderInfoLength, VectorIndexCols, VectorIndexSize,
|
||||||
ipToString
|
ipToString
|
||||||
} = require('./util');
|
} from './util.js';
|
||||||
|
|
||||||
class Searcher {
|
export class Searcher {
|
||||||
constructor(version, dbPath, vectorIndex, cBuffer) {
|
constructor(version, dbPath, vectorIndex, cBuffer) {
|
||||||
this.ioCount = 0;
|
this.ioCount = 0;
|
||||||
this.version = version;
|
this.version = version;
|
||||||
|
|
@ -114,20 +114,14 @@ class Searcher {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function newWithFileOnly(version, dbPath) {
|
export function newWithFileOnly(version, dbPath) {
|
||||||
return new Searcher(version, dbPath, null, null);
|
return new Searcher(version, dbPath, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
function newWithVectorIndex(version, dbPath, vectorIndex) {
|
export function newWithVectorIndex(version, dbPath, vectorIndex) {
|
||||||
return new Searcher(version, dbPath, vectorIndex, null);
|
return new Searcher(version, dbPath, vectorIndex, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
function newWithBuffer(version, cBuffer) {
|
export function newWithBuffer(version, cBuffer) {
|
||||||
return new Searcher(version, null, null, cBuffer);
|
return new Searcher(version, null, null, cBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
newWithFileOnly,
|
|
||||||
newWithVectorIndex,
|
|
||||||
newWithBuffer
|
|
||||||
}
|
|
||||||
|
|
@ -5,9 +5,11 @@
|
||||||
// util test script
|
// util test script
|
||||||
// @Author Lion <chenxin619315@gmail.com>
|
// @Author Lion <chenxin619315@gmail.com>
|
||||||
|
|
||||||
const util = require('../util.js');
|
import * as util from '../util.js';
|
||||||
const path = require('path');
|
import path from 'node:path';
|
||||||
|
import { fileURLToPath } from 'url';
|
||||||
|
|
||||||
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
||||||
const dbPath = path.join(__dirname, '..', '..', '..', 'data', 'ip2region_v4.xdb')
|
const dbPath = path.join(__dirname, '..', '..', '..', 'data', 'ip2region_v4.xdb')
|
||||||
|
|
||||||
test('test load header', () => {
|
test('test load header', () => {
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@
|
||||||
// util test script
|
// util test script
|
||||||
// @Author Lion <chenxin619315@gmail.com>
|
// @Author Lion <chenxin619315@gmail.com>
|
||||||
|
|
||||||
const util = require('../util.js');
|
import * as util from '../util.js';
|
||||||
|
|
||||||
test('parse ip address', () => {
|
test('parse ip address', () => {
|
||||||
let ip_list = [
|
let ip_list = [
|
||||||
|
|
|
||||||
|
|
@ -5,10 +5,12 @@
|
||||||
// searcher search tester
|
// searcher search tester
|
||||||
// @Author Lion <chenxin619315@gmail.com>
|
// @Author Lion <chenxin619315@gmail.com>
|
||||||
|
|
||||||
const {IPv4, IPv6, parseIP, ipToString} = require('../util');
|
import {IPv4, IPv6, parseIP, ipToString} from '../util.js';
|
||||||
const {newWithFileOnly} = require('../searcher');
|
import {newWithFileOnly} from '../searcher.js';
|
||||||
const path = require('path');
|
import path from 'path';
|
||||||
|
import { fileURLToPath } from 'url';
|
||||||
|
|
||||||
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
||||||
const dbPath = {
|
const dbPath = {
|
||||||
v4: path.join(__dirname, '..', '..', '..', 'data', 'ip2region_v4.xdb'),
|
v4: path.join(__dirname, '..', '..', '..', 'data', 'ip2region_v4.xdb'),
|
||||||
v6: path.join(__dirname, '..', '..', '..', 'data', 'ip2region_v6.xdb')
|
v6: path.join(__dirname, '..', '..', '..', 'data', 'ip2region_v6.xdb')
|
||||||
|
|
|
||||||
|
|
@ -5,10 +5,12 @@
|
||||||
// searcher new tester
|
// searcher new tester
|
||||||
// @Author Lion <chenxin619315@gmail.com>
|
// @Author Lion <chenxin619315@gmail.com>
|
||||||
|
|
||||||
const {IPv4, IPv6, loadVectorIndexFromFile, XdbIPv4Id, loadContentFromFile} = require('../util');
|
import {IPv4, IPv6, loadVectorIndexFromFile, XdbIPv4Id, loadContentFromFile} from '../util.js';
|
||||||
const {newWithFileOnly, newWithVectorIndex, newWithBuffer} = require('../searcher');
|
import {newWithFileOnly, newWithVectorIndex, newWithBuffer} from '../searcher.js';
|
||||||
const path = require('path');
|
import path from 'path';
|
||||||
|
import { fileURLToPath } from 'url';
|
||||||
|
|
||||||
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
||||||
const dbPath = {
|
const dbPath = {
|
||||||
v4: path.join(__dirname, '..', '..', '..', 'data', 'ip2region_v4.xdb'),
|
v4: path.join(__dirname, '..', '..', '..', 'data', 'ip2region_v4.xdb'),
|
||||||
v6: path.join(__dirname, '..', '..', '..', 'data', 'ip2region_v6.xdb')
|
v6: path.join(__dirname, '..', '..', '..', 'data', 'ip2region_v6.xdb')
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@
|
||||||
// version test script
|
// version test script
|
||||||
// @Author Lion <chenxin619315@gmail.com>
|
// @Author Lion <chenxin619315@gmail.com>
|
||||||
|
|
||||||
const util = require('../util');
|
import * as util from '../util.js';
|
||||||
|
|
||||||
test('const print', () => {
|
test('const print', () => {
|
||||||
console.log("IPv4: ", util.IPv4.toString());
|
console.log("IPv4: ", util.IPv4.toString());
|
||||||
|
|
|
||||||
|
|
@ -5,19 +5,19 @@
|
||||||
// util functions
|
// util functions
|
||||||
// @Author Lion <chenxin619315@gmail.com>
|
// @Author Lion <chenxin619315@gmail.com>
|
||||||
|
|
||||||
const fs = require('fs');
|
import fs from 'fs';
|
||||||
|
|
||||||
const XdbStructure20 = 2;
|
export const XdbStructure20 = 2;
|
||||||
const XdbStructure30 = 3;
|
export const XdbStructure30 = 3;
|
||||||
const XdbIPv4Id = 4;
|
export const XdbIPv4Id = 4;
|
||||||
const XdbIPv6Id = 6;
|
export const XdbIPv6Id = 6;
|
||||||
|
|
||||||
const HeaderInfoLength = 256;
|
export const HeaderInfoLength = 256;
|
||||||
const VectorIndexRows = 256;
|
export const VectorIndexRows = 256;
|
||||||
const VectorIndexCols = 256;
|
export const VectorIndexCols = 256;
|
||||||
const VectorIndexSize = 8;
|
export const VectorIndexSize = 8;
|
||||||
|
|
||||||
class Header {
|
export class Header {
|
||||||
constructor(buff) {
|
constructor(buff) {
|
||||||
this.version = buff.readUInt16LE(0);
|
this.version = buff.readUInt16LE(0);
|
||||||
this.indexPolicy = buff.readUInt16LE(2);
|
this.indexPolicy = buff.readUInt16LE(2);
|
||||||
|
|
@ -134,7 +134,7 @@ function _parse_ipv6_addr(v6String) {
|
||||||
// parse the specified string ip and return its bytes
|
// parse the specified string ip and return its bytes
|
||||||
// @param ip string
|
// @param ip string
|
||||||
// @return Buffer
|
// @return Buffer
|
||||||
function parseIP(ipString) {
|
export function parseIP(ipString) {
|
||||||
let sDot = ipString.indexOf('.');
|
let sDot = ipString.indexOf('.');
|
||||||
let cDot = ipString.indexOf(':');
|
let cDot = ipString.indexOf(':');
|
||||||
if (sDot > -1 && cDot == -1) {
|
if (sDot > -1 && cDot == -1) {
|
||||||
|
|
@ -205,7 +205,7 @@ function _ipv6_to_string(v6Bytes, compress) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// bytes ip to humen-readable string ip
|
// bytes ip to humen-readable string ip
|
||||||
function ipToString(ipBytes, compress) {
|
export function ipToString(ipBytes, compress) {
|
||||||
if (!Buffer.isBuffer(ipBytes)) {
|
if (!Buffer.isBuffer(ipBytes)) {
|
||||||
throw new Error('invalid bytes ip, not a Buffer');
|
throw new Error('invalid bytes ip, not a Buffer');
|
||||||
}
|
}
|
||||||
|
|
@ -219,7 +219,7 @@ function ipToString(ipBytes, compress) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function ipBytesString(ipBytes) {
|
export function ipBytesString(ipBytes) {
|
||||||
if (!Buffer.isBuffer(ipBytes)) {
|
if (!Buffer.isBuffer(ipBytes)) {
|
||||||
throw new Error('invalid bytes ip, not a Buffer');
|
throw new Error('invalid bytes ip, not a Buffer');
|
||||||
}
|
}
|
||||||
|
|
@ -235,17 +235,17 @@ function ipBytesString(ipBytes) {
|
||||||
// compare two byte ips
|
// compare two byte ips
|
||||||
// ip2 = buff[offset:ip1.length]
|
// ip2 = buff[offset:ip1.length]
|
||||||
// returns: -1 if ip1 < ip2, 1 if ip1 > ip2 or 0
|
// returns: -1 if ip1 < ip2, 1 if ip1 > ip2 or 0
|
||||||
function ipSubCompare(ip1, buff, offset) {
|
export function ipSubCompare(ip1, buff, offset) {
|
||||||
return ip1.compare(buff, offset, offset + ip1.length);
|
return ip1.compare(buff, offset, offset + ip1.length);
|
||||||
}
|
}
|
||||||
|
|
||||||
function ipCompare(ip1, ip2) {
|
export function ipCompare(ip1, ip2) {
|
||||||
return ipSubCompare(ip1, ip2, 0);
|
return ipSubCompare(ip1, ip2, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---
|
// ---
|
||||||
|
|
||||||
class Version {
|
export class Version {
|
||||||
constructor(id, name, bytes, indexSize, ipCompareFunc) {
|
constructor(id, name, bytes, indexSize, ipCompareFunc) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.name = name;
|
this.name = name;
|
||||||
|
|
@ -268,7 +268,7 @@ class Version {
|
||||||
}
|
}
|
||||||
|
|
||||||
// 14 = 4 + 4 + 2 + 4
|
// 14 = 4 + 4 + 2 + 4
|
||||||
const IPv4 = new Version(XdbIPv4Id, "IPv4", 4, 14, function(ip1, buff, offset){
|
export const IPv4 = new Version(XdbIPv4Id, "IPv4", 4, 14, function(ip1, buff, offset){
|
||||||
// ip1: Big endian byte order parsed from input
|
// ip1: Big endian byte order parsed from input
|
||||||
// ip2: Little endian byte order read from xdb index.
|
// ip2: Little endian byte order read from xdb index.
|
||||||
// @Note: to compatible with the old Litten endian index encode implementation.
|
// @Note: to compatible with the old Litten endian index encode implementation.
|
||||||
|
|
@ -289,9 +289,9 @@ const IPv4 = new Version(XdbIPv4Id, "IPv4", 4, 14, function(ip1, buff, offset){
|
||||||
});
|
});
|
||||||
|
|
||||||
// 38 = 16 + 16 + 2 + 4
|
// 38 = 16 + 16 + 2 + 4
|
||||||
const IPv6 = new Version(XdbIPv6Id, "IPv6", 16, 38, ipSubCompare);
|
export const IPv6 = new Version(XdbIPv6Id, "IPv6", 16, 38, ipSubCompare);
|
||||||
|
|
||||||
function versionFromName(name) {
|
export function versionFromName(name) {
|
||||||
let n = name.toUpperCase();
|
let n = name.toUpperCase();
|
||||||
if (n == "V4" || n == "IPV4") {
|
if (n == "V4" || n == "IPV4") {
|
||||||
return IPv4;
|
return IPv4;
|
||||||
|
|
@ -302,7 +302,7 @@ function versionFromName(name) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function versionFromHeader(h) {
|
export function versionFromHeader(h) {
|
||||||
let v = h.version();
|
let v = h.version();
|
||||||
|
|
||||||
// old structure with ONLY IPv4 supporting
|
// old structure with ONLY IPv4 supporting
|
||||||
|
|
@ -327,7 +327,7 @@ function versionFromHeader(h) {
|
||||||
|
|
||||||
// ---
|
// ---
|
||||||
|
|
||||||
function loadHeader(fd) {
|
export function loadHeader(fd) {
|
||||||
const buffer = Buffer.alloc(HeaderInfoLength);
|
const buffer = Buffer.alloc(HeaderInfoLength);
|
||||||
const rBytes = fs.readSync(fd, buffer, 0, HeaderInfoLength, 0);
|
const rBytes = fs.readSync(fd, buffer, 0, HeaderInfoLength, 0);
|
||||||
if (rBytes != HeaderInfoLength) {
|
if (rBytes != HeaderInfoLength) {
|
||||||
|
|
@ -336,14 +336,14 @@ function loadHeader(fd) {
|
||||||
return new Header(buffer);
|
return new Header(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
function loadHeaderFromFile(dbPath) {
|
export function loadHeaderFromFile(dbPath) {
|
||||||
const fd = fs.openSync(dbPath, "r");
|
const fd = fs.openSync(dbPath, "r");
|
||||||
const header = loadHeader(fd);
|
const header = loadHeader(fd);
|
||||||
fs.closeSync(fd);
|
fs.closeSync(fd);
|
||||||
return header;
|
return header;
|
||||||
}
|
}
|
||||||
|
|
||||||
function loadVectorIndex(fd) {
|
export function loadVectorIndex(fd) {
|
||||||
const vBytes = VectorIndexCols * VectorIndexRows * VectorIndexSize;
|
const vBytes = VectorIndexCols * VectorIndexRows * VectorIndexSize;
|
||||||
const buffer = Buffer.alloc(vBytes);
|
const buffer = Buffer.alloc(vBytes);
|
||||||
const rBytes = fs.readSync(fd, buffer, 0, vBytes, HeaderInfoLength);
|
const rBytes = fs.readSync(fd, buffer, 0, vBytes, HeaderInfoLength);
|
||||||
|
|
@ -353,14 +353,14 @@ function loadVectorIndex(fd) {
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
function loadVectorIndexFromFile(dbPath) {
|
export function loadVectorIndexFromFile(dbPath) {
|
||||||
const fd = fs.openSync(dbPath, "r");
|
const fd = fs.openSync(dbPath, "r");
|
||||||
const vIndex = loadVectorIndex(fd);
|
const vIndex = loadVectorIndex(fd);
|
||||||
fs.closeSync(fd);
|
fs.closeSync(fd);
|
||||||
return vIndex;
|
return vIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
function loadContent(fd) {
|
export function loadContent(fd) {
|
||||||
const stats = fs.fstatSync(fd);
|
const stats = fs.fstatSync(fd);
|
||||||
const buffer = Buffer.alloc(stats.size);
|
const buffer = Buffer.alloc(stats.size);
|
||||||
const rBytes = fs.readSync(fd, buffer, 0, buffer.length, 0);
|
const rBytes = fs.readSync(fd, buffer, 0, buffer.length, 0);
|
||||||
|
|
@ -370,27 +370,9 @@ function loadContent(fd) {
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
function loadContentFromFile(dbPath) {
|
export function loadContentFromFile(dbPath) {
|
||||||
const fd = fs.openSync(dbPath, "r");
|
const fd = fs.openSync(dbPath, "r");
|
||||||
const content = loadContent(fd);
|
const content = loadContent(fd);
|
||||||
fs.close(fd, function(){});
|
fs.close(fd, function(){});
|
||||||
return content;
|
return content;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
// header
|
|
||||||
XdbStructure20, XdbStructure30, XdbIPv4Id, XdbIPv6Id,
|
|
||||||
HeaderInfoLength, VectorIndexRows, VectorIndexCols, VectorIndexSize,
|
|
||||||
|
|
||||||
// version
|
|
||||||
IPv4, IPv6,
|
|
||||||
versionFromName, versionFromHeader,
|
|
||||||
|
|
||||||
// utils
|
|
||||||
parseIP, ipToString, ipBytesString,
|
|
||||||
ipSubCompare, ipCompare,
|
|
||||||
loadHeader, loadHeaderFromFile,
|
|
||||||
loadVectorIndex, loadVectorIndexFromFile,
|
|
||||||
loadContent, loadContentFromFile
|
|
||||||
}
|
|
||||||
Loading…
Reference in New Issue