1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
//! A high-performance, zero-copy parser and query engine for xdb IP geolocation
//! database files (ip2region-compatible format).
//!
//! Supports both IPv4 and IPv6 lookup via an optimized two-level binary search.
//!
//! # Quick start
//!
//! ```no_run
//! use xdb_parse::{load_file, search_ip};
//!
//! let data = load_file("./assets/ip2region_v4.xdb".into())?;
//! let location = search_ip("73.24.63.66", &data)?;
//! println!("{}", location);
//! # Ok::<(), xdb_parse::error::XdbError>(())
//! ```
//!
//! # Flexible input
//!
//! [`search_ip`] accepts any type that implements [`IntoIpAddr`]:
//!
//! ```no_run
//! use xdb_parse::{load_file, search_ip};
//!
//! let data = load_file("./assets/ip2region_v4.xdb".into())?;
//!
//! // &str or String
//! search_ip("73.24.63.66", &data)?;
//!
//! // raw u32 (fastest IPv4 path)
//! search_ip(0x4918_3F42u32, &data)?;
//!
//! // IpAddr from socket
//! search_ip("::1".parse::<std::net::IpAddr>()?, &data)?;
//! # Ok::<(), xdb_parse::error::XdbError>(())
//! ```
//!
//! # Performance
//!
//! All search functions return `&str` borrowing from the loaded buffer —
//! zero allocation per query. For the fastest path, use
//! [`search_by_uint`] / [`search_by_u128`] to skip trait dispatch.
//!
//! # Thread safety
//!
//! The loaded `Vec<u8>` is `Send + Sync`. Wrap it in `Arc` to share across threads:
//!
//! ```no_run
//! use std::sync::Arc;
//! use xdb_parse::{load_file, search_ip};
//!
//! let data = Arc::new(load_file("./assets/ip2region_v6.xdb".into())?);
//! let handle = std::thread::spawn({
//! let data = Arc::clone(&data);
//! move || search_ip("::1", &data).unwrap()
//! });
//! # Ok::<(), xdb_parse::error::XdbError>(())
//! ```
use File;
use Read;
use PathBuf;
use crateXdbError;
pub const TOTAL_HEADER_SIZE: usize = 256;
pub const VECTOR_COL_SIZE: usize = 256;
pub const VECTOR_ROW_SIZE: usize = 256;
pub const VECTOR_INDEX_BLOCK_SIZE: usize = 8;
pub const TOTAL_VECTOR_INDEX_SIZE: usize =
VECTOR_COL_SIZE * VECTOR_ROW_SIZE * VECTOR_INDEX_BLOCK_SIZE;
pub const IPV4_SEGMENT_INDEX_BLOCK_SIZE: u32 = 14;
pub const IPV6_SEGMENT_INDEX_BLOCK_SIZE: u32 = 38;
pub use IntoIpAddr;
pub use ;
pub use ;
/// Load an xdb database file into memory.
///
/// Pre-allocates the buffer with the exact file size to avoid reallocation
/// during reading.
///
/// # Example
///
/// ```no_run
/// let data = xdb_parse::load_file("./assets/ip2region_v4.xdb".into())?;
/// # Ok::<(), xdb_parse::error::XdbError>(())
/// ```