mirror of
https://github.com/lionsoul2014/ip2region.git
synced 2025-12-08 19:25:22 +00:00
159 lines
3.2 KiB
C++
159 lines
3.2 KiB
C++
|
|
#include "ip.h"
|
|
|
|
namespace xdb {
|
|
|
|
ip_t::ip_t() {
|
|
memset(p, '\0', sizeof(p));
|
|
}
|
|
|
|
ip_t::ip_t(const ip_t& rhs, int val) {
|
|
memcpy(p, rhs.p, ip_size);
|
|
|
|
if (val == 0 || val == 255)
|
|
for (int i = 2; i < ip_size; ++i)
|
|
p[i] = val;
|
|
}
|
|
|
|
ip_t::ip_t(const char* p) {
|
|
from_xdb(p);
|
|
}
|
|
|
|
bool ip_t::from_str(const string& str) {
|
|
int af_inet = ip_version == ipv4 ? AF_INET : AF_INET6;
|
|
return inet_pton(af_inet, str.data(), p) == 1;
|
|
}
|
|
|
|
void ip_t::from_xdb(const char str[16]) {
|
|
for (int i = 0; i < ip_size; ++i)
|
|
if (ip_version == ipv6)
|
|
p[i] = str[i];
|
|
else
|
|
p[i] = str[ip_size - 1 - i];
|
|
}
|
|
|
|
ip_t& ip_t::operator=(const ip_t& rhs) {
|
|
memcpy(p, rhs.p, ip_size);
|
|
return *this;
|
|
}
|
|
|
|
int ip_t::compare(const ip_t& rhs) const {
|
|
for (int i = 0; i < ip_size; ++i) {
|
|
if ((unsigned char)p[i] > (unsigned char)rhs.p[i])
|
|
return 1;
|
|
if ((unsigned char)p[i] < (unsigned char)rhs.p[i])
|
|
return -1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
bool ip_t::operator<(const ip_t& rhs) const {
|
|
return compare(rhs) < 0;
|
|
}
|
|
|
|
bool ip_t::operator<=(const ip_t& rhs) const {
|
|
return compare(rhs) <= 0;
|
|
}
|
|
|
|
bool ip_t::operator>(const ip_t& rhs) const {
|
|
return compare(rhs) > 0;
|
|
}
|
|
|
|
bool ip_t::operator>=(const ip_t& rhs) const {
|
|
return compare(rhs) >= 0;
|
|
}
|
|
|
|
bool ip_t::operator==(const ip_t& rhs) const {
|
|
return compare(rhs) == 0;
|
|
}
|
|
|
|
bool ip_t::operator!=(const ip_t& rhs) const {
|
|
return compare(rhs) != 0;
|
|
}
|
|
|
|
string ip_t::to_string() const {
|
|
char buf[INET6_ADDRSTRLEN + 1];
|
|
int af_inet = ip_version == ipv4 ? AF_INET : AF_INET6;
|
|
inet_ntop(af_inet, p, buf, sizeof(buf));
|
|
return string(buf);
|
|
}
|
|
|
|
string ip_t::to_bit() const {
|
|
string str;
|
|
for (int i = 0; i < ip_size; ++i)
|
|
if (ip_version == ipv6)
|
|
str.push_back(p[i]);
|
|
else
|
|
str.push_back(p[ip_size - 1 - i]);
|
|
return str;
|
|
}
|
|
|
|
ip_t operator+(const ip_t& lhs, int v) {
|
|
ip_t ip;
|
|
|
|
int i = ip_size;
|
|
while (--i >= 0) {
|
|
v += lhs.p[i];
|
|
ip.p[i] = v % 256;
|
|
v /= 256;
|
|
}
|
|
return ip;
|
|
}
|
|
|
|
ip_t operator-(const ip_t& lhs, int v) {
|
|
ip_t ip;
|
|
|
|
int i = ip_size;
|
|
v = -v;
|
|
while (--i >= 0) {
|
|
v += lhs.p[i];
|
|
if (v == -1)
|
|
ip.p[i] = 255;
|
|
else {
|
|
ip.p[i] = v;
|
|
v = 0;
|
|
}
|
|
}
|
|
return ip;
|
|
}
|
|
|
|
// node_t
|
|
node_t::node_t() {
|
|
}
|
|
|
|
node_t::node_t(char* buf) {
|
|
char* pos1 = strchr(buf, '|');
|
|
|
|
if (pos1 == NULL)
|
|
log_exit("invalid data: " + std::string(buf));
|
|
char* pos2 = strchr(pos1 + 1, '|');
|
|
if (pos2 == NULL)
|
|
log_exit("invalid data: " + std::string(buf));
|
|
*pos1 = '\0';
|
|
*pos2 = '\0';
|
|
|
|
region = pos2 + 1;
|
|
|
|
if (!ip1.from_str(buf) || !ip2.from_str(pos1 + 1) || ip2 < ip1 ||
|
|
region.empty()) {
|
|
*pos1 = *pos2 = '|';
|
|
log_exit(string("invalid data: ") + buf);
|
|
}
|
|
}
|
|
|
|
bool node_t::operator<(const node_t& rhs) const {
|
|
if (ip1 < rhs.ip1)
|
|
return true;
|
|
return ip2 < rhs.ip2;
|
|
}
|
|
|
|
string node_t::to_string() const {
|
|
return ip1.to_string() + "|" + ip2.to_string() + "|" + region;
|
|
}
|
|
|
|
string node_t::to_bit() const {
|
|
return ip1.to_bit() + ip2.to_bit();
|
|
}
|
|
|
|
} // namespace xdb
|