From 6c463282d0c43024c51f09a4f9b37f982e171425 Mon Sep 17 00:00:00 2001 From: lion Date: Sat, 11 Oct 2025 23:57:55 +0800 Subject: [PATCH] merge the header/version to util.js --- binding/javascript/header.js | 82 ---------- binding/javascript/tests/version.test.js | 8 +- binding/javascript/util.js | 183 +++++++++++++++++++++-- binding/javascript/version.js | 93 ------------ 4 files changed, 178 insertions(+), 188 deletions(-) delete mode 100644 binding/javascript/header.js delete mode 100644 binding/javascript/version.js diff --git a/binding/javascript/header.js b/binding/javascript/header.js deleted file mode 100644 index 4e49713..0000000 --- a/binding/javascript/header.js +++ /dev/null @@ -1,82 +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. - -// xdb header class -// @Author Lion - -const XdbStructure20 = 2; -const XdbStructure30 = 3; -const xdbIPv4Id = 4; -const xdbIPv6Id = 6; - -const HeaderInfoLength = 256; -const VectorIndexRows = 256; -const VectorIndexCols = 256; -const VectorIndexSize = 8; - -class Header { - constructor(buff) { - this.version = buff.readUInt16LE(0); - this.indexPolicy = buff.readUInt16LE(2); - this.createdAt = buff.readUInt32LE(4); - this.startIndexPtr = buff.readUInt32LE(8); - this.endIndexPtr = buff.readUInt32LE(12); - - // since IPv6 supporting - this.ipVersion = buff.readUInt16LE(16); - this.runtimePtrBytes = buff.readUInt16LE(18); - - // keep the raw data - this.buff = buff; - } - - version() { - return this.version; - } - - indexPolicy() { - return this.indexPolicy; - } - - createdAt() { - return this.createdAt; - } - - startIndexPtr() { - return this.startIndexPtr; - } - - endIndexPtr() { - return this.endIndexPtr; - } - - ipVersion() { - return this.ipVersion; - } - - runtimePtrBytes() { - return this.runtimePtrBytes; - } - - buff() { - return this.buff; - } - - toString() { - return `{ - "version":${this.version}, - "index_policy":${this.indexPolicy}, - "start_index_ptr": ${this.startIndexPtr}, - "end_index_ptr": ${this.endIndexPtr}, - "ipVersion": ${this.ipVersion}, - "runtime_ptr_bytes": ${this.runtimePtrBytes} - }`; - } -} - -module.exports = { - XdbStructure20, XdbStructure30, xdbIPv4Id, xdbIPv6Id, - HeaderInfoLength, VectorIndexRows, VectorIndexCols, VectorIndexSize, - Header -} \ No newline at end of file diff --git a/binding/javascript/tests/version.test.js b/binding/javascript/tests/version.test.js index a8869ad..5f75544 100644 --- a/binding/javascript/tests/version.test.js +++ b/binding/javascript/tests/version.test.js @@ -5,17 +5,17 @@ // version test script // @Author Lion -const version = require('../version'); +const util = require('../util'); test('const print', () => { - console.log("IPv4: ", version.IPv4.toString()); - console.log("IPv6: ", version.IPv6.toString()); + console.log("IPv4: ", util.IPv4.toString()); + console.log("IPv6: ", util.IPv6.toString()); }); test("test version from name", () => { let vs = ["v4", "ipv4", "v4x", "v6", "ipv6", "v6x"]; vs.forEach(ele => { - let v = version.versionFromName(ele); + let v = util.versionFromName(ele); console.log(`versionFrom(${ele})`, v == null ? null : v.toString()); }); }); \ No newline at end of file diff --git a/binding/javascript/util.js b/binding/javascript/util.js index d8e6b44..f33fefb 100644 --- a/binding/javascript/util.js +++ b/binding/javascript/util.js @@ -5,10 +5,165 @@ // util functions // @Author Lion -const header = require('./header'); const fs = require('fs'); -// -- +// --- header +const XdbStructure20 = 2; +const XdbStructure30 = 3; +const XdbIPv4Id = 4; +const XdbIPv6Id = 6; + +const HeaderInfoLength = 256; +const VectorIndexRows = 256; +const VectorIndexCols = 256; +const VectorIndexSize = 8; + +class Header { + constructor(buff) { + this.version = buff.readUInt16LE(0); + this.indexPolicy = buff.readUInt16LE(2); + this.createdAt = buff.readUInt32LE(4); + this.startIndexPtr = buff.readUInt32LE(8); + this.endIndexPtr = buff.readUInt32LE(12); + + // since IPv6 supporting + this.ipVersion = buff.readUInt16LE(16); + this.runtimePtrBytes = buff.readUInt16LE(18); + + // keep the raw data + this.buff = buff; + } + + version() { + return this.version; + } + + indexPolicy() { + return this.indexPolicy; + } + + createdAt() { + return this.createdAt; + } + + startIndexPtr() { + return this.startIndexPtr; + } + + endIndexPtr() { + return this.endIndexPtr; + } + + ipVersion() { + return this.ipVersion; + } + + runtimePtrBytes() { + return this.runtimePtrBytes; + } + + buff() { + return this.buff; + } + + toString() { + return `{ + "version":${this.version}, + "index_policy":${this.indexPolicy}, + "start_index_ptr": ${this.startIndexPtr}, + "end_index_ptr": ${this.endIndexPtr}, + "ipVersion": ${this.ipVersion}, + "runtime_ptr_bytes": ${this.runtimePtrBytes} + }`; + } +} + +// --- + +// --- +// version +class Version { + constructor(id, name, bytes, indexSize, ip_compare_func) { + this.id = id; + this.name = name; + this.bytes = bytes; + this.indexSize = indexSize; + this.ip_compare_func = ip_compare_func; + } + + id() { + return this.id; + } + + name() { + return this.name; + } + + bytes() { + return this.bytes; + } + + indexSize() { + return this.indexSize; + } + + compareFunc() { + return this.ip_compare_func; + } + + ipCompare(ip1, ip2) { + return this.ip_compare_func(ip1, ip2); + } + + toString() { + return `{"id": ${this.id}, "name": "${this.name}", "bytes":${this.bytes}, "index_size": ${this.indexSize}}`; + } +} + +// 14 = 4 + 4 + 2 + 4 +const IPv4 = new Version(XdbIPv4Id, "IPv4", 4, 14, function(ip1, ip2){ +}); + +// 38 = 16 + 16 + 2 + 4 +const IPv6 = new Version(XdbIPv6Id, "IPv6", 6, 38, function(ip1, ip2){ +}); + +function versionFromName(name) { + let n = name.toUpperCase(); + if (n == "V4" || n == "IPV4") { + return IPv4; + } else if (n == "V6" || n == "IPV6") { + return IPv6; + } else { + return null; + } +} + +function versionFromHeader(h) { + let v = h.version(); + + // old structure with ONLY IPv4 supporting + if (v == XdbStructure20) { + return IPv4; + } + + // structure 3.0 with IPv6 supporting + if (v != XdbStructure30) { + return null; + } + + let ipVer = h.ipVersion(); + if (ipVer == XdbIPv4Id) { + return IPv4; + } else if (ipVer == XdbIPv6Id) { + return IPv6; + } else { + return null; + } +} +// --- + +// --- // parse the specified string ip and return its bytes // parse ipv4 address @@ -113,7 +268,6 @@ function parseIP(ipString) { // --- - // --- // bytes ip to humen-readable string ip @@ -212,12 +366,12 @@ function ipCompare(ip1, ip2) { // load header from xdb file function loadHeader(fd) { - const buffer = Buffer.alloc(header.HeaderInfoLength); - const rBytes = fs.readSync(fd, buffer, 0, header.HeaderInfoLength, 0); - if (rBytes != header.HeaderInfoLength) { + const buffer = Buffer.alloc(HeaderInfoLength); + const rBytes = fs.readSync(fd, buffer, 0, HeaderInfoLength, 0); + if (rBytes != HeaderInfoLength) { throw new Error(`incomplete read (${rBytes} read, ${header.HeaderInfoLength} expected)`); } - return new header.Header(buffer); + return new Header(buffer); } function loadHeaderFromFile(dbPath) { @@ -228,9 +382,9 @@ function loadHeaderFromFile(dbPath) { } function loadVectorIndex(fd) { - const vBytes = header.VectorIndexCols * header.VectorIndexRows * header.VectorIndexSize; + const vBytes = VectorIndexCols * VectorIndexRows * VectorIndexSize; const buffer = Buffer.alloc(vBytes); - const rBytes = fs.readSync(fd, buffer, 0, vBytes, header.HeaderInfoLength); + const rBytes = fs.readSync(fd, buffer, 0, vBytes, HeaderInfoLength); if (rBytes != vBytes) { throw new Error(`incomplete read (${rBytes} read, ${vBytes} expected)`); } @@ -261,7 +415,18 @@ function loadContentFromFile(dbPath) { return content; } + module.exports = { + // header + XdbStructure20, XdbStructure30, XdbIPv4Id, XdbIPv6Id, + HeaderInfoLength, VectorIndexRows, VectorIndexCols, VectorIndexSize, + Header, + + // version + Version, IPv4, IPv6, + versionFromName, versionFromHeader, + + // utils parseIP, ipToString, ipBytesString, ipCompare, loadHeader, loadHeaderFromFile, loadVectorIndex, loadVectorIndexFromFile, diff --git a/binding/javascript/version.js b/binding/javascript/version.js deleted file mode 100644 index 5b70561..0000000 --- a/binding/javascript/version.js +++ /dev/null @@ -1,93 +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. - -// version module -// @Author Lion - -const header = require('./header'); - -class Version { - constructor(id, name, bytes, indexSize, ip_compare_func) { - this.id = id; - this.name = name; - this.bytes = bytes; - this.indexSize = indexSize; - this.ip_compare_func = ip_compare_func; - } - - id() { - return this.id; - } - - name() { - return this.name; - } - - bytes() { - return this.bytes; - } - - indexSize() { - return this.indexSize; - } - - compareFunc() { - return this.ip_compare_func; - } - - ipCompare(ip1, ip2) { - return this.ip_compare_func(ip1, ip2); - } - - toString() { - return `{"id": ${this.id}, "name": "${this.name}", "bytes":${this.bytes}, "index_size": ${this.indexSize}}`; - } -} - -// 14 = 4 + 4 + 2 + 4 -const IPv4 = new Version(header.xdbIPv4Id, "IPv4", 4, 14, function(ip1, ip2){ -}); - -// 38 = 16 + 16 + 2 + 4 -const IPv6 = new Version(header.xdbIPv6Id, "IPv6", 6, 38, function(ip1, ip2){ -}); - -function versionFromName(name) { - let n = name.toUpperCase(); - if (n == "V4" || n == "IPV4") { - return IPv4; - } else if (n == "V6" || n == "IPV6") { - return IPv6; - } else { - return null; - } -} - -function versionFromHeader(h) { - let v = h.version(); - - // old structure with ONLY IPv4 supporting - if (v == header.XdbStructure20) { - return IPv4; - } - - // structure 3.0 with IPv6 supporting - if (v != header.XdbStructure30) { - return null; - } - - let ipVer = h.ipVersion(); - if (ipVer == header.xdbIPv4Id) { - return IPv4; - } else if (ipVer == header.xdbIPv6Id) { - return IPv6; - } else { - return null; - } -} - -module.exports = { - Version, IPv4, IPv6, - versionFromName, versionFromHeader -} \ No newline at end of file