header/vector/content load util funcs is ready

This commit is contained in:
lion 2025-10-11 13:28:20 +08:00
parent d6345bc015
commit ccf7f323c2
6 changed files with 90 additions and 22 deletions

View File

@ -5,8 +5,15 @@
// xdb header class // xdb header class
// @Author Lion <chenxin619315@gmail.com> // @Author Lion <chenxin619315@gmail.com>
const xdb_structure_20 = 2; const XdbStructure20 = 2;
const xdb_structure_30 = 3; const XdbStructure30 = 3;
const xdbIPv4Id = 4;
const xdbIPv6Id = 6;
const HeaderInfoLength = 256;
const VectorIndexRows = 256;
const VectorIndexCols = 256;
const VectorIndexSize = 8;
class Header { class Header {
constructor(buff) { constructor(buff) {
@ -69,6 +76,7 @@ class Header {
} }
module.exports = { module.exports = {
xdb_structure_20, xdb_structure_30, XdbStructure20, XdbStructure30, xdbIPv4Id, xdbIPv6Id,
HeaderInfoLength, VectorIndexRows, VectorIndexCols, VectorIndexSize,
Header Header
} }

View File

@ -2,7 +2,6 @@
"name": "ip2region", "name": "ip2region",
"version": "3.0.0", "version": "3.0.0",
"description": "javascript (ES6) binding for ip2region with both IPv4 and IPv6 supported ", "description": "javascript (ES6) binding for ip2region with both IPv4 and IPv6 supported ",
"type": "module",
"main": "index.js", "main": "index.js",
"scripts": { "scripts": {
"test": "jest" "test": "jest"

View File

@ -0,0 +1,26 @@
// 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.
// util test script
// @Author Lion <chenxin619315@gmail.com>
const util = require('../util');
const path = require('path');
const dbPath = path.join(__dirname, '..', '..', '..', 'data', 'ip2region_v4.xdb')
test('test load header', () => {
let header = util.loadHeaderFromFile(dbPath);
console.log(`dbPath: ${dbPath}, header: ${header.toString()}}`);
});
test('test load vector index', () => {
let vIndex = util.loadVectorIndexFromFile(dbPath);
console.log(`dbPath: ${dbPath}, vIndex: ${vIndex.length}}`);
});
test('test load content', () => {
let content = util.loadContentFromFile(dbPath);
console.log(`dbPath: ${dbPath}, content: ${content.length}}`);
});

View File

@ -2,6 +2,9 @@
// Use of this source code is governed by a Apache2.0-style // Use of this source code is governed by a Apache2.0-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// version test script
// @Author Lion <chenxin619315@gmail.com>
const version = require('../version'); const version = require('../version');
test('const print', () => { test('const print', () => {

View File

@ -5,6 +5,9 @@
// util functions // util functions
// @Author Lion <chenxin619315@gmail.com> // @Author Lion <chenxin619315@gmail.com>
const header = require('./header');
const fs = require('fs');
// 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
@ -24,26 +27,59 @@ function ipCompare(ip1, ip2) {
} }
// load header from xdb file // load header from xdb file
function loadHeader(handle) { function loadHeader(fd) {
const buffer = Buffer.alloc(header.HeaderInfoLength);
const rBytes = fs.readSync(fd, buffer, 0, header.HeaderInfoLength, 0);
if (rBytes != header.HeaderInfoLength) {
throw new Error(`incomplete read (${rBytes} read, ${header.HeaderInfoLength} expected)`);
}
return new header.Header(buffer);
} }
function loadHeaderFromFile(dbPath) { function loadHeaderFromFile(dbPath) {
const fd = fs.openSync(dbPath, "r");
const header = loadHeader(fd);
fs.closeSync(fd);
return header;
} }
function loadVectorIndex(handle) { function loadVectorIndex(fd) {
const vBytes = header.VectorIndexCols * header.VectorIndexRows * header.VectorIndexSize;
const buffer = Buffer.alloc(vBytes);
const rBytes = fs.readSync(fd, buffer, 0, vBytes, header.HeaderInfoLength);
if (rBytes != vBytes) {
throw new Error(`incomplete read (${rBytes} read, ${vBytes} expected)`);
}
return buffer;
} }
function loadVectorIndexFromFile(dbPath) { function loadVectorIndexFromFile(dbPath) {
const fd = fs.openSync(dbPath, "r");
const vIndex = loadVectorIndex(fd);
fs.closeSync(fd);
return vIndex;
} }
function loadContent(handle) { function loadContent(fd) {
const stats = fs.fstatSync(fd);
const buffer = Buffer.alloc(stats.size);
const rBytes = fs.readSync(fd, buffer, 0, buffer.length, 0);
if (rBytes != stats.size) {
throw new Error(`incomplete read (${rBytes} read, ${stats.size} expected)`);
}
return buffer;
} }
function loadContentFromFile(dbPath) { function loadContentFromFile(dbPath) {
const fd = fs.openSync(dbPath, "r");
const content = loadContent(fd);
fs.close(fd, function(){});
return content;
}
module.exports = {
parseIP, ipToString, ipCompare,
loadHeader, loadHeaderFromFile,
loadVectorIndex, loadVectorIndexFromFile,
loadContent, loadContentFromFile
} }

View File

@ -7,9 +7,6 @@
const header = require('./header'); const header = require('./header');
const xdb_ipv4_id = 4;
const xdb_ipv6_id = 6;
class Version { class Version {
constructor(id, name, bytes, indexSize, ip_compare_func) { constructor(id, name, bytes, indexSize, ip_compare_func) {
this.id = id; this.id = id;
@ -49,11 +46,11 @@ class Version {
} }
// 14 = 4 + 4 + 2 + 4 // 14 = 4 + 4 + 2 + 4
const IPv4 = new Version(xdb_ipv4_id, "IPv4", 4, 14, function(ip1, ip2){ const IPv4 = new Version(header.xdbIPv4Id, "IPv4", 4, 14, function(ip1, ip2){
}); });
// 38 = 16 + 16 + 2 + 4 // 38 = 16 + 16 + 2 + 4
const IPv6 = new Version(xdb_ipv6_id, "IPv6", 6, 38, function(ip1, ip2){ const IPv6 = new Version(header.xdbIPv6Id, "IPv6", 6, 38, function(ip1, ip2){
}); });
function versionFromName(name) { function versionFromName(name) {
@ -71,19 +68,19 @@ function versionFromHeader(h) {
let v = h.version(); let v = h.version();
// old structure with ONLY IPv4 supporting // old structure with ONLY IPv4 supporting
if (v == header.xdb_structure_20) { if (v == header.XdbStructure20) {
return IPv4; return IPv4;
} }
// structure 3.0 with IPv6 supporting // structure 3.0 with IPv6 supporting
if (v != header.xdb_structure_30) { if (v != header.XdbStructure30) {
return null; return null;
} }
let ipVer = h.ipVersion(); let ipVer = h.ipVersion();
if (ipVer == xdb_ipv4_id) { if (ipVer == header.xdbIPv4Id) {
return IPv4; return IPv4;
} else if (ipVer == xdb_ipv6_id) { } else if (ipVer == header.xdbIPv6Id) {
return IPv6; return IPv6;
} else { } else {
return null; return null;
@ -91,7 +88,6 @@ function versionFromHeader(h) {
} }
module.exports = { module.exports = {
xdb_ipv4_id, xdb_ipv6_id,
Version, IPv4, IPv6, Version, IPv4, IPv6,
versionFromName, versionFromHeader versionFromName, versionFromHeader
} }