From eb80b89c0ec61d6b8cf0811344a7b49302cd0125 Mon Sep 17 00:00:00 2001 From: lion Date: Tue, 16 Sep 2025 14:46:34 +0800 Subject: [PATCH] ipv6 supporting for clang --- binding/c/Makefile | 25 ++- binding/c/ReadMe.md | 6 +- binding/c/main.c | 6 +- binding/c/test_util | Bin 0 -> 17360 bytes binding/c/{util_test.c => test_util.c} | 16 +- binding/c/{xdb_searcher.h => xdb_api.h} | 12 +- binding/c/xdb_searcher.c | 261 +---------------------- binding/c/xdb_util.c | 264 ++++++++++++++++++++++++ 8 files changed, 299 insertions(+), 291 deletions(-) create mode 100755 binding/c/test_util rename binding/c/{util_test.c => test_util.c} (93%) rename binding/c/{xdb_searcher.h => xdb_api.h} (95%) create mode 100644 binding/c/xdb_util.c diff --git a/binding/c/Makefile b/binding/c/Makefile index 3031f3b..f4724ba 100644 --- a/binding/c/Makefile +++ b/binding/c/Makefile @@ -1,24 +1,27 @@ -all: xdb_searcher util_test +all: xdb_searcher test_util -xdb_searcher: xdb_searcher.h xdb_searcher.c main.c - gcc -O2 -I./ xdb_searcher.c main.c -o xdb_searcher +xdb_searcher: xdb_api.h xdb_util.c xdb_searcher.c main.c + gcc -O2 -I./ xdb_util.c xdb_searcher.c main.c -o xdb_searcher -util_test: xdb_searcher.h xdb_searcher.c util_test.c - gcc -O2 -I./ xdb_searcher.c util_test.c -o util_test +test_util: xdb_api.h xdb_util.c test_util.c + gcc -O2 -I./ xdb_util.c test_util.c -o test_util xdb_searcher.o: xdb_searcher.c - gcc -c -o xdb_searcher.o xdb_searcher.c + gcc -c xdb_searcher.c -xdb_searcher_lib: xdb_searcher.o +xdb_util.o: xdb_util.c + gcc -c xdb_util.c + +xdb_searcher_lib: xdb_util.o xdb_searcher.o mkdir -p build/lib mkdir -p build/include - ar -rc build/lib/libxdb_searcher.a `find . -name *.o` - cp xdb_searcher.h build/include + ar -rc build/lib/libxdb.a `find . -name *.o` + cp xdb_api.h build/include clean: find ./ -name \*.o | xargs rm -f - find ./ -name util_test | xargs rm -f + find ./ -name test_util | xargs rm -f find ./ -name xdb_searcher | xargs rm -f rm -rf build -.PHONY: all clean xdb_searcher util_test +.PHONY: all clean xdb_searcher test_util diff --git a/binding/c/ReadMe.md b/binding/c/ReadMe.md index 591f905..b684f5a 100644 --- a/binding/c/ReadMe.md +++ b/binding/c/ReadMe.md @@ -7,7 +7,7 @@ ```c #include -#include "xdb_searcher.h" +#include "xdb_api.h" int main(int argc, char *argv[]) { char *db_path = "ip2region.xdb file path"; @@ -45,7 +45,7 @@ int main(int argc, char *argv[]) { 我们可以提前从 xdb 文件中加载出来 VectorIndex 数据,然后全局缓存,每次创建 Searcher 对象的时候使用全局的 VectorIndex 缓存可以减少一次固定的 IO 操作,从而加速查询,减少 IO 压力。 ```c #include -#include "xdb_searcher.h" +#include "xdb_api.h" int main(int argc, char *argv[]) { char *db_path = "ip2region.xdb file path"; @@ -94,7 +94,7 @@ int main(int argc, char *argv[]) { 我们也可以预先加载整个 ip2region.xdb 的数据到内存,然后基于这个数据创建查询对象来实现完全基于文件的查询,类似之前的 memory search。 ```c #include -#include "xdb_searcher.h" +#include "xdb_api.h" int main(int argc, char *argv[]) { char *db_path = "ip2region.xdb file path"; diff --git a/binding/c/main.c b/binding/c/main.c index 49a0f13..8a2219e 100644 --- a/binding/c/main.c +++ b/binding/c/main.c @@ -7,7 +7,7 @@ // @Date 2022/06/28 #include "stdio.h" -#include "xdb_searcher.h" +#include "xdb_api.h" struct searcher_test_entry { xdb_searcher_t searcher; @@ -64,13 +64,13 @@ void destroy_searcher_test(searcher_test_t *test) { // check and free the vector index if (test->v_index != NULL) { - xdb_close_vector_index(test->v_index); + xdb_free_vector_index(test->v_index); test->v_index = NULL; } // check and free the content buffer if (test->c_buffer != NULL) { - xdb_close_content(test->c_buffer); + xdb_free_content(test->c_buffer); test->c_buffer = NULL; } } diff --git a/binding/c/test_util b/binding/c/test_util new file mode 100755 index 0000000000000000000000000000000000000000..625cdc9746549bc66fad79832d92b972458fca7a GIT binary patch literal 17360 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 literal 0 HcmV?d00001 diff --git a/binding/c/util_test.c b/binding/c/test_util.c similarity index 93% rename from binding/c/util_test.c rename to binding/c/test_util.c index f6828d2..9a9fcb6 100644 --- a/binding/c/util_test.c +++ b/binding/c/test_util.c @@ -7,7 +7,7 @@ // @Date 2022/06/27 #include "stdio.h" -#include "xdb_searcher.h" +#include "xdb_api.h" void test_check_ip() { char *ip_list[] = { @@ -37,7 +37,7 @@ void test_check_ip() { } void test_load_header() { - xdb_header_t *header = xdb_load_header_from_file("../../data/ip2region.xdb"); + xdb_header_t *header = xdb_load_header_from_file("../../data/ip2region_v4.xdb"); if (header == NULL) { printf("failed to load header"); } else { @@ -54,29 +54,29 @@ void test_load_header() { ); } - xdb_close_header(header); + xdb_free_header(header); } void test_load_vector_index() { - xdb_vector_index_t *v_index = xdb_load_vector_index_from_file("../../data/ip2region.xdb"); + xdb_vector_index_t *v_index = xdb_load_vector_index_from_file("../../data/ip2region_v4.xdb"); if (v_index == NULL) { printf("failed to load vector index from file\n"); } else { printf("vector index loaded from file, length=%d\n", v_index->length); } - xdb_close_vector_index(v_index); + xdb_free_vector_index(v_index); } void test_load_content() { - xdb_content_t *content = xdb_load_content_from_file("../../data/ip2region.xdb"); + xdb_content_t *content = xdb_load_content_from_file("../../data/ip2region_v4.xdb"); if (content == NULL) { printf("failed to load content from file\n"); } else { printf("content loaded from file, length=%d\n", content->length); } - xdb_close_content(content); + xdb_free_content(content); } // valgrind --tool=memcheck --leak-check=full ./a.out @@ -98,4 +98,4 @@ int main(int argc, char *argv[]) { printf("|--done\n\n"); return 0; -} \ No newline at end of file +} diff --git a/binding/c/xdb_searcher.h b/binding/c/xdb_api.h similarity index 95% rename from binding/c/xdb_searcher.h rename to binding/c/xdb_api.h index 8be9429..22b1d5e 100644 --- a/binding/c/xdb_searcher.h +++ b/binding/c/xdb_api.h @@ -6,8 +6,8 @@ // @Author Lion // @Date 2022/06/27 -#ifndef C_XDB_SEARCHER_H -#define C_XDB_SEARCHER_H +#ifndef C_IP2REGION_XDB_H +#define C_IP2REGION_XDB_H #include #include @@ -59,7 +59,7 @@ XDB_PUBLIC(xdb_header_t *) xdb_load_header(FILE *); XDB_PUBLIC(xdb_header_t *) xdb_load_header_from_file(const char *); -XDB_PUBLIC(void) xdb_close_header(void *); +XDB_PUBLIC(void) xdb_free_header(void *); // --- vector index buffer @@ -73,7 +73,7 @@ XDB_PUBLIC(xdb_vector_index_t *) xdb_load_vector_index(FILE *); XDB_PUBLIC(xdb_vector_index_t *) xdb_load_vector_index_from_file(const char *); -XDB_PUBLIC(void) xdb_close_vector_index(void *); +XDB_PUBLIC(void) xdb_free_vector_index(void *); // --- content buffer @@ -87,7 +87,7 @@ XDB_PUBLIC(xdb_content_t *) xdb_load_content(FILE *); XDB_PUBLIC(xdb_content_t *) xdb_load_content_from_file(const char *); -XDB_PUBLIC(void) xdb_close_content(void *); +XDB_PUBLIC(void) xdb_free_content(void *); // --- End buffer load @@ -146,4 +146,4 @@ XDB_PUBLIC(unsigned int) xdb_mip(unsigned long, unsigned long); XDB_PUBLIC(long) xdb_now(); -#endif //C_XDB_SEARCHER_H +#endif // C_IP2REGION_XDB_H diff --git a/binding/c/xdb_searcher.c b/binding/c/xdb_searcher.c index 53f9af6..7ad4d16 100644 --- a/binding/c/xdb_searcher.c +++ b/binding/c/xdb_searcher.c @@ -6,35 +6,7 @@ // @Author Lion // @Date 2022/06/27 -#include "xdb_searcher.h" - -// for Linux -#ifdef XDB_LINUX -#include "sys/time.h" -#endif - -// @Note: since 2023/10/13 to compatible with the windows system -#ifdef XDB_WINDOWS -#include -XDB_PRIVATE(int) gettimeofday(struct timeval* tp, void* tzp) { - time_t clock; - struct tm tm; - SYSTEMTIME wtm; - GetLocalTime(&wtm); - tm.tm_year = wtm.wYear - 1900; - tm.tm_mon = wtm.wMonth - 1; - tm.tm_mday = wtm.wDay; - tm.tm_hour = wtm.wHour; - tm.tm_min = wtm.wMinute; - tm.tm_sec = wtm.wSecond; - tm.tm_isdst = -1; - clock = mktime(&tm); - tp->tv_sec = clock; - tp->tv_usec = wtm.wMilliseconds * 1000; - return (0); -} -#endif - +#include "xdb_api.h" // internal function prototype define XDB_PRIVATE(int) read(xdb_searcher_t *, long offset, char *, size_t length); @@ -196,234 +168,3 @@ XDB_PRIVATE(int) read(xdb_searcher_t *xdb, long offset, char *buffer, size_t len XDB_PUBLIC(int) xdb_get_io_count(xdb_searcher_t *xdb) { return xdb->io_count; } - - -// --- buffer load util functions - -XDB_PUBLIC(xdb_header_t *) xdb_load_header(FILE *handle) { - xdb_header_t *header; - unsigned int size = xdb_header_info_length; - - // entry alloc - header = (xdb_header_t *) xdb_malloc(sizeof(xdb_header_t)); - if (header == NULL) { - return NULL; - } - - if (fseek(handle, 0, SEEK_SET) == -1) { - xdb_free(header); - return NULL; - } - - if (fread(header->buffer, 1,size, handle) != size) { - xdb_free(header); - return NULL; - } - - // fill the fields - header->length = size; - header->version = (unsigned short) xdb_get_ushort(header->buffer, 0); - header->index_policy = (unsigned short) xdb_get_ushort(header->buffer, 2); - header->created_at = xdb_get_uint(header->buffer, 4); - header->start_index_ptr = xdb_get_uint(header->buffer, 8); - header->end_index_ptr = xdb_get_uint(header->buffer,12); - - return header; -} - -XDB_PUBLIC(xdb_header_t *) xdb_load_header_from_file(const char *db_path) { - xdb_header_t *header; - FILE *handle = fopen(db_path, "rb"); - if (handle == NULL) { - return NULL; - } - - header = xdb_load_header(handle); - fclose(handle); - return header; -} - -XDB_PUBLIC(void) xdb_close_header(void *ptr) { - xdb_header_t *header = (xdb_header_t *) ptr; - if (header->length > 0) { - header->length = 0; - xdb_free(header); - } -} - -// --- vector index - -XDB_PUBLIC(xdb_vector_index_t *) xdb_load_vector_index(FILE *handle) { - xdb_vector_index_t *v_index; - unsigned int size = xdb_vector_index_length; - - // seek to the vector index offset - if (fseek(handle, xdb_header_info_length, SEEK_SET) == -1) { - return NULL; - } - - // do the buffer read - v_index = (xdb_vector_index_t *) xdb_malloc(sizeof(xdb_vector_index_t)); - if (v_index == NULL) { - return NULL; - } - - v_index->length = size; - if (fread(v_index->buffer, 1, size, handle) != size) { - xdb_free(v_index); - return NULL; - } - - return v_index; -} - -XDB_PUBLIC(xdb_vector_index_t *) xdb_load_vector_index_from_file(const char *db_path) { - xdb_vector_index_t *v_index; - FILE *handle = fopen(db_path, "rb"); - if (handle == NULL) { - return NULL; - } - - v_index = xdb_load_vector_index(handle); - fclose(handle); - return v_index; -} - -XDB_PUBLIC(void) xdb_close_vector_index(void *ptr) { - xdb_vector_index_t *v_index = (xdb_vector_index_t *) ptr; - if (v_index->length > 0) { - v_index->length = 0; - xdb_free(v_index); - } -} - -// --- content buffer - -XDB_PUBLIC(xdb_content_t *) xdb_load_content(FILE *handle) { - unsigned int size; - xdb_content_t *content; - - // determine the file size - if (fseek(handle, 0, SEEK_END) == -1) { - return NULL; - } - - size = (unsigned int) ftell(handle); - if (fseek(handle, 0, SEEK_SET) == -1) { - return NULL; - } - - // do the file read - content = (xdb_content_t *) xdb_malloc(sizeof(xdb_content_t)); - if (content == NULL) { - return NULL; - } - - // do the buffer alloc - content->buffer = (char *) xdb_malloc(size); - if (content->buffer == NULL) { - xdb_free(content); - return NULL; - } - - // read the content into the buffer - content->length = size; - if (fread(content->buffer, 1, size, handle) != size) { - xdb_free(content); - return NULL; - } - - return content; -} - -XDB_PUBLIC(xdb_content_t *) xdb_load_content_from_file(const char *db_path) { - xdb_content_t *content; - FILE *handle = fopen(db_path, "rb"); - if (handle == NULL) { - return NULL; - } - - content = xdb_load_content(handle); - fclose(handle); - return content; -} - -XDB_PUBLIC(void) xdb_close_content(void *ptr) { - xdb_content_t *content = (xdb_content_t *) ptr; - if (content->length > 0) { - content->length = 0; - xdb_free(content->buffer); - content->buffer = NULL; - xdb_free(content); - } -} - -// --- End - -// get unsigned long (4bytes) from a specified buffer start from the specified offset -XDB_PUBLIC(unsigned int) xdb_get_uint(const char *buffer, int offset) { - return ( - ((buffer[offset ]) & 0x000000FF) | - ((buffer[offset+1] << 8) & 0x0000FF00) | - ((buffer[offset+2] << 16) & 0x00FF0000) | - ((buffer[offset+3] << 24) & 0xFF000000) - ); -} - -// get unsigned short (2bytes) from a specified buffer start from the specified offset -XDB_PUBLIC(int) xdb_get_ushort(const char *buffer, int offset) { - return ( - ((buffer[offset ]) & 0x000000FF) | - ((buffer[offset+1] << 8) & 0x0000FF00) - ); -} - -// string ip to unsigned int -static int shiftIndex[4] = {24, 16, 8, 0}; -XDB_PUBLIC(int) xdb_check_ip(const char *src_ip, unsigned int *dst_ip) { - char c; - int i, n, ip = 0; - const char *ptr = src_ip; - for (i = 0; i < 4; i++) { - n = 0; - while (1) { - c = *ptr; - ptr++; - if (c >= '0' && c <= '9') { - n *= 10; - n += c - '0'; - } else if ((i < 3 && c == '.') || i == 3) { - // stopping at the '.' but ignore the tailing chars - // after the 3rd one (auto clean the tailing none-integer ?). - break; - } else { - return 1; - } - } - - if (n > 0xFF) { - return 2; - } - - ip |= (n << shiftIndex[i]); - } - - *dst_ip = ip; - return 0; -} - -// unsigned int ip to string ip -XDB_PUBLIC(void) xdb_long2ip(unsigned int ip, char *buffer) { - sprintf(buffer, "%d.%d.%d.%d", (ip >> 24) & 0xFF, (ip >> 16) & 0xFF, (ip >> 8) & 0xFF, ip & 0xFF); -} - -// get the middle ip of a and b -XDB_PUBLIC(unsigned int) xdb_mip(unsigned long a, unsigned long b) { - return (unsigned int) ((a + b) >> 1); -} - -XDB_PUBLIC(long) xdb_now() { - struct timeval c_time; - gettimeofday(&c_time, NULL); - return c_time.tv_sec * (int)1e6 + c_time.tv_usec; -} diff --git a/binding/c/xdb_util.c b/binding/c/xdb_util.c new file mode 100644 index 0000000..2d6c9e9 --- /dev/null +++ b/binding/c/xdb_util.c @@ -0,0 +1,264 @@ +// 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. + +// --- +// @Author Lion +// @Date 2022/06/27 + +#include "xdb_api.h" + +// for Linux +#ifdef XDB_LINUX +#include "sys/time.h" +#endif + +// @Note: since 2023/10/13 to compatible with the windows system +#ifdef XDB_WINDOWS +#include +XDB_PRIVATE(int) gettimeofday(struct timeval* tp, void* tzp) { + time_t clock; + struct tm tm; + SYSTEMTIME wtm; + GetLocalTime(&wtm); + tm.tm_year = wtm.wYear - 1900; + tm.tm_mon = wtm.wMonth - 1; + tm.tm_mday = wtm.wDay; + tm.tm_hour = wtm.wHour; + tm.tm_min = wtm.wMinute; + tm.tm_sec = wtm.wSecond; + tm.tm_isdst = -1; + clock = mktime(&tm); + tp->tv_sec = clock; + tp->tv_usec = wtm.wMilliseconds * 1000; + return (0); +} +#endif + +XDB_PUBLIC(xdb_header_t *) xdb_load_header(FILE *handle) { + xdb_header_t *header; + unsigned int size = xdb_header_info_length; + + // entry alloc + header = (xdb_header_t *) xdb_malloc(sizeof(xdb_header_t)); + if (header == NULL) { + return NULL; + } + + if (fseek(handle, 0, SEEK_SET) == -1) { + xdb_free(header); + return NULL; + } + + if (fread(header->buffer, 1,size, handle) != size) { + xdb_free(header); + return NULL; + } + + // fill the fields + header->length = size; + header->version = (unsigned short) xdb_get_ushort(header->buffer, 0); + header->index_policy = (unsigned short) xdb_get_ushort(header->buffer, 2); + header->created_at = xdb_get_uint(header->buffer, 4); + header->start_index_ptr = xdb_get_uint(header->buffer, 8); + header->end_index_ptr = xdb_get_uint(header->buffer,12); + + return header; +} + +XDB_PUBLIC(xdb_header_t *) xdb_load_header_from_file(const char *db_path) { + xdb_header_t *header; + FILE *handle = fopen(db_path, "rb"); + if (handle == NULL) { + return NULL; + } + + header = xdb_load_header(handle); + fclose(handle); + return header; +} + +XDB_PUBLIC(void) xdb_free_header(void *ptr) { + xdb_header_t *header = (xdb_header_t *) ptr; + if (header->length > 0) { + header->length = 0; + xdb_free(header); + } +} + +// --- vector index + +XDB_PUBLIC(xdb_vector_index_t *) xdb_load_vector_index(FILE *handle) { + xdb_vector_index_t *v_index; + unsigned int size = xdb_vector_index_length; + + // seek to the vector index offset + if (fseek(handle, xdb_header_info_length, SEEK_SET) == -1) { + return NULL; + } + + // do the buffer read + v_index = (xdb_vector_index_t *) xdb_malloc(sizeof(xdb_vector_index_t)); + if (v_index == NULL) { + return NULL; + } + + v_index->length = size; + if (fread(v_index->buffer, 1, size, handle) != size) { + xdb_free(v_index); + return NULL; + } + + return v_index; +} + +XDB_PUBLIC(xdb_vector_index_t *) xdb_load_vector_index_from_file(const char *db_path) { + xdb_vector_index_t *v_index; + FILE *handle = fopen(db_path, "rb"); + if (handle == NULL) { + return NULL; + } + + v_index = xdb_load_vector_index(handle); + fclose(handle); + return v_index; +} + +XDB_PUBLIC(void) xdb_free_vector_index(void *ptr) { + xdb_vector_index_t *v_index = (xdb_vector_index_t *) ptr; + if (v_index->length > 0) { + v_index->length = 0; + xdb_free(v_index); + } +} + +// --- content buffer + +XDB_PUBLIC(xdb_content_t *) xdb_load_content(FILE *handle) { + unsigned int size; + xdb_content_t *content; + + // determine the file size + if (fseek(handle, 0, SEEK_END) == -1) { + return NULL; + } + + size = (unsigned int) ftell(handle); + if (fseek(handle, 0, SEEK_SET) == -1) { + return NULL; + } + + // do the file read + content = (xdb_content_t *) xdb_malloc(sizeof(xdb_content_t)); + if (content == NULL) { + return NULL; + } + + // do the buffer alloc + content->buffer = (char *) xdb_malloc(size); + if (content->buffer == NULL) { + xdb_free(content); + return NULL; + } + + // read the content into the buffer + content->length = size; + if (fread(content->buffer, 1, size, handle) != size) { + xdb_free(content); + return NULL; + } + + return content; +} + +XDB_PUBLIC(xdb_content_t *) xdb_load_content_from_file(const char *db_path) { + xdb_content_t *content; + FILE *handle = fopen(db_path, "rb"); + if (handle == NULL) { + return NULL; + } + + content = xdb_load_content(handle); + fclose(handle); + return content; +} + +XDB_PUBLIC(void) xdb_free_content(void *ptr) { + xdb_content_t *content = (xdb_content_t *) ptr; + if (content->length > 0) { + content->length = 0; + xdb_free(content->buffer); + content->buffer = NULL; + xdb_free(content); + } +} + +// --- End + +// get unsigned long (4bytes) from a specified buffer start from the specified offset +XDB_PUBLIC(unsigned int) xdb_get_uint(const char *buffer, int offset) { + return ( + ((buffer[offset ]) & 0x000000FF) | + ((buffer[offset+1] << 8) & 0x0000FF00) | + ((buffer[offset+2] << 16) & 0x00FF0000) | + ((buffer[offset+3] << 24) & 0xFF000000) + ); +} + +// get unsigned short (2bytes) from a specified buffer start from the specified offset +XDB_PUBLIC(int) xdb_get_ushort(const char *buffer, int offset) { + return ( + ((buffer[offset ]) & 0x000000FF) | + ((buffer[offset+1] << 8) & 0x0000FF00) + ); +} + +// string ip to unsigned int +static int shiftIndex[4] = {24, 16, 8, 0}; +XDB_PUBLIC(int) xdb_check_ip(const char *src_ip, unsigned int *dst_ip) { + char c; + int i, n, ip = 0; + const char *ptr = src_ip; + for (i = 0; i < 4; i++) { + n = 0; + while (1) { + c = *ptr; + ptr++; + if (c >= '0' && c <= '9') { + n *= 10; + n += c - '0'; + } else if ((i < 3 && c == '.') || i == 3) { + // stopping at the '.' but ignore the tailing chars + // after the 3rd one (auto clean the tailing none-integer ?). + break; + } else { + return 1; + } + } + + if (n > 0xFF) { + return 2; + } + + ip |= (n << shiftIndex[i]); + } + + *dst_ip = ip; + return 0; +} + +// unsigned int ip to string ip +XDB_PUBLIC(void) xdb_long2ip(unsigned int ip, char *buffer) { + sprintf(buffer, "%d.%d.%d.%d", (ip >> 24) & 0xFF, (ip >> 16) & 0xFF, (ip >> 8) & 0xFF, ip & 0xFF); +} + +// get the middle ip of a and b +XDB_PUBLIC(unsigned int) xdb_mip(unsigned long a, unsigned long b) { + return (unsigned int) ((a + b) >> 1); +} + +XDB_PUBLIC(long) xdb_now() { + struct timeval c_time; + gettimeofday(&c_time, NULL); + return c_time.tv_sec * (int)1e6 + c_time.tv_usec; +}