Replace c_impl, remove rust_binding, with cpp_impl
This commit is contained in:
parent
a11c99e115
commit
00c1be07dc
27 changed files with 0 additions and 3781 deletions
0
cpp_impl/.gitignore → .gitignore
vendored
0
cpp_impl/.gitignore → .gitignore
vendored
2
c_impl/.gitignore
vendored
2
c_impl/.gitignore
vendored
|
@ -1,2 +0,0 @@
|
|||
build*/
|
||||
compile_commands.json
|
|
@ -1,49 +0,0 @@
|
|||
cmake_minimum_required(VERSION 3.7)
|
||||
project(UDPConnection)
|
||||
|
||||
set(UDPConnection_VERSION 1.0)
|
||||
|
||||
set(UDPConnection_SOURCES
|
||||
src/UDPConnection.c
|
||||
src/UDPC_Deque.c
|
||||
src/UDPC_HashMap.c
|
||||
)
|
||||
|
||||
set(CMAKE_C_FLAGS "-Wall -Wno-missing-braces")
|
||||
set(CMAKE_C_FLAGS_DEBUG "-O0 -g")
|
||||
set(CMAKE_C_FLAGS_RELEASE "-O3 -D NDEBUG")
|
||||
|
||||
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
|
||||
message(STATUS "Setting build type to 'Debug', none was specified.")
|
||||
set(CMAKE_BUILD_TYPE Debug CACHE STRING "Choose the type of build." FORCE)
|
||||
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release")
|
||||
endif()
|
||||
|
||||
add_library(UDPConnection ${UDPConnection_SOURCES})
|
||||
|
||||
set_target_properties(UDPConnection PROPERTIES VERSION ${UDPConnection_VERSION})
|
||||
|
||||
target_compile_features(UDPConnection PUBLIC c_std_11)
|
||||
target_link_libraries(UDPConnection PUBLIC pthread)
|
||||
|
||||
if(CMAKE_BUILD_TYPE MATCHES "Debug")
|
||||
set(UDPC_UnitTest_SOURCES
|
||||
src/test/UDPC_UnitTest.c)
|
||||
add_executable(UnitTest ${UDPC_UnitTest_SOURCES})
|
||||
target_link_libraries(UnitTest PUBLIC UDPConnection)
|
||||
target_include_directories(UnitTest PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src)
|
||||
|
||||
set(UDPC_NetworkTest_SOURCES
|
||||
src/test/UDPC_NetworkTest.c)
|
||||
add_executable(NetworkTest ${UDPC_NetworkTest_SOURCES})
|
||||
target_link_libraries(NetworkTest PUBLIC UDPConnection)
|
||||
target_include_directories(NetworkTest PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src)
|
||||
endif()
|
||||
|
||||
install(TARGETS UDPConnection DESTINATION lib)
|
||||
install(FILES
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/UDPConnection.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/UDPC_Defines.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/UDPC_Deque.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/UDPC_HashMap.h
|
||||
DESTINATION include)
|
|
@ -1,65 +0,0 @@
|
|||
#ifndef UDPC_DEFINES_H
|
||||
#define UDPC_DEFINES_H
|
||||
|
||||
#define UDPC_PLATFORM_WINDOWS 1
|
||||
#define UDPC_PLATFORM_MAC 2
|
||||
#define UDPC_PLATFORM_LINUX 3
|
||||
#define UDPC_PLATFORM_UNKNOWN 0
|
||||
|
||||
#if defined _WIN32
|
||||
#define UDPC_PLATFORM UDPC_PLATFORM_WINDOWS
|
||||
#elif defined __APPLE__
|
||||
#define UDPC_PLATFORM UDPC_PLATFORM_MAC
|
||||
#elif defined __linux__
|
||||
#define UDPC_PLATFORM UDPC_PLATFORM_LINUX
|
||||
#else
|
||||
#define UDPC_PLATFORM UDPC_PLATFORM_UNKNOWN
|
||||
#endif
|
||||
|
||||
#define UDPC_SUCCESS 0
|
||||
#define UDPC_ERR_SOCKETFAIL 1 // failed to create socket
|
||||
#define UDPC_ERR_SOCKETBINDF 2 // failed to bind socket
|
||||
#define UDPC_ERR_SOCKETNONBF 3 // failed to set non-blocking on socket
|
||||
#define UDPC_ERR_MTXFAIL 4 // failed to create mutex
|
||||
#define UDPC_ERR_CVFAIL 5 // failed to create condition variable
|
||||
#define UDPC_ERR_THREADFAIL 6 // failed to create thread
|
||||
|
||||
// Error strings are defined in UDPConnection.c
|
||||
extern const char *UDPC_ERR_SOCKETFAIL_STR;
|
||||
extern const char *UDPC_ERR_SOCKETBINDF_STR;
|
||||
extern const char *UDPC_ERR_SOCKETNONBF_STR;
|
||||
extern const char *UDPC_ERR_MTXFAIL_STR;
|
||||
extern const char *UDPC_ERR_CVFAIL_STR;
|
||||
extern const char *UDPC_ERR_THREADFAIL_STR;
|
||||
|
||||
#define UDPC_CD_AMOUNT 32
|
||||
|
||||
#define UDPC_GOOD_MODE_SEND_INTERVAL (1.0f/30.0f)
|
||||
#define UDPC_BAD_MODE_SEND_INTERVAL (1.0f/10.0f)
|
||||
#define UDPC_TIMEOUT_SECONDS 10.0f
|
||||
#define UDPC_HEARTBEAT_PKT_INTERVAL (15.0f/100.0f)
|
||||
#define UDPC_INIT_PKT_INTERVAL 5
|
||||
#define UDPC_INIT_PKT_INTERVAL_F ((float)UDPC_INIT_PKT_INTERVAL)
|
||||
#define UDPC_PKT_DEFAULT_PROTOCOL_ID 1357924680
|
||||
|
||||
#define UDPC_ID_CONNECT 0x80000000
|
||||
#define UDPC_ID_PING 0x40000000
|
||||
#define UDPC_ID_NO_REC_CHK 0x20000000
|
||||
#define UDPC_ID_RESENDING 0x10000000
|
||||
|
||||
#define UDPC_SENT_PKTS_MAX_SIZE 34
|
||||
#define UDPC_SENT_PKTS_ALLOC_SIZE 35
|
||||
#define UDPC_SEND_PKTS_ALLOC_SIZE 40
|
||||
#define UDPC_RESEND_PKTS_ALLOC_SIZE 40
|
||||
|
||||
#define UDPC_PACKET_MAX_SIZE 8192
|
||||
|
||||
#define UDPC_PACKET_TIMEOUT_SEC 1.0f
|
||||
#define UDPC_GOOD_RTT_LIMIT_SEC 0.25f
|
||||
|
||||
#define UDPC_REC_PKTS_ALLOC_SIZE 128
|
||||
|
||||
#define UDPC_CONNECTED_EVENT_SIZE 64
|
||||
#define UDPC_DISCONNECTED_EVENT_SIZE 64
|
||||
|
||||
#endif
|
|
@ -1,511 +0,0 @@
|
|||
#include "UDPC_Deque.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
UDPC_Deque* UDPC_Deque_init(uint32_t alloc_size)
|
||||
{
|
||||
UDPC_Deque *deque = malloc(sizeof(UDPC_Deque));
|
||||
if(!deque)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
UDPC_Deque_clear(deque);
|
||||
deque->alloc_size = alloc_size;
|
||||
deque->buf = malloc(alloc_size);
|
||||
if(deque->buf)
|
||||
{
|
||||
return deque;
|
||||
}
|
||||
else
|
||||
{
|
||||
free(deque);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void UDPC_Deque_destroy(UDPC_Deque *deque)
|
||||
{
|
||||
free(deque->buf);
|
||||
free(deque);
|
||||
}
|
||||
|
||||
int UDPC_Deque_realloc(UDPC_Deque *deque, uint32_t new_size)
|
||||
{
|
||||
if(new_size < deque->size)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else if(deque->size != 0 && deque->tail <= deque->head)
|
||||
{
|
||||
char *buf = malloc(new_size);
|
||||
memcpy(buf, &deque->buf[deque->head], deque->alloc_size - deque->head);
|
||||
if(deque->tail != 0)
|
||||
{
|
||||
memcpy(&buf[deque->alloc_size - deque->head], deque->buf, deque->tail);
|
||||
}
|
||||
free(deque->buf);
|
||||
deque->buf = buf;
|
||||
deque->alloc_size = new_size;
|
||||
deque->head = 0;
|
||||
deque->tail = deque->size;
|
||||
if(deque->tail == deque->alloc_size)
|
||||
{
|
||||
deque->tail = 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
void *buf = realloc(deque->buf, new_size);
|
||||
if(buf)
|
||||
{
|
||||
deque->buf = buf;
|
||||
deque->alloc_size = new_size;
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int UDPC_Deque_push_back(UDPC_Deque *deque, const void *data, uint32_t size)
|
||||
{
|
||||
if(deque->size + size > deque->alloc_size)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else if(deque->tail + size <= deque->alloc_size)
|
||||
{
|
||||
memcpy(&deque->buf[deque->tail], data, size);
|
||||
deque->tail += size;
|
||||
if(deque->tail == deque->alloc_size)
|
||||
{
|
||||
deque->tail = 0;
|
||||
}
|
||||
deque->size += size;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint32_t temp;
|
||||
|
||||
if(deque->tail < deque->alloc_size)
|
||||
{
|
||||
memcpy(&deque->buf[deque->tail], data, deque->alloc_size - deque->tail);
|
||||
temp = deque->alloc_size - deque->tail;
|
||||
deque->size += temp;
|
||||
size -= temp;
|
||||
deque->tail = 0;
|
||||
}
|
||||
if(size > 0)
|
||||
{
|
||||
memcpy(&deque->buf[deque->tail], &((const char*)data)[temp], size);
|
||||
deque->tail += size;
|
||||
deque->size += size;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int UDPC_Deque_push_front(UDPC_Deque *deque, const void *data, uint32_t size)
|
||||
{
|
||||
if(deque->size + size > deque->alloc_size)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else if(size <= deque->head)
|
||||
{
|
||||
memcpy(&deque->buf[deque->head - size], data, size);
|
||||
deque->head -= size;
|
||||
deque->size += size;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(deque->head > 0)
|
||||
{
|
||||
memcpy(deque->buf, &((const char*)data)[size - deque->head], deque->head);
|
||||
deque->size += deque->head;
|
||||
size -= deque->head;
|
||||
deque->head = 0;
|
||||
}
|
||||
if(size > 0)
|
||||
{
|
||||
memcpy(&deque->buf[deque->alloc_size - size], data, size);
|
||||
deque->head = deque->alloc_size - size;
|
||||
deque->size += size;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int UDPC_Deque_push_back_realloc(UDPC_Deque *deque, const void *data, uint32_t size)
|
||||
{
|
||||
if(UDPC_Deque_push_back(deque, data, size) == 0)
|
||||
{
|
||||
if(UDPC_Deque_realloc(deque, deque->alloc_size * 2) != 0)
|
||||
{
|
||||
return UDPC_Deque_push_back(deque, data, size);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int UDPC_Deque_push_front_realloc(UDPC_Deque *deque, const void *data, uint32_t size)
|
||||
{
|
||||
if(UDPC_Deque_push_front(deque, data, size) == 0)
|
||||
{
|
||||
if(UDPC_Deque_realloc(deque, deque->alloc_size * 2) != 0)
|
||||
{
|
||||
return UDPC_Deque_push_front(deque, data, size);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t UDPC_Deque_get_available(UDPC_Deque *deque)
|
||||
{
|
||||
return deque->alloc_size - deque->size;
|
||||
}
|
||||
|
||||
uint32_t UDPC_Deque_get_used(UDPC_Deque *deque)
|
||||
{
|
||||
return deque->size;
|
||||
}
|
||||
|
||||
int UDPC_Deque_get_back(UDPC_Deque *deque, void **data, uint32_t *size)
|
||||
{
|
||||
int returnValue = 1;
|
||||
if(deque->size == 0)
|
||||
{
|
||||
*size = 0;
|
||||
*data = NULL;
|
||||
return 0;
|
||||
}
|
||||
else if(*size > deque->size)
|
||||
{
|
||||
*size = deque->size;
|
||||
returnValue = 0;
|
||||
}
|
||||
|
||||
*data = malloc(*size);
|
||||
|
||||
if(deque->tail == 0)
|
||||
{
|
||||
memcpy(*data, &deque->buf[deque->alloc_size - *size], *size);
|
||||
return returnValue;
|
||||
}
|
||||
else if(deque->tail < *size)
|
||||
{
|
||||
memcpy(data[*size - deque->tail], deque->buf, deque->tail);
|
||||
memcpy(
|
||||
*data,
|
||||
&deque->buf[deque->alloc_size - (*size - deque->tail)],
|
||||
*size - deque->tail);
|
||||
return returnValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(*data, &deque->buf[deque->tail - *size], *size);
|
||||
return returnValue;
|
||||
}
|
||||
}
|
||||
|
||||
void* UDPC_Deque_get_back_ptr(UDPC_Deque *deque, uint32_t unitSize)
|
||||
{
|
||||
if(deque->size < unitSize)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(deque->tail == 0 && deque->size >= unitSize)
|
||||
{
|
||||
return &deque->buf[deque->alloc_size - unitSize];
|
||||
}
|
||||
else if(deque->tail < unitSize)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
return &deque->buf[deque->tail - unitSize];
|
||||
}
|
||||
}
|
||||
|
||||
int UDPC_Deque_get_front(UDPC_Deque *deque, void **data, uint32_t *size)
|
||||
{
|
||||
int returnValue = 1;
|
||||
if(deque->size == 0)
|
||||
{
|
||||
*size = 0;
|
||||
*data = NULL;
|
||||
return 0;
|
||||
}
|
||||
else if(*size > deque->size)
|
||||
{
|
||||
*size = deque->size;
|
||||
returnValue = 0;
|
||||
}
|
||||
|
||||
*data = malloc(*size);
|
||||
|
||||
if(deque->head + *size > deque->alloc_size)
|
||||
{
|
||||
memcpy(*data, &deque->buf[deque->head], deque->alloc_size - deque->head);
|
||||
memcpy(
|
||||
data[deque->alloc_size - deque->head],
|
||||
deque->buf,
|
||||
*size - (deque->alloc_size - deque->head));
|
||||
return returnValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(*data, &deque->buf[deque->head], *size);
|
||||
return returnValue;
|
||||
}
|
||||
}
|
||||
|
||||
void* UDPC_Deque_get_front_ptr(UDPC_Deque *deque, uint32_t unitSize)
|
||||
{
|
||||
if(deque->size < unitSize || deque->head + unitSize > deque->alloc_size)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return &deque->buf[deque->head];
|
||||
}
|
||||
|
||||
void UDPC_Deque_pop_back(UDPC_Deque *deque, uint32_t size)
|
||||
{
|
||||
if(deque->size == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
else if(deque->size <= size)
|
||||
{
|
||||
UDPC_Deque_clear(deque);
|
||||
return;
|
||||
}
|
||||
|
||||
deque->size -= size;
|
||||
|
||||
if(deque->tail < size)
|
||||
{
|
||||
deque->tail = deque->alloc_size - (size - deque->tail);
|
||||
}
|
||||
else
|
||||
{
|
||||
deque->tail -= size;
|
||||
}
|
||||
}
|
||||
|
||||
void UDPC_Deque_pop_front(UDPC_Deque *deque, uint32_t size)
|
||||
{
|
||||
if(deque->size == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
else if(deque->size <= size)
|
||||
{
|
||||
UDPC_Deque_clear(deque);
|
||||
return;
|
||||
}
|
||||
|
||||
deque->size -= size;
|
||||
|
||||
if(deque->head + size > deque->alloc_size)
|
||||
{
|
||||
deque->head = deque->head + size - deque->alloc_size;
|
||||
}
|
||||
else
|
||||
{
|
||||
deque->head += size;
|
||||
if(deque->head == deque->alloc_size)
|
||||
{
|
||||
deque->head = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int UDPC_Deque_index(UDPC_Deque *deque, uint32_t unitSize, uint32_t index, void **out)
|
||||
{
|
||||
uint32_t pos = unitSize * index;
|
||||
uint32_t abspos;
|
||||
if(pos >= deque->size)
|
||||
{
|
||||
*out = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
*out = malloc(unitSize);
|
||||
|
||||
if(pos + deque->head >= deque->alloc_size)
|
||||
{
|
||||
abspos = pos + deque->head - deque->alloc_size;
|
||||
}
|
||||
else
|
||||
{
|
||||
abspos = pos + deque->head;
|
||||
}
|
||||
|
||||
if(abspos + unitSize >= deque->alloc_size)
|
||||
{
|
||||
memcpy(*out, &deque->buf[abspos], deque->alloc_size - abspos);
|
||||
memcpy(*out, deque->buf, unitSize - (deque->alloc_size - abspos));
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(*out, &deque->buf[abspos], unitSize);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void* UDPC_Deque_index_ptr(UDPC_Deque *deque, uint32_t unitSize, uint32_t index)
|
||||
{
|
||||
uint32_t pos = unitSize * index;
|
||||
uint32_t abspos;
|
||||
if(pos >= deque->size)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(pos + deque->head >= deque->alloc_size)
|
||||
{
|
||||
abspos = pos + deque->head - deque->alloc_size;
|
||||
}
|
||||
else
|
||||
{
|
||||
abspos = pos + deque->head;
|
||||
}
|
||||
|
||||
if(abspos + unitSize > deque->alloc_size)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return &deque->buf[abspos];
|
||||
}
|
||||
|
||||
int UDPC_Deque_index_rev(UDPC_Deque *deque, uint32_t unitSize, uint32_t index, void **out)
|
||||
{
|
||||
uint32_t pos = unitSize * (index + 1);
|
||||
uint32_t abspos;
|
||||
if(pos >= deque->size + unitSize)
|
||||
{
|
||||
*out = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
*out = malloc(unitSize);
|
||||
|
||||
if(pos > deque->tail)
|
||||
{
|
||||
abspos = deque->alloc_size - (pos - deque->tail);
|
||||
}
|
||||
else
|
||||
{
|
||||
abspos = deque->tail - pos;
|
||||
}
|
||||
|
||||
if(abspos + unitSize >= deque->alloc_size)
|
||||
{
|
||||
memcpy(*out, &deque->buf[abspos], deque->alloc_size - abspos);
|
||||
memcpy(*out, deque->buf, unitSize - (deque->alloc_size - abspos));
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(*out, &deque->buf[abspos], unitSize);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void* UDPC_Deque_index_rev_ptr(UDPC_Deque *deque, uint32_t unitSize, uint32_t index)
|
||||
{
|
||||
uint32_t pos = unitSize * (index + 1);
|
||||
uint32_t abspos;
|
||||
if(pos >= deque->size + unitSize)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(pos > deque->tail)
|
||||
{
|
||||
abspos = deque->alloc_size - (pos - deque->tail);
|
||||
}
|
||||
else
|
||||
{
|
||||
abspos = deque->tail - pos;
|
||||
}
|
||||
|
||||
if(abspos + unitSize > deque->alloc_size)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return &deque->buf[abspos];
|
||||
}
|
||||
|
||||
int UDPC_Deque_remove(UDPC_Deque *deque, uint32_t unitSize, uint32_t index)
|
||||
{
|
||||
uint32_t pos = unitSize * index;
|
||||
uint32_t abspos;
|
||||
uint32_t lastpos;
|
||||
if(deque->size == 0 || pos >= deque->size)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else if(deque->size <= unitSize)
|
||||
{
|
||||
UDPC_Deque_clear(deque);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(pos + deque->head >= deque->alloc_size)
|
||||
{
|
||||
abspos = pos + deque->head - deque->alloc_size;
|
||||
}
|
||||
else
|
||||
{
|
||||
abspos = pos + deque->head;
|
||||
}
|
||||
|
||||
if(deque->tail == 0)
|
||||
{
|
||||
lastpos = deque->alloc_size - unitSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
lastpos = deque->tail - unitSize;
|
||||
}
|
||||
|
||||
if(abspos != lastpos)
|
||||
{
|
||||
if(deque->tail == 0)
|
||||
{
|
||||
memcpy(&deque->buf[abspos], &deque->buf[deque->alloc_size - unitSize], unitSize);
|
||||
deque->tail = deque->alloc_size - unitSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(&deque->buf[abspos], &deque->buf[deque->tail - unitSize], unitSize);
|
||||
deque->tail -= unitSize;
|
||||
}
|
||||
deque->size -= unitSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
UDPC_Deque_pop_back(deque, unitSize);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void UDPC_Deque_clear(UDPC_Deque *deque)
|
||||
{
|
||||
deque->head = 0;
|
||||
deque->tail = 0;
|
||||
deque->size = 0;
|
||||
}
|
|
@ -1,168 +0,0 @@
|
|||
#ifndef UDPC_DEQUE_H
|
||||
#define UDPC_DEQUE_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
typedef struct {
|
||||
uint32_t head;
|
||||
uint32_t tail;
|
||||
uint32_t size;
|
||||
uint32_t alloc_size;
|
||||
char *buf;
|
||||
} UDPC_Deque;
|
||||
|
||||
/*!
|
||||
* \return non-null on success
|
||||
*/
|
||||
UDPC_Deque* UDPC_Deque_init(uint32_t alloc_size);
|
||||
|
||||
/*!
|
||||
* Frees resources used by a UDPC_Deque
|
||||
*/
|
||||
void UDPC_Deque_destroy(UDPC_Deque *deque);
|
||||
|
||||
/*!
|
||||
* Fails if new_size is smaller than current size of Deque.
|
||||
* On failure, deque remains unchanged.
|
||||
* \return non-zero on success
|
||||
*/
|
||||
int UDPC_Deque_realloc(UDPC_Deque *deque, uint32_t new_size);
|
||||
|
||||
/*!
|
||||
* If there was not enough space in the Deque, then no data is inserted at all.
|
||||
* \return non-zero on success (there was enough size to insert data)
|
||||
*/
|
||||
int UDPC_Deque_push_back(UDPC_Deque *deque, const void *data, uint32_t size);
|
||||
|
||||
/*!
|
||||
* If there was not enough space in the Deque, then no data is inserted at all.
|
||||
* \return non-zero on success (there was enough size to insert data)
|
||||
*/
|
||||
int UDPC_Deque_push_front(UDPC_Deque *deque, const void *data, uint32_t size);
|
||||
|
||||
/*!
|
||||
* \brief Same as push_back, but realloc if not enough free space
|
||||
* Note when realloc occurs, the allocated space is doubled.
|
||||
* \return non-zero on data pushed into Deque success
|
||||
*/
|
||||
int UDPC_Deque_push_back_realloc(UDPC_Deque *deque, const void *data, uint32_t size);
|
||||
|
||||
/*!
|
||||
* \brief Same as push_front, but realloc if not enough free space
|
||||
* Note when realloc occurs, the allocated space is doubled.
|
||||
* \return non-zero on data pushed into Deque success
|
||||
*/
|
||||
int UDPC_Deque_push_front_realloc(UDPC_Deque *deque, const void *data, uint32_t size);
|
||||
|
||||
/*!
|
||||
* \return size in bytes of available data
|
||||
*/
|
||||
uint32_t UDPC_Deque_get_available(UDPC_Deque *deque);
|
||||
|
||||
/*!
|
||||
* \return size in bytes of used data
|
||||
*/
|
||||
uint32_t UDPC_Deque_get_used(UDPC_Deque *deque);
|
||||
|
||||
/*!
|
||||
* \brief Get data from back of deque
|
||||
* Data must be free'd after use as it was allocated with malloc.
|
||||
* When size is greater than deque size, partial data is allocated, size is
|
||||
* updated to allocated amount. If deque is empty, no data is allocated.
|
||||
* \return non-zero if full requested size was returned
|
||||
*/
|
||||
int UDPC_Deque_get_back(UDPC_Deque *deque, void **data, uint32_t *size);
|
||||
|
||||
/*!
|
||||
* \brief Get data ptr from back of deque
|
||||
* The returned ptr is part of the Deque's internal buffer and must not be
|
||||
* manually free'd; it will be free'd when the Deque itself is destroyed.
|
||||
* \return non-null if tail of deque has contiguous data of size unitSize
|
||||
*/
|
||||
void* UDPC_Deque_get_back_ptr(UDPC_Deque *deque, uint32_t unitSize);
|
||||
|
||||
/*!
|
||||
* \brief Get data from front of deque
|
||||
* Data must be free'd after use as it was allocated with malloc.
|
||||
* When size is greater than deque size, partial data is allocated, size is
|
||||
* updated to allocated amount. If deque is empty, no data is allocated.
|
||||
* \return non-zero if full requested size was returned
|
||||
*/
|
||||
int UDPC_Deque_get_front(UDPC_Deque *deque, void **data, uint32_t *size);
|
||||
|
||||
/*!
|
||||
* \brief Get data ptr from front of deque
|
||||
* The returned ptr is part of the Deque's internal buffer and must not be
|
||||
* manually free'd; it will be free'd when the Deque itself is destroyed.
|
||||
* \return non-null if head of deque has contiguous data of size unitSize
|
||||
*/
|
||||
void* UDPC_Deque_get_front_ptr(UDPC_Deque *deque, uint32_t unitSize);
|
||||
|
||||
/*!
|
||||
* \brief "free" data from the back of the deque
|
||||
* If size is greater than data used, then all data will be "free"d.
|
||||
* Note that this doesn't actually deallocate data, but changes internal values
|
||||
* that keep track of data positions in the internal buffer. The data will only
|
||||
* actually be removed when it is overwritten or the Deque is free'd.
|
||||
*/
|
||||
void UDPC_Deque_pop_back(UDPC_Deque *deque, uint32_t size);
|
||||
|
||||
/*!
|
||||
* \brief "free" data from the front of the deque
|
||||
* If size is greater than data used, then all data will be "free"d.
|
||||
* Note that this doesn't actually deallocate data, but changes internal values
|
||||
* that keep track of data positions in the internal buffer. The data will only
|
||||
* actually be removed when it is overwritten or the Deque is free'd.
|
||||
*/
|
||||
void UDPC_Deque_pop_front(UDPC_Deque *deque, uint32_t size);
|
||||
|
||||
/*!
|
||||
* \brief Get a unitSize sized chunk of data at position unitSize * index
|
||||
* The data will be indexed relative to the head of the Deque.
|
||||
* The out pointer will be malloc'd with size unitSize and will have a copy of
|
||||
* the data at the specified unitSize * index.
|
||||
* Note that the out data must be free'd, but on fail nothing will be malloc'd
|
||||
* and *out will be set to NULL.
|
||||
* \return non-zero if unitSize * index < size
|
||||
*/
|
||||
int UDPC_Deque_index(UDPC_Deque *deque, uint32_t unitSize, uint32_t index, void **out);
|
||||
|
||||
/*!
|
||||
* \brief Get a ptr to the indexed data at position unitSize * index
|
||||
* The ptr will be indexed relative to the head of the Deque.
|
||||
* The returned ptr is part of the Deque's internal buffer and will be free'd
|
||||
* when the Deque is destroyed, so it should not be free'd directly.
|
||||
* \return non-null if indexed data is a valid contiguous part of the buffer
|
||||
*/
|
||||
void* UDPC_Deque_index_ptr(UDPC_Deque *deque, uint32_t unitSize, uint32_t index);
|
||||
|
||||
/*!
|
||||
* \brief Get a unitSize sized chunk of data at position relative to tail
|
||||
* The out pointer will be malloc'd with size unitSize and will have a copy of
|
||||
* the data at the specified unitSize * index relative to tail in reverse
|
||||
* direction.
|
||||
* Note that the out data must be free'd, but on fail nothing will be malloc'd
|
||||
* and *out will be set to NULL.
|
||||
* \return non-zero if unitSize * index < size
|
||||
*/
|
||||
int UDPC_Deque_index_rev(UDPC_Deque *deque, uint32_t unitSize, uint32_t index, void **out);
|
||||
|
||||
/*!
|
||||
* \brief Get a ptr to the indexed data at position unitSize * index
|
||||
* The ptr will be indexed relative to the tail of the Deque.
|
||||
* The returned ptr is part of the Deque's internal buffer and will be free'd
|
||||
* when the Deque is destroyed, so it should not be free'd directly.
|
||||
* \return non-null if indexed data is a valid contiguous part of the buffer
|
||||
*/
|
||||
void* UDPC_Deque_index_rev_ptr(UDPC_Deque *deque, uint32_t unitSize, uint32_t index);
|
||||
|
||||
/*!
|
||||
* \brief Replaces the data at index with data at the end (if exists)
|
||||
* Note this will reduce the size of the Deque by unitSize amount.
|
||||
* \return non-zero if data was removed
|
||||
*/
|
||||
int UDPC_Deque_remove(UDPC_Deque *deque, uint32_t unitSize, uint32_t index);
|
||||
|
||||
void UDPC_Deque_clear(UDPC_Deque *deque);
|
||||
|
||||
#endif
|
|
@ -1,315 +0,0 @@
|
|||
#include "UDPC_HashMap.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
UDPC_HashMap* UDPC_HashMap_init(uint32_t capacity, uint32_t unitSize)
|
||||
{
|
||||
UDPC_HashMap *m = malloc(sizeof(UDPC_HashMap));
|
||||
if(!m)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int fail = 0;
|
||||
m->size = 0;
|
||||
m->capacity = (capacity > UDPC_HASHMAP_INIT_CAPACITY ? capacity : UDPC_HASHMAP_INIT_CAPACITY);
|
||||
m->unitSize = unitSize;
|
||||
|
||||
m->buckets = malloc(sizeof(UDPC_HashMap_Node*) * m->capacity);
|
||||
if(!m->buckets)
|
||||
{
|
||||
free(m);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for(int x = 0; x < m->capacity; ++x)
|
||||
{
|
||||
if(fail != 0)
|
||||
{
|
||||
m->buckets[x] = NULL;
|
||||
continue;
|
||||
}
|
||||
m->buckets[x] = calloc(1, sizeof(UDPC_HashMap_Node));
|
||||
if(!m->buckets[x])
|
||||
{
|
||||
fail = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if(fail != 0)
|
||||
{
|
||||
for(int x = 0; x < m->capacity; ++x)
|
||||
{
|
||||
if(m->buckets[x])
|
||||
{
|
||||
free(m->buckets[x]);
|
||||
}
|
||||
}
|
||||
free(m->buckets);
|
||||
free(m);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
void UDPC_HashMap_destroy(UDPC_HashMap *hashMap)
|
||||
{
|
||||
UDPC_HashMap_Node *current;
|
||||
UDPC_HashMap_Node *next;
|
||||
for(int x = 0; x < hashMap->capacity; ++x)
|
||||
{
|
||||
current = hashMap->buckets[x];
|
||||
while(current)
|
||||
{
|
||||
next = current->next;
|
||||
if(current->data) { free(current->data); }
|
||||
free(current);
|
||||
current = next;
|
||||
}
|
||||
}
|
||||
free(hashMap->buckets);
|
||||
free(hashMap);
|
||||
}
|
||||
|
||||
void* UDPC_HashMap_insert(UDPC_HashMap *hm, uint32_t key, void *data)
|
||||
{
|
||||
if(hm->capacity <= hm->size)
|
||||
{
|
||||
if(UDPC_HashMap_realloc(hm, hm->capacity * 2) == 0)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t hash = UDPC_HASHMAP_MOD(key, hm->capacity);
|
||||
|
||||
UDPC_HashMap_Node *current = hm->buckets[hash];
|
||||
while(current->next)
|
||||
{
|
||||
current = current->next;
|
||||
}
|
||||
current->next = malloc(sizeof(UDPC_HashMap_Node));
|
||||
current->next->key = key;
|
||||
if(hm->unitSize != 0)
|
||||
{
|
||||
current->next->data = malloc(hm->unitSize);
|
||||
memcpy(current->next->data, data, hm->unitSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
current->next->data = NULL;
|
||||
}
|
||||
current->next->next = NULL;
|
||||
current->next->prev = current;
|
||||
|
||||
++hm->size;
|
||||
return current->next->data;
|
||||
}
|
||||
|
||||
int UDPC_HashMap_remove(UDPC_HashMap *hm, uint32_t key)
|
||||
{
|
||||
if(hm->size == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t hash = UDPC_HASHMAP_MOD(key, hm->capacity);
|
||||
|
||||
UDPC_HashMap_Node *current = hm->buckets[hash]->next;
|
||||
while(current && current->key != key)
|
||||
{
|
||||
current = current->next;
|
||||
}
|
||||
|
||||
if(!current) { return 0; }
|
||||
|
||||
current->prev->next = current->next;
|
||||
if(current->next) { current->next->prev = current->prev; }
|
||||
|
||||
if(current->data) { free(current->data); }
|
||||
free(current);
|
||||
|
||||
--hm->size;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void* UDPC_HashMap_get(UDPC_HashMap *hm, uint32_t key)
|
||||
{
|
||||
if(hm->size == 0)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
uint32_t hash = UDPC_HASHMAP_MOD(key, hm->capacity);
|
||||
|
||||
UDPC_HashMap_Node *current = hm->buckets[hash];
|
||||
while(current && (current == hm->buckets[hash] || current->key != key))
|
||||
{
|
||||
current = current->next;
|
||||
}
|
||||
|
||||
if(!current) { return NULL; }
|
||||
|
||||
return current->data;
|
||||
}
|
||||
|
||||
int UDPC_HashMap_has(UDPC_HashMap *hm, uint32_t key)
|
||||
{
|
||||
if(hm->size == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t hash = UDPC_HASHMAP_MOD(key, hm->capacity);
|
||||
|
||||
UDPC_HashMap_Node *current = hm->buckets[hash];
|
||||
while(current && (current == hm->buckets[hash] || current->key != key))
|
||||
{
|
||||
current = current->next;
|
||||
}
|
||||
|
||||
return current != NULL ? 1 : 0;
|
||||
}
|
||||
|
||||
int UDPC_HashMap_realloc(UDPC_HashMap *hm, uint32_t newCapacity)
|
||||
{
|
||||
if(hm->size > newCapacity)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// allocate newBuckets
|
||||
int fail = 0;
|
||||
UDPC_HashMap_Node **newBuckets = malloc(sizeof(UDPC_HashMap_Node*) * newCapacity);
|
||||
if(!newBuckets) { return 0; }
|
||||
for(int x = 0; x < newCapacity; ++x)
|
||||
{
|
||||
if(fail != 0) { newBuckets[x] = NULL; continue; }
|
||||
newBuckets[x] = calloc(1, sizeof(UDPC_HashMap_Node));
|
||||
if(!newBuckets[x]) { fail = 1; }
|
||||
}
|
||||
if(fail != 0)
|
||||
{
|
||||
for(int x = 0; x < newCapacity; ++x)
|
||||
{
|
||||
if(newBuckets[x]) { free(newBuckets[x]); }
|
||||
}
|
||||
free(newBuckets);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// rehash entries from hm->buckets to newBuckets
|
||||
uint32_t hash;
|
||||
UDPC_HashMap_Node *current;
|
||||
UDPC_HashMap_Node *next;
|
||||
UDPC_HashMap_Node *newCurrent;
|
||||
for(int x = 0; x < hm->capacity; ++x)
|
||||
{
|
||||
current = hm->buckets[x]->next;
|
||||
while(current)
|
||||
{
|
||||
next = current->next;
|
||||
hash = UDPC_HASHMAP_MOD(current->key, newCapacity);
|
||||
newCurrent = newBuckets[hash];
|
||||
while(newCurrent->next)
|
||||
{
|
||||
newCurrent = newCurrent->next;
|
||||
}
|
||||
newCurrent->next = malloc(sizeof(UDPC_HashMap_Node));
|
||||
if(!newCurrent->next)
|
||||
{
|
||||
fail = 1;
|
||||
break;
|
||||
}
|
||||
newCurrent->next->key = current->key;
|
||||
newCurrent->next->data = current->data;
|
||||
newCurrent->next->next = NULL;
|
||||
newCurrent->next->prev = newCurrent;
|
||||
current = next;
|
||||
}
|
||||
if(fail != 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(fail != 0)
|
||||
{
|
||||
for(int x = 0; x < newCapacity; ++x)
|
||||
{
|
||||
current = newBuckets[x];
|
||||
while(current)
|
||||
{
|
||||
next = current->next;
|
||||
free(current);
|
||||
current = next;
|
||||
}
|
||||
}
|
||||
free(newBuckets);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// cleanup hm->buckets to be replaced by newBuckets
|
||||
for(int x = 0; x < hm->capacity; ++x)
|
||||
{
|
||||
current = hm->buckets[x];
|
||||
while(current)
|
||||
{
|
||||
next = current->next;
|
||||
// do not free current->data as it is now being pointed to by entries in newBuckets
|
||||
free(current);
|
||||
current = next;
|
||||
}
|
||||
}
|
||||
free(hm->buckets);
|
||||
|
||||
hm->capacity = newCapacity;
|
||||
hm->buckets = newBuckets;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void UDPC_HashMap_clear(UDPC_HashMap *hm)
|
||||
{
|
||||
UDPC_HashMap_Node *current;
|
||||
UDPC_HashMap_Node *next;
|
||||
for(int x = 0; x < hm->capacity; ++x)
|
||||
{
|
||||
current = hm->buckets[x]->next;
|
||||
while(current)
|
||||
{
|
||||
next = current->next;
|
||||
if(current->data) { free(current->data); }
|
||||
free(current);
|
||||
current = next;
|
||||
}
|
||||
hm->buckets[x]->next = NULL;
|
||||
}
|
||||
hm->size = 0;
|
||||
}
|
||||
|
||||
uint32_t UDPC_HashMap_get_size(UDPC_HashMap *hm)
|
||||
{
|
||||
return hm->size;
|
||||
}
|
||||
|
||||
uint32_t UDPC_HashMap_get_capacity(UDPC_HashMap *hm)
|
||||
{
|
||||
return hm->capacity;
|
||||
}
|
||||
|
||||
void UDPC_HashMap_itercall(UDPC_HashMap *hm, void (*fn)(void*, uint32_t, char*), void *userData)
|
||||
{
|
||||
UDPC_HashMap_Node *current;
|
||||
for(int x = 0; x < hm->capacity; ++x)
|
||||
{
|
||||
current = hm->buckets[x]->next;
|
||||
while(current)
|
||||
{
|
||||
fn(userData, current->key, current->data);
|
||||
current = current->next;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,111 +0,0 @@
|
|||
#ifndef UDPC_HASHMAP_H
|
||||
#define UDPC_HASHMAP_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
// 5 8 2 7 3 6 1
|
||||
// 3 2 5 1 8 7 6
|
||||
#define UDPC_HASH32(x) ( \
|
||||
( \
|
||||
(((x) & 0xF8000000) >> 5) | \
|
||||
(((x) & 0x07F80000) >> 6) | \
|
||||
(((x) & 0x00060000) << 10) | \
|
||||
(((x) & 0x0001FC00) >> 4) | \
|
||||
(((x) & 0x00000380) << 22) | \
|
||||
(((x) & 0x0000007E) >> 1) | \
|
||||
(((x) & 0x00000001) << 21) \
|
||||
) ^ 0x96969696 \
|
||||
)
|
||||
|
||||
#define UDPC_HASHMAP_INIT_CAPACITY 13
|
||||
|
||||
#define UDPC_HASHMAP_MOD(k, m) ((UDPC_HASH32(k) % (m * 2 + 1)) % m)
|
||||
|
||||
struct UDPC_HashMap_Node {
|
||||
uint32_t key;
|
||||
char *data;
|
||||
struct UDPC_HashMap_Node *next;
|
||||
struct UDPC_HashMap_Node *prev;
|
||||
};
|
||||
typedef struct UDPC_HashMap_Node UDPC_HashMap_Node;
|
||||
|
||||
typedef struct {
|
||||
uint32_t size;
|
||||
uint32_t capacity;
|
||||
uint32_t unitSize;
|
||||
UDPC_HashMap_Node **buckets;
|
||||
} UDPC_HashMap;
|
||||
|
||||
/*!
|
||||
* \brief Creates a HashMap structure
|
||||
* Note that UDPC_HashMap_destroy must be called on the returned ptr to free
|
||||
* resources to avoid a memory leak.
|
||||
* \return non-null if creating the HashMap was successful
|
||||
*/
|
||||
UDPC_HashMap* UDPC_HashMap_init(uint32_t capacity, uint32_t unitSize);
|
||||
|
||||
/*!
|
||||
* \brief Releases resources used by a HashMap structure
|
||||
*/
|
||||
void UDPC_HashMap_destroy(UDPC_HashMap *hashMap);
|
||||
|
||||
/*!
|
||||
* \brief Inserts a copy of data pointed to by given pointer
|
||||
* Note if size already equals capacity, the hash map's capacity is doubled
|
||||
* with UDPC_HashMap_realloc(). realloc requires rehashing of all items which
|
||||
* may be costly.
|
||||
* Also, if the hash map runs out of space for a specific key to insert, it will
|
||||
* also invoke realloc() with double the previous capacity and will attempt to
|
||||
* insert again afterwards.
|
||||
* It is possible to insert items with duplicate keys. In that case, the first
|
||||
* duplicate inserted will be the first returned with get() and first removed
|
||||
* with remove().
|
||||
* \return Pointer to inserted data, NULL on fail or unitSize = 0
|
||||
*/
|
||||
void* UDPC_HashMap_insert(UDPC_HashMap *hm, uint32_t key, void *data);
|
||||
|
||||
/*!
|
||||
* \brief Removes data with the given key
|
||||
* \return non-zero if data was successfully removed
|
||||
*/
|
||||
int UDPC_HashMap_remove(UDPC_HashMap *hm, uint32_t key);
|
||||
|
||||
/*!
|
||||
* \brief Returns a pointer to data with the given key
|
||||
* Note if unitSize == 0, then the returned pointer will point to a copy of
|
||||
* its integer key, which should not be changed manually (otherwise, the hash
|
||||
* map would not be able to find it).
|
||||
* \return non-NULL if data was found and unitSize != 0
|
||||
*/
|
||||
void* UDPC_HashMap_get(UDPC_HashMap *hm, uint32_t key);
|
||||
|
||||
/*!
|
||||
* \return non-zero if item with specified key is in the hash map
|
||||
*/
|
||||
int UDPC_HashMap_has(UDPC_HashMap *hm, uint32_t key);
|
||||
|
||||
/*!
|
||||
* \brief Resizes the maximum capacity of a hash map
|
||||
* Note on fail, the hash map is unchanged.
|
||||
* If newCapacity is less than the current size of the hash map, this function
|
||||
* will fail.
|
||||
* \return non-zero if resizing was successful
|
||||
*/
|
||||
int UDPC_HashMap_realloc(UDPC_HashMap *hm, uint32_t newCapacity);
|
||||
|
||||
/*!
|
||||
* \brief Empties the hash map
|
||||
*/
|
||||
void UDPC_HashMap_clear(UDPC_HashMap *hm);
|
||||
|
||||
uint32_t UDPC_HashMap_get_size(UDPC_HashMap *hm);
|
||||
|
||||
uint32_t UDPC_HashMap_get_capacity(UDPC_HashMap *hm);
|
||||
|
||||
/*!
|
||||
* \brief Calls a fn with a ptr to each entry in the hash map
|
||||
* The fn is called with userData, entry key, and entry data.
|
||||
*/
|
||||
void UDPC_HashMap_itercall(UDPC_HashMap *hm, void (*fn)(void*, uint32_t, char*), void *userData);
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load diff
|
@ -1,325 +0,0 @@
|
|||
#ifndef UDPCONNECTION_H
|
||||
#define UDPCONNECTION_H
|
||||
|
||||
/*!
|
||||
* Any function or struct starting with "UDPC_INTERNAL" should never be used,
|
||||
* as they are used internally by this library.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <threads.h>
|
||||
#include <time.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "UDPC_Defines.h"
|
||||
#include "UDPC_Deque.h"
|
||||
#include "UDPC_HashMap.h"
|
||||
|
||||
#if UDPC_PLATFORM == UDPC_PLATFORM_WINDOWS
|
||||
#include <winsock2.h>
|
||||
|
||||
#define CleanupSocket(x) closesocket(x)
|
||||
#elif UDPC_PLATFORM == UDPC_PLATFORM_MAC || UDPC_PLATFORM == UDPC_PLATFORM_LINUX
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define CleanupSocket(x) close(x)
|
||||
#else
|
||||
#define CleanupSocket(x) ((void)0)
|
||||
#endif
|
||||
|
||||
#define UDPC_ATOSTR_BUF_SIZE 16
|
||||
|
||||
/// (void *userData, uint32_t address)
|
||||
/*!
|
||||
* Note address is in network byte order (usually big-endian)
|
||||
*/
|
||||
typedef void (*UDPC_callback_connected)(void*, uint32_t);
|
||||
|
||||
/// (void *userData, uint32_t address)
|
||||
/*!
|
||||
* Note address is in network byte order (usually big-endian)
|
||||
*/
|
||||
typedef void (*UDPC_callback_disconnected)(void*, uint32_t);
|
||||
|
||||
/// (void *userData, uint32_t address, char *packetData, uint32_t packetSize)
|
||||
/*!
|
||||
* The data pointed to by the packetData argument is to data internally managed
|
||||
* by the UDPC_Context. It will change every time this callback is called so do
|
||||
* not depend on it persisting. This means you should copy the data out of it
|
||||
* when the callback is invoked and work with the copied data.
|
||||
*/
|
||||
typedef void (*UDPC_callback_received)(void*, uint32_t, char*, uint32_t);
|
||||
|
||||
/// This struct should not be used outside of this library
|
||||
typedef struct {
|
||||
uint32_t addr; // in network order (big-endian)
|
||||
uint32_t id;
|
||||
/*
|
||||
* 0x1 - is resending
|
||||
* 0x2 - is check received packet
|
||||
* 0x4 - has been re-sent
|
||||
* 0x8 - initiate connection packet
|
||||
*/
|
||||
uint32_t flags;
|
||||
char *data; // no-header in sendPktQueue and receivedPackets, header in sentPkts
|
||||
uint32_t size;
|
||||
struct timespec sent;
|
||||
} UDPC_INTERNAL_PacketInfo;
|
||||
|
||||
/// This struct should not be used outside of this library
|
||||
typedef struct {
|
||||
/*
|
||||
* 0x1 - trigger send
|
||||
* 0x2 - is good mode
|
||||
* 0x4 - is good rtt
|
||||
* 0x8 - initiating connection to server
|
||||
* 0x10 - is id set
|
||||
*/
|
||||
uint32_t flags;
|
||||
uint32_t id;
|
||||
uint32_t lseq;
|
||||
uint32_t rseq;
|
||||
uint32_t ack;
|
||||
float timer;
|
||||
float toggleT;
|
||||
float toggleTimer;
|
||||
float toggledTimer;
|
||||
uint32_t addr; // in network order (big-endian)
|
||||
uint16_t port;
|
||||
UDPC_Deque *sentPkts;
|
||||
UDPC_Deque *sendPktQueue;
|
||||
UDPC_Deque *priorityPktQueue;
|
||||
struct timespec received;
|
||||
struct timespec sent;
|
||||
float rtt;
|
||||
} UDPC_INTERNAL_ConnectionData;
|
||||
|
||||
/// This struct should not be used externally, only passed to functions that require it
|
||||
typedef struct {
|
||||
int isThreaded;
|
||||
/*
|
||||
* 0x1 - unused
|
||||
* 0x2 - is client
|
||||
* 0x4 - log errors
|
||||
* 0x8 - log warnings
|
||||
* 0x10 - log info
|
||||
* 0x20 - log verbose
|
||||
* 0x40 - accept new connections
|
||||
*/
|
||||
uint32_t flags;
|
||||
/*
|
||||
* 0x1 - thread should stop
|
||||
*/
|
||||
uint32_t threadFlags;
|
||||
uint32_t protocolID;
|
||||
uint32_t error;
|
||||
int socketHandle;
|
||||
struct sockaddr_in socketInfo;
|
||||
thrd_t threadHandle;
|
||||
mtx_t tCVMtx;
|
||||
mtx_t tflagsMtx;
|
||||
cnd_t threadCV;
|
||||
UDPC_HashMap *conMap;
|
||||
// Clients intentionally do not use idMap at all
|
||||
UDPC_HashMap *idMap;
|
||||
struct timespec lastUpdated;
|
||||
char atostrBuf[UDPC_ATOSTR_BUF_SIZE];
|
||||
char recvBuf[UDPC_PACKET_MAX_SIZE];
|
||||
UDPC_Deque *connectedEvents;
|
||||
UDPC_Deque *disconnectedEvents;
|
||||
UDPC_Deque *receivedPackets;
|
||||
|
||||
UDPC_callback_connected callbackConnected;
|
||||
void *callbackConnectedUserData;
|
||||
UDPC_callback_disconnected callbackDisconnected;
|
||||
void *callbackDisconnectedUserData;
|
||||
UDPC_callback_received callbackReceived;
|
||||
void *callbackReceivedUserData;
|
||||
} UDPC_Context;
|
||||
|
||||
/// This struct should not be used outside of this library
|
||||
typedef struct {
|
||||
struct timespec tsNow;
|
||||
float dt;
|
||||
UDPC_Deque *removedQueue;
|
||||
UDPC_Context *ctx;
|
||||
} UDPC_INTERNAL_update_struct;
|
||||
|
||||
/// Creates a new UDPC_Context, for establishing a connection via UDP
|
||||
/*!
|
||||
* Callbacks must be set to use UDPC effectively, using the following functions:
|
||||
* - UDPC_set_callback_connected()
|
||||
* - UDPC_set_callback_disconnected()
|
||||
* - UDPC_set_callback_received()
|
||||
*
|
||||
* Clients should also use UDPC_client_initiate_connection() to let UDPC know
|
||||
* what server to connect to.
|
||||
*
|
||||
* UDPC_update() must be called periodically (ideally at 30 updates per second
|
||||
* or faster), to send and receive UDP packets, and establish new connections
|
||||
* when enabled. An init variant "UDPC_init_threaded_update()" is available
|
||||
* which will call update periodically on a separate thread.
|
||||
*
|
||||
* UDPC_check_events() must also be called to call the set callbacks for
|
||||
* connected, disconnected, and received events.
|
||||
*
|
||||
* When finished using UDPC, UDPC_destroy must be called on the context to free
|
||||
* resources.
|
||||
*/
|
||||
UDPC_Context* UDPC_init(uint16_t listenPort, uint32_t listenAddr, int isClient);
|
||||
|
||||
/// Creates a new UDPC_Context, where a thread is created to update UDPC on its own
|
||||
/*!
|
||||
* If using a UDPC_Context created by this init variant, UDPC_update() must not
|
||||
* be manually called, as it is called automatically by a separate thread.
|
||||
*
|
||||
* See the documentation for UDPC_init() for more details.
|
||||
*/
|
||||
UDPC_Context* UDPC_init_threaded_update(uint16_t listenPort, uint32_t listenAddr, int isClient);
|
||||
|
||||
/// This fn must be called on a UDPC_Context to free resources
|
||||
void UDPC_destroy(UDPC_Context *ctx);
|
||||
|
||||
void UDPC_INTERNAL_destroy_conMap(void *unused, uint32_t addr, char *data);
|
||||
|
||||
/// Sets the callback for connected events
|
||||
void UDPC_set_callback_connected(
|
||||
UDPC_Context *ctx, UDPC_callback_connected fptr, void *userData);
|
||||
|
||||
/// Sets the callback for disconnected events
|
||||
void UDPC_set_callback_disconnected(
|
||||
UDPC_Context *ctx, UDPC_callback_disconnected fptr, void *userData);
|
||||
|
||||
/// Sets the callback for received packet events
|
||||
void UDPC_set_callback_received(
|
||||
UDPC_Context *ctx, UDPC_callback_received fptr, void *userData);
|
||||
|
||||
/// Invokes callbacks based on events that have ocurred during UDPC_update()
|
||||
void UDPC_check_events(UDPC_Context *ctx);
|
||||
|
||||
/// Tells UDPC to initiate a connection to a server
|
||||
void UDPC_client_initiate_connection(UDPC_Context *ctx, uint32_t addr, uint16_t port);
|
||||
|
||||
/*!
|
||||
* \brief Queues a packet to send to a connected peer
|
||||
* Note addr is expected to be in network-byte-order (big-endian).
|
||||
* If isChecked is non-zero, UDPC will attempt to resend the packet if peer has
|
||||
* not received it within UDPC_PACKET_TIMEOUT_SEC seconds.
|
||||
* \return non-zero on success
|
||||
*/
|
||||
int UDPC_queue_send(
|
||||
UDPC_Context *ctx, uint32_t addr, uint32_t isChecked, void *data, uint32_t size);
|
||||
|
||||
/*!
|
||||
* \brief get the number of packets that can be queued to the addr
|
||||
* \return number of queueable packets or 0 if connection has not been established
|
||||
*/
|
||||
int UDPC_get_queue_send_available(UDPC_Context *ctx, uint32_t addr);
|
||||
|
||||
/// Returns non-zero if UDPC is accepting new connections
|
||||
int UDPC_get_accept_new_connections(UDPC_Context *ctx);
|
||||
|
||||
/// Set isAccepting to non-zero to let UDPC accept new connections
|
||||
/*!
|
||||
* Set isAccepting to zero to prevent UDPC from accepting new connections.
|
||||
*/
|
||||
void UDPC_set_accept_new_connections(UDPC_Context *ctx, int isAccepting);
|
||||
|
||||
/// Drops a connection specified by addr
|
||||
/*!
|
||||
* \return non-zero if the connection existed and was dropped
|
||||
*/
|
||||
int UDPC_drop_connection(UDPC_Context *ctx, uint32_t addr);
|
||||
|
||||
/// Gets the currently set protocol id
|
||||
uint32_t UDPC_get_protocol_id(UDPC_Context *ctx);
|
||||
|
||||
/// Sets the protocol id
|
||||
/*!
|
||||
* Note that UDPC can only connect to other UDPC instances that use the same
|
||||
* protocol id.
|
||||
*/
|
||||
void UDPC_set_protocol_id(UDPC_Context *ctx, uint32_t id);
|
||||
|
||||
/*!
|
||||
* \brief Get the currently set error code, and clear it internally
|
||||
* Error codes and their meanings are defined in UDPC_Defines.h .
|
||||
* Use UDPC_get_error_str() to get a string describing the error.
|
||||
*/
|
||||
uint32_t UDPC_get_error(UDPC_Context *ctx);
|
||||
|
||||
/// Returns a string describing the error code for UDPC
|
||||
const char* UDPC_get_error_str(uint32_t error);
|
||||
|
||||
/*!
|
||||
* 0 - log nothing
|
||||
* 1 - log only errors
|
||||
* 2 - log only errors and warnings
|
||||
* 3 - log errors, warnings, and info
|
||||
* 4+ - log everything
|
||||
*
|
||||
* By default, erros and warnings are logged.
|
||||
*/
|
||||
void UDPC_set_logging_type(UDPC_Context *ctx, uint32_t logType);
|
||||
|
||||
/// If threaded, this function is called automatically
|
||||
void UDPC_update(UDPC_Context *ctx);
|
||||
|
||||
void UDPC_INTERNAL_update_to_rtt_si(void *userData, uint32_t addr, char *data);
|
||||
|
||||
void UDPC_INTERNAL_update_send(void *userData, uint32_t addr, char *data);
|
||||
|
||||
void UDPC_INTERNAL_update_rtt(
|
||||
UDPC_Context *ctx,
|
||||
UDPC_INTERNAL_ConnectionData *cd,
|
||||
uint32_t rseq,
|
||||
struct timespec *tsNow);
|
||||
|
||||
void UDPC_INTERNAL_check_pkt_timeout(
|
||||
UDPC_Context *ctx,
|
||||
UDPC_INTERNAL_ConnectionData *cd,
|
||||
uint32_t rseq,
|
||||
uint32_t ack,
|
||||
struct timespec *tsNow);
|
||||
|
||||
float UDPC_INTERNAL_ts_diff(struct timespec *ts0, struct timespec *ts1);
|
||||
|
||||
int UDPC_INTERNAL_threadfn(void *context);
|
||||
|
||||
/*
|
||||
* 0x1 - is ping
|
||||
* 0x2 - is resending
|
||||
* 0x4 - is checked received packet
|
||||
* 0x8 - is init connection packet
|
||||
*/
|
||||
void UDPC_INTERNAL_prepare_pkt(
|
||||
void *data,
|
||||
uint32_t protocolID,
|
||||
uint32_t conID,
|
||||
uint32_t rseq,
|
||||
uint32_t ack,
|
||||
uint32_t *seqID,
|
||||
int flags);
|
||||
|
||||
/*!
|
||||
* 0 - error
|
||||
* 1 - warning
|
||||
* 2 - info
|
||||
* 3 - verbose
|
||||
*/
|
||||
void UDPC_INTERNAL_log(UDPC_Context *ctx, uint32_t level, const char *msg, ...);
|
||||
|
||||
char* UDPC_INTERNAL_atostr(UDPC_Context *ctx, uint32_t addr);
|
||||
|
||||
uint32_t UDPC_INTERNAL_generate_id(UDPC_Context *ctx);
|
||||
|
||||
/*1
|
||||
* \brief Converts a IPV4 string to a 32-bit unsigned integer address in big-endian
|
||||
* \return 0 if string is invalid, address in big-endian format otherwise
|
||||
*/
|
||||
uint32_t UDPC_strtoa(const char *addrStr);
|
||||
|
||||
#endif
|
|
@ -1,163 +0,0 @@
|
|||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <threads.h>
|
||||
|
||||
#include <UDPConnection.h>
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int isConnected;
|
||||
int hasConnectedOnce;
|
||||
uint32_t addr;
|
||||
} TestContext;
|
||||
|
||||
void printUsage()
|
||||
{
|
||||
printf("Usage: [-c] [-t] -a <addr> -p <target_port> -l <listen_port>"
|
||||
" [-d <listen_address>]\n");
|
||||
}
|
||||
|
||||
void conCallback(void *userdata, uint32_t addr)
|
||||
{
|
||||
TestContext *ctx = userdata;
|
||||
ctx->isConnected = 1;
|
||||
ctx->hasConnectedOnce = 1;
|
||||
ctx->addr = addr;
|
||||
printf("Connected callback called\n");
|
||||
}
|
||||
|
||||
void discCallback(void *userdata, uint32_t addr)
|
||||
{
|
||||
TestContext *ctx = userdata;
|
||||
ctx->isConnected = 0;
|
||||
printf("Disconnected callback called\n");
|
||||
}
|
||||
|
||||
void recCallback(void *userdata, uint32_t addr, char *data, uint32_t size)
|
||||
{
|
||||
TestContext *ctx = userdata;
|
||||
if(ctx->addr == addr && size == 7 && data[6] == '\0')
|
||||
{
|
||||
printf("Got %s\n", data);
|
||||
}
|
||||
}
|
||||
|
||||
void updateSendBuffer(uint32_t *index, char *buffer)
|
||||
{
|
||||
++(*index);
|
||||
if(*index >= 26 * 26 * 26 * 26 * 26 * 26)
|
||||
{
|
||||
*index = 0;
|
||||
}
|
||||
|
||||
uint32_t temp = 1;
|
||||
for(int x = 0; x < 6; ++x)
|
||||
{
|
||||
buffer[x] = (*index / temp) % 26 + 'a';
|
||||
temp *= 26;
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
int isClient = 0;
|
||||
int isThreaded = 0;
|
||||
uint32_t targetAddress = 0;
|
||||
uint16_t targetPort = 0;
|
||||
uint32_t listenAddress = 0;
|
||||
uint16_t listenPort = 0;
|
||||
TestContext testCtx = {0, 0};
|
||||
|
||||
uint32_t sendIndex = 0;
|
||||
char sendBuffer[7] = {
|
||||
'a', 'a', 'a',
|
||||
'a', 'a', 'a',
|
||||
'\0'
|
||||
};
|
||||
|
||||
--argc; ++argv;
|
||||
while(argc > 0)
|
||||
{
|
||||
if(strcmp("-c", argv[0]) == 0)
|
||||
{
|
||||
isClient = 1;
|
||||
}
|
||||
else if(strcmp("-t", argv[0]) == 0)
|
||||
{
|
||||
isThreaded = 1;
|
||||
}
|
||||
else if(strcmp("-a", argv[0]) == 0 && argc > 1)
|
||||
{
|
||||
targetAddress = UDPC_strtoa(argv[1]);
|
||||
--argc; ++argv;
|
||||
}
|
||||
else if(strcmp("-p", argv[0]) == 0 && argc > 1)
|
||||
{
|
||||
targetPort = strtoul(argv[1], NULL, 10);
|
||||
--argc; ++argv;
|
||||
}
|
||||
else if(strcmp("-l", argv[0]) == 0 && argc > 1)
|
||||
{
|
||||
listenPort = strtoul(argv[1], NULL, 10);
|
||||
--argc; ++argv;
|
||||
}
|
||||
else if(strcmp("-d", argv[0]) == 0 && argc > 1)
|
||||
{
|
||||
listenAddress = UDPC_strtoa(argv[1]);
|
||||
--argc; ++argv;
|
||||
}
|
||||
else if(strcmp("-h", argv[0]) == 0 || strcmp("--help", argv[0]) == 0)
|
||||
{
|
||||
printUsage();
|
||||
return 0;
|
||||
}
|
||||
--argc; ++argv;
|
||||
}
|
||||
|
||||
UDPC_Context *ctx;
|
||||
if(isThreaded == 0)
|
||||
{
|
||||
ctx = UDPC_init(listenPort, listenAddress, isClient);
|
||||
}
|
||||
else
|
||||
{
|
||||
ctx = UDPC_init_threaded_update(listenPort, listenAddress, isClient);
|
||||
}
|
||||
|
||||
printf("isClient: %s, targetAddr: %s, targetPort: %u, listenPort: %u\n",
|
||||
isClient == 0 ? "false" : "true",
|
||||
UDPC_INTERNAL_atostr(ctx, targetAddress),
|
||||
targetPort,
|
||||
listenPort);
|
||||
|
||||
if(UDPC_get_error(ctx) == UDPC_SUCCESS)
|
||||
{
|
||||
UDPC_set_logging_type(ctx, 4);
|
||||
UDPC_set_callback_connected(ctx, conCallback, &testCtx);
|
||||
UDPC_set_callback_disconnected(ctx, discCallback, &testCtx);
|
||||
UDPC_set_callback_received(ctx, recCallback, &testCtx);
|
||||
while(UDPC_get_error(ctx) == UDPC_SUCCESS)
|
||||
{
|
||||
if(isClient && testCtx.isConnected == 0)
|
||||
{
|
||||
UDPC_client_initiate_connection(ctx, targetAddress, targetPort);
|
||||
}
|
||||
if(isThreaded == 0) { UDPC_update(ctx); }
|
||||
UDPC_check_events(ctx);
|
||||
if(testCtx.isConnected != 0 && UDPC_get_queue_send_available(ctx, testCtx.addr) > 0)
|
||||
{
|
||||
UDPC_queue_send(ctx, testCtx.addr, 0, sendBuffer, 7);
|
||||
updateSendBuffer(&sendIndex, sendBuffer);
|
||||
}
|
||||
thrd_sleep(&(struct timespec){0, 16666666}, NULL);
|
||||
if(testCtx.hasConnectedOnce != 0 && testCtx.isConnected == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
UDPC_destroy(ctx);
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -1,419 +0,0 @@
|
|||
#include "UDPC_UnitTest.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <UDPC_Deque.h>
|
||||
#include <UDPC_HashMap.h>
|
||||
#include <UDPConnection.h>
|
||||
|
||||
static UnitTestState UDPC_uts = {0, 0};
|
||||
|
||||
void TEST_DEQUE()
|
||||
{
|
||||
int arr[32];
|
||||
char *temp = NULL;
|
||||
uint32_t size;
|
||||
for(int x = 0; x < 32; ++x)
|
||||
{
|
||||
arr[x] = x;
|
||||
}
|
||||
UDPC_Deque *deque;
|
||||
|
||||
// init
|
||||
deque = UDPC_Deque_init(sizeof(int) * 32);
|
||||
ASSERT_TRUE(deque);
|
||||
ASSERT_TRUE(deque->buf);
|
||||
ASSERT_EQ(deque->head, 0);
|
||||
ASSERT_EQ(deque->tail, 0);
|
||||
ASSERT_EQ(deque->size, 0);
|
||||
ASSERT_EQ(deque->alloc_size, sizeof(int) * 32);
|
||||
|
||||
// realloc smaller success
|
||||
ASSERT_TRUE(UDPC_Deque_realloc(deque, sizeof(int) * 16));
|
||||
ASSERT_TRUE(deque->buf);
|
||||
ASSERT_EQ(deque->head, 0);
|
||||
ASSERT_EQ(deque->tail, 0);
|
||||
ASSERT_EQ(deque->size, 0);
|
||||
ASSERT_EQ(deque->alloc_size, sizeof(int) * 16);
|
||||
|
||||
// push back success
|
||||
ASSERT_TRUE(UDPC_Deque_push_back(deque, arr, sizeof(int) * 4));
|
||||
ASSERT_EQ_MEM(arr, deque->buf, sizeof(int) * 4);
|
||||
ASSERT_EQ_MEM(arr, UDPC_Deque_get_back_ptr(deque, sizeof(int) * 4), sizeof(int) * 4);
|
||||
ASSERT_EQ_MEM(arr, UDPC_Deque_get_front_ptr(deque, sizeof(int) * 4), sizeof(int) * 4);
|
||||
for(int x = 0; x < 4; ++x)
|
||||
{
|
||||
ASSERT_EQ_MEM(&arr[x], UDPC_Deque_index_ptr(deque, sizeof(int), x), sizeof(int));
|
||||
ASSERT_EQ_MEM(&arr[3 - x], UDPC_Deque_index_rev_ptr(deque, sizeof(int), x), sizeof(int));
|
||||
}
|
||||
ASSERT_EQ(deque->size, sizeof(int) * 4);
|
||||
|
||||
// push front success
|
||||
ASSERT_TRUE(UDPC_Deque_push_front(deque, &arr[4], sizeof(int) * 4));
|
||||
ASSERT_EQ_MEM(&arr[4], &deque->buf[sizeof(int) * 12], sizeof(int) * 4);
|
||||
ASSERT_EQ_MEM(arr, UDPC_Deque_get_back_ptr(deque, sizeof(int) * 4), sizeof(int) * 4);
|
||||
ASSERT_EQ_MEM(&arr[4], UDPC_Deque_get_front_ptr(deque, sizeof(int) * 4), sizeof(int) * 4);
|
||||
for(int x = 0; x < 4; ++x)
|
||||
{
|
||||
ASSERT_EQ_MEM(&arr[x + 4], UDPC_Deque_index_ptr(deque, sizeof(int), x), sizeof(int));
|
||||
ASSERT_EQ_MEM(&arr[x], UDPC_Deque_index_ptr(deque, sizeof(int), x + 4), sizeof(int));
|
||||
ASSERT_EQ_MEM(&arr[3 - x], UDPC_Deque_index_rev_ptr(deque, sizeof(int), x), sizeof(int));
|
||||
ASSERT_EQ_MEM(&arr[7 - x], UDPC_Deque_index_rev_ptr(deque, sizeof(int), x + 4), sizeof(int));
|
||||
}
|
||||
ASSERT_EQ(deque->size, sizeof(int) * 8);
|
||||
|
||||
// realloc bigger success
|
||||
ASSERT_TRUE(UDPC_Deque_realloc(deque, sizeof(int) * 32));
|
||||
ASSERT_EQ_MEM(&arr[4], deque->buf, sizeof(int) * 4);
|
||||
ASSERT_EQ_MEM(arr, &deque->buf[sizeof(int) * 4], sizeof(int) * 4);
|
||||
ASSERT_EQ(deque->alloc_size, sizeof(int) * 32);
|
||||
|
||||
// pop front success
|
||||
UDPC_Deque_pop_front(deque, sizeof(int) * 4);
|
||||
ASSERT_EQ(deque->size, sizeof(int) * 4);
|
||||
|
||||
// get front success
|
||||
size = sizeof(int) * 4;
|
||||
ASSERT_TRUE(UDPC_Deque_get_front(deque, (void**)&temp, &size));
|
||||
ASSERT_EQ(size, sizeof(int) * 4);
|
||||
ASSERT_EQ_MEM(arr, temp, size);
|
||||
free(temp);
|
||||
|
||||
// pop back success
|
||||
UDPC_Deque_pop_back(deque, sizeof(int) * 4);
|
||||
ASSERT_EQ(deque->size, 0);
|
||||
|
||||
// push front success
|
||||
ASSERT_TRUE(UDPC_Deque_push_front(deque, arr, sizeof(int) * 16));
|
||||
ASSERT_EQ(deque->size, sizeof(int) * 16);
|
||||
|
||||
// get front success
|
||||
size = sizeof(int) * 16;
|
||||
ASSERT_TRUE(UDPC_Deque_get_front(deque, (void**)&temp, &size));
|
||||
ASSERT_EQ(size, sizeof(int) * 16);
|
||||
ASSERT_EQ_MEM(arr, temp, size);
|
||||
free(temp);
|
||||
|
||||
// get back success
|
||||
size = sizeof(int) * 16;
|
||||
ASSERT_TRUE(UDPC_Deque_get_back(deque, (void**)&temp, &size));
|
||||
ASSERT_EQ(size, sizeof(int) * 16);
|
||||
ASSERT_EQ_MEM(arr, temp, size);
|
||||
free(temp);
|
||||
|
||||
// realloc smaller fail
|
||||
ASSERT_FALSE(UDPC_Deque_realloc(deque, sizeof(int) * 8));
|
||||
ASSERT_EQ(deque->size, sizeof(int) * 16);
|
||||
ASSERT_EQ(deque->alloc_size, sizeof(int) * 32);
|
||||
|
||||
// realloc smaller success
|
||||
ASSERT_TRUE(UDPC_Deque_realloc(deque, sizeof(int) * 16));
|
||||
ASSERT_EQ(deque->size, sizeof(int) * 16);
|
||||
ASSERT_EQ(deque->alloc_size, sizeof(int) * 16);
|
||||
ASSERT_EQ_MEM(deque->buf, arr, sizeof(int) * 16);
|
||||
|
||||
// push back fail
|
||||
ASSERT_FALSE(UDPC_Deque_push_back(deque, arr, sizeof(int) * 16));
|
||||
ASSERT_EQ(deque->size, sizeof(int) * 16);
|
||||
ASSERT_EQ(deque->alloc_size, sizeof(int) * 16);
|
||||
ASSERT_EQ_MEM(deque->buf, arr, sizeof(int) * 16);
|
||||
|
||||
// push front fail
|
||||
ASSERT_FALSE(UDPC_Deque_push_back(deque, arr, sizeof(int) * 16));
|
||||
ASSERT_EQ(deque->size, sizeof(int) * 16);
|
||||
ASSERT_EQ(deque->alloc_size, sizeof(int) * 16);
|
||||
ASSERT_EQ_MEM(deque->buf, arr, sizeof(int) * 16);
|
||||
|
||||
// pop back
|
||||
UDPC_Deque_pop_back(deque, sizeof(int) * 8);
|
||||
|
||||
// get front success
|
||||
size = sizeof(int) * 8;
|
||||
ASSERT_TRUE(UDPC_Deque_get_front(deque, (void**)&temp, &size));
|
||||
ASSERT_EQ(size, sizeof(int) * 8);
|
||||
ASSERT_EQ_MEM(temp, arr, sizeof(int) * 8);
|
||||
free(temp);
|
||||
|
||||
// get front fail
|
||||
size = sizeof(int) * 16;
|
||||
ASSERT_FALSE(UDPC_Deque_get_front(deque, (void**)&temp, &size));
|
||||
ASSERT_EQ(size, sizeof(int) * 8);
|
||||
ASSERT_EQ_MEM(temp, arr, sizeof(int) * 8);
|
||||
free(temp);
|
||||
|
||||
// get back success
|
||||
size = sizeof(int) * 8;
|
||||
ASSERT_TRUE(UDPC_Deque_get_back(deque, (void**)&temp, &size));
|
||||
ASSERT_EQ(size, sizeof(int) * 8);
|
||||
ASSERT_EQ_MEM(temp, arr, sizeof(int) * 8);
|
||||
free(temp);
|
||||
|
||||
// get back fail
|
||||
size = sizeof(int) * 16;
|
||||
ASSERT_FALSE(UDPC_Deque_get_back(deque, (void**)&temp, &size));
|
||||
ASSERT_EQ(size, sizeof(int) * 8);
|
||||
ASSERT_EQ_MEM(temp, arr, sizeof(int) * 8);
|
||||
free(temp);
|
||||
|
||||
// index success
|
||||
for(int x = 0; x < 8; ++x)
|
||||
{
|
||||
ASSERT_TRUE(UDPC_Deque_index(deque, sizeof(int), x, (void**)&temp));
|
||||
if(temp)
|
||||
{
|
||||
ASSERT_EQ_MEM(temp, &arr[x], sizeof(int));
|
||||
free(temp);
|
||||
}
|
||||
}
|
||||
|
||||
// index fail
|
||||
ASSERT_FALSE(UDPC_Deque_index(deque, sizeof(int), 8, (void**)&temp));
|
||||
ASSERT_FALSE(temp);
|
||||
|
||||
// index_rev success
|
||||
for(int x = 0; x < 8; ++x)
|
||||
{
|
||||
ASSERT_TRUE(UDPC_Deque_index_rev(deque, sizeof(int), x, (void**)&temp));
|
||||
if(temp)
|
||||
{
|
||||
ASSERT_EQ_MEM(temp, &arr[7 - x], sizeof(int));
|
||||
free(temp);
|
||||
}
|
||||
}
|
||||
|
||||
// index_rev fail
|
||||
ASSERT_FALSE(UDPC_Deque_index_rev(deque, sizeof(int), 8, (void**)&temp));
|
||||
ASSERT_FALSE(temp);
|
||||
|
||||
// remove success front
|
||||
ASSERT_TRUE(UDPC_Deque_remove(deque, sizeof(int), 0));
|
||||
ASSERT_EQ(sizeof(int) * 7, deque->size);
|
||||
ASSERT_EQ_MEM(deque->buf, &arr[7], sizeof(int));
|
||||
|
||||
// remove success end
|
||||
ASSERT_TRUE(UDPC_Deque_remove(deque, sizeof(int), 6));
|
||||
ASSERT_EQ(sizeof(int) * 6, deque->size);
|
||||
ASSERT_EQ_MEM(&deque->buf[deque->tail - sizeof(int)], &arr[5], sizeof(int));
|
||||
|
||||
// remove success middle
|
||||
ASSERT_TRUE(UDPC_Deque_remove(deque, sizeof(int), 2));
|
||||
ASSERT_EQ(sizeof(int) * 5, deque->size);
|
||||
ASSERT_EQ_MEM(&deque->buf[deque->head + sizeof(int) * 2], &arr[5], sizeof(int));
|
||||
|
||||
// remove success until empty
|
||||
while(deque->size > 0)
|
||||
{
|
||||
ASSERT_TRUE(UDPC_Deque_remove(deque, sizeof(int), 0));
|
||||
}
|
||||
ASSERT_EQ(deque->size, 0);
|
||||
|
||||
// test push_back_realloc
|
||||
ASSERT_EQ(deque->alloc_size, 16 * sizeof(int));
|
||||
for(int x = 0; x < 16; ++x)
|
||||
{
|
||||
ASSERT_NEQ(UDPC_Deque_push_back(deque, &x, sizeof(int)), 0);
|
||||
}
|
||||
int tempInt = 20;
|
||||
ASSERT_EQ(UDPC_Deque_push_back(deque, &tempInt, sizeof(int)), 0);
|
||||
ASSERT_NEQ(UDPC_Deque_push_back_realloc(deque, &tempInt, sizeof(int)), 0);
|
||||
ASSERT_EQ(deque->alloc_size, 32 * sizeof(int));
|
||||
ASSERT_EQ_MEM(UDPC_Deque_get_back_ptr(deque, sizeof(int)), &tempInt, sizeof(int));
|
||||
|
||||
UDPC_Deque_pop_back(deque, sizeof(int));
|
||||
ASSERT_NEQ(UDPC_Deque_realloc(deque, 16 * sizeof(int)), 0);
|
||||
|
||||
// test push_front_realloc
|
||||
ASSERT_EQ(UDPC_Deque_push_front(deque, &tempInt, sizeof(int)), 0);
|
||||
ASSERT_NEQ(UDPC_Deque_push_front_realloc(deque, &tempInt, sizeof(int)), 0);
|
||||
ASSERT_EQ(deque->alloc_size, 32 * sizeof(int));
|
||||
ASSERT_EQ_MEM(UDPC_Deque_get_front_ptr(deque, sizeof(int)), &tempInt, sizeof(int));
|
||||
|
||||
/*
|
||||
for(int x = 0; x < deque->tail / sizeof(int); ++x)
|
||||
{
|
||||
temp = &deque->buf[x * sizeof(int)];
|
||||
printf("%d: %d ", x, *((int*)temp));
|
||||
}
|
||||
printf("\n");
|
||||
printf("asize %d, size %d, head %d, tail %d\n",
|
||||
deque->alloc_size, deque->size, deque->head, deque->tail);
|
||||
*/
|
||||
|
||||
UDPC_Deque_destroy(deque);
|
||||
UNITTEST_REPORT(DEQUE)
|
||||
}
|
||||
|
||||
void TEST_ATOSTR()
|
||||
{
|
||||
UDPC_Context ctx;
|
||||
ASSERT_EQ_MEM(
|
||||
UDPC_INTERNAL_atostr(&ctx, (0xFF << 24) | (0x1 << 16) | (0x1E << 8) | 0xAC),
|
||||
"172.30.1.255",
|
||||
13);
|
||||
UNITTEST_REPORT(ATOSTR);
|
||||
}
|
||||
|
||||
void TEST_HASHMAP_itercall_comp(void *userData, uint32_t key, char *data)
|
||||
{
|
||||
*((int*)userData) += 1;
|
||||
int temp = *((int*)(data)) / 100;
|
||||
ASSERT_EQ(temp, key);
|
||||
}
|
||||
|
||||
void TEST_HASHMAP()
|
||||
{
|
||||
UDPC_HashMap *hm = UDPC_HashMap_init(0, sizeof(int));
|
||||
int temp;
|
||||
|
||||
temp = 1333;
|
||||
ASSERT_NEQ(UDPC_HashMap_insert(hm, 0, &temp), NULL);
|
||||
ASSERT_EQ_MEM(UDPC_HashMap_get(hm, 0), &temp, sizeof(int));
|
||||
ASSERT_NEQ(UDPC_HashMap_has(hm, 0), 0);
|
||||
ASSERT_EQ(UDPC_HashMap_has(hm, 1), 0);
|
||||
|
||||
temp = 9999;
|
||||
ASSERT_NEQ(UDPC_HashMap_insert(hm, 1, &temp), NULL);
|
||||
ASSERT_EQ_MEM(UDPC_HashMap_get(hm, 1), &temp, sizeof(int));
|
||||
ASSERT_NEQ(UDPC_HashMap_has(hm, 0), 0);
|
||||
ASSERT_NEQ(UDPC_HashMap_has(hm, 1), 0);
|
||||
ASSERT_EQ(UDPC_HashMap_has(hm, 2), 0);
|
||||
|
||||
temp = 1235987;
|
||||
ASSERT_NEQ(UDPC_HashMap_insert(hm, 2, &temp), NULL);
|
||||
ASSERT_EQ_MEM(UDPC_HashMap_get(hm, 2), &temp, sizeof(int));
|
||||
ASSERT_NEQ(UDPC_HashMap_has(hm, 0), 0);
|
||||
ASSERT_NEQ(UDPC_HashMap_has(hm, 1), 0);
|
||||
ASSERT_NEQ(UDPC_HashMap_has(hm, 2), 0);
|
||||
ASSERT_EQ(UDPC_HashMap_has(hm, 3), 0);
|
||||
|
||||
ASSERT_NEQ(UDPC_HashMap_remove(hm, 1), 0);
|
||||
temp = 1333;
|
||||
ASSERT_EQ_MEM(UDPC_HashMap_get(hm, 0), &temp, sizeof(int));
|
||||
temp = 1235987;
|
||||
ASSERT_EQ_MEM(UDPC_HashMap_get(hm, 2), &temp, sizeof(int));
|
||||
ASSERT_NEQ(UDPC_HashMap_has(hm, 0), 0);
|
||||
ASSERT_EQ(UDPC_HashMap_has(hm, 1), 0);
|
||||
ASSERT_NEQ(UDPC_HashMap_has(hm, 2), 0);
|
||||
|
||||
ASSERT_EQ(UDPC_HashMap_realloc(hm, 0), 0);
|
||||
ASSERT_NEQ(UDPC_HashMap_realloc(hm, 16), 0);
|
||||
|
||||
temp = 1333;
|
||||
ASSERT_EQ_MEM(UDPC_HashMap_get(hm, 0), &temp, sizeof(int));
|
||||
temp = 1235987;
|
||||
ASSERT_EQ_MEM(UDPC_HashMap_get(hm, 2), &temp, sizeof(int));
|
||||
ASSERT_NEQ(UDPC_HashMap_has(hm, 0), 0);
|
||||
ASSERT_EQ(UDPC_HashMap_has(hm, 1), 0);
|
||||
ASSERT_NEQ(UDPC_HashMap_has(hm, 2), 0);
|
||||
|
||||
UDPC_HashMap_clear(hm);
|
||||
ASSERT_EQ(hm->size, 0);
|
||||
ASSERT_EQ(hm->capacity, 16);
|
||||
|
||||
ASSERT_NEQ(UDPC_HashMap_realloc(hm, 8), 0);
|
||||
ASSERT_EQ(hm->size, 0);
|
||||
ASSERT_EQ(hm->capacity, 8);
|
||||
|
||||
for(int x = 0; x < 8; ++x)
|
||||
{
|
||||
temp = x * 100;
|
||||
ASSERT_NEQ(UDPC_HashMap_insert(hm, x, &temp), NULL);
|
||||
}
|
||||
for(int x = 0; x < 8; ++x)
|
||||
{
|
||||
temp = x * 100;
|
||||
ASSERT_EQ_MEM(UDPC_HashMap_get(hm, x), &temp, sizeof(int));
|
||||
ASSERT_NEQ(UDPC_HashMap_has(hm, x), 0);
|
||||
}
|
||||
ASSERT_GTE(hm->capacity, 8);
|
||||
|
||||
temp = 800;
|
||||
ASSERT_NEQ(UDPC_HashMap_insert(hm, 8, &temp), NULL);
|
||||
for(int x = 0; x < 9; ++x)
|
||||
{
|
||||
temp = x * 100;
|
||||
ASSERT_EQ_MEM(UDPC_HashMap_get(hm, x), &temp, sizeof(int));
|
||||
ASSERT_NEQ(UDPC_HashMap_has(hm, x), 0);
|
||||
}
|
||||
ASSERT_GTE(hm->capacity, 16);
|
||||
|
||||
for(int x = 0; x < 9; ++x)
|
||||
{
|
||||
ASSERT_NEQ(UDPC_HashMap_remove(hm, x), 0);
|
||||
ASSERT_EQ(UDPC_HashMap_has(hm, x), 0);
|
||||
}
|
||||
ASSERT_EQ(hm->size, 0);
|
||||
ASSERT_GTE(hm->capacity, 16);
|
||||
|
||||
for(int x = 0; x < 32; ++x)
|
||||
{
|
||||
temp = x * 100;
|
||||
ASSERT_NEQ(UDPC_HashMap_insert(hm, x, &temp), NULL);
|
||||
}
|
||||
ASSERT_EQ(hm->size, 32);
|
||||
|
||||
for(int x = 0; x < 32; ++x)
|
||||
{
|
||||
temp = x * 100;
|
||||
ASSERT_EQ_MEM(UDPC_HashMap_get(hm, x), &temp, sizeof(int));
|
||||
ASSERT_NEQ(UDPC_HashMap_has(hm, x), 0);
|
||||
}
|
||||
|
||||
temp = 0;
|
||||
UDPC_HashMap_itercall(hm, TEST_HASHMAP_itercall_comp, &temp);
|
||||
ASSERT_EQ(temp, 32);
|
||||
|
||||
// TODO DEBUG
|
||||
/*
|
||||
printf("Size = %d\n", hm->size);
|
||||
printf("Capacity = %d\n", hm->capacity);
|
||||
for(int x = 0; x < hm->capacity; ++x)
|
||||
{
|
||||
for(int y = 0; y * (4 + sizeof(int)) < hm->buckets[x]->size; ++y)
|
||||
{
|
||||
printf("Bucket%d[%d] = %d\n", x, y,
|
||||
*((int*)&hm->buckets[x]->buf[y * (4 + sizeof(int)) + 4]));
|
||||
}
|
||||
}
|
||||
for(int x = 0; x < hm->overflow->size; ++x)
|
||||
{
|
||||
printf("Overflow[%d] = %d\n", x,
|
||||
*((int*)&hm->overflow->buf[x * (4 + sizeof(int)) + 4]));
|
||||
}
|
||||
*/
|
||||
|
||||
UDPC_HashMap_destroy(hm);
|
||||
UNITTEST_REPORT(HASHMAP);
|
||||
}
|
||||
|
||||
void TEST_STRTOA()
|
||||
{
|
||||
ASSERT_EQ(0x04030201, UDPC_strtoa("1.2.3.4"));
|
||||
ASSERT_EQ(0x0100007F, UDPC_strtoa("127.0.0.1"));
|
||||
ASSERT_EQ(0xFF01A8C0, UDPC_strtoa("192.168.1.255"));
|
||||
ASSERT_EQ(0, UDPC_strtoa("1.2.3.4.5"));
|
||||
ASSERT_EQ(0, UDPC_strtoa("100.20.30"));
|
||||
ASSERT_EQ(0, UDPC_strtoa("200.400.30.50"));
|
||||
UNITTEST_REPORT(STRTOA);
|
||||
}
|
||||
|
||||
void TEST_ATOSTRTOA()
|
||||
{
|
||||
UDPC_Context ctx;
|
||||
|
||||
ASSERT_EQ(0x01020304, UDPC_strtoa(UDPC_INTERNAL_atostr(&ctx, 0x01020304)));
|
||||
ASSERT_EQ(0x7F000001, UDPC_strtoa(UDPC_INTERNAL_atostr(&ctx, 0x7F000001)));
|
||||
ASSERT_EQ(0xC0A801FF, UDPC_strtoa(UDPC_INTERNAL_atostr(&ctx, 0xC0A801FF)));
|
||||
ASSERT_EQ(0xFFFEFDFC, UDPC_strtoa(UDPC_INTERNAL_atostr(&ctx, 0xFFFEFDFC)));
|
||||
|
||||
UNITTEST_REPORT(ATOSTRTOA);
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
TEST_DEQUE();
|
||||
TEST_ATOSTR();
|
||||
TEST_STRTOA();
|
||||
TEST_ATOSTRTOA();
|
||||
TEST_HASHMAP();
|
||||
return 0;
|
||||
}
|
|
@ -1,61 +0,0 @@
|
|||
#ifndef UDPC_UNIT_TEST_H
|
||||
#define UDPC_UNIT_TEST_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
/*
|
||||
#include <UDPC_Deque.h>
|
||||
*/
|
||||
|
||||
#define ASSERT_TRUE(x) \
|
||||
if(!x) { printf("%d: ASSERT_TRUE(%s) FAILED\n", __LINE__, #x); \
|
||||
++UDPC_uts.failed; } ++UDPC_uts.total;
|
||||
#define ASSERT_FALSE(x) \
|
||||
if(x) { printf("%d: ASSERT_FALSE(%s) FAILED\n", __LINE__, #x); \
|
||||
++UDPC_uts.failed; } ++UDPC_uts.total;
|
||||
#define ASSERT_EQ(x, y) \
|
||||
if(x != y) { printf("%d: ASSERT_EQ(%s, %s) FAILED\n", __LINE__, #x, #y); \
|
||||
++UDPC_uts.failed; } ++UDPC_uts.total;
|
||||
#define ASSERT_NEQ(x, y) \
|
||||
if(x == y) { printf("%d: ASSERT_NEQ(%s, %s) FAILED\n", __LINE__, #x, #y); \
|
||||
++UDPC_uts.failed; } ++UDPC_uts.total;
|
||||
#define ASSERT_EQ_MEM(x, y, size) \
|
||||
if(memcmp(x, y, size) != 0) { printf("%d: ASSERT_EQ_MEM(%s, %s, %s) FAILED\n", \
|
||||
__LINE__, #x, #y, #size); ++UDPC_uts.failed; } ++UDPC_uts.total;
|
||||
#define ASSERT_NEQ_MEM(x, y, size) \
|
||||
if(memcmp(x, y, size) == 0) { printf("%d: ASSERT_NEQ_MEM(%s, %s, %s) FAILED\n", \
|
||||
__LINE__, #x, #y, #size); ++UDPC_uts.failed; } ++UDPC_uts.total;
|
||||
#define ASSERT_GT(x, y) \
|
||||
if(x <= y) { printf("%d: ASSERT_GT(%s, %s) FAILED\n", __LINE__, #x, #y); \
|
||||
++UDPC_uts.failed; } ++UDPC_uts.total;
|
||||
#define ASSERT_GTE(x, y) \
|
||||
if(x < y) { printf("%d: ASSERT_GTE(%s, %s) FAILED\n", __LINE__, #x, #y); \
|
||||
++UDPC_uts.failed; } ++UDPC_uts.total;
|
||||
#define ASSERT_LT(x, y) \
|
||||
if(x >= y) { printf("%d: ASSERT_LT(%s, %s) FAILED\n", __LINE__, #x, #y); \
|
||||
++UDPC_uts.failed; } ++UDPC_uts.total;
|
||||
#define ASSERT_LTE(x, y) \
|
||||
if(x > y) { printf("%d: ASSERT_LTE(%s, %s) FAILED\n", __LINE__, #x, #y); \
|
||||
++UDPC_uts.failed; } ++UDPC_uts.total;
|
||||
|
||||
#define UNITTEST_REPORT(x) { \
|
||||
printf("%s: %d/%d tests failed\n", #x, UDPC_uts.failed, UDPC_uts.total); \
|
||||
UDPC_uts.failed = 0; \
|
||||
UDPC_uts.total = 0; }
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int result;
|
||||
} UnitTest_Test;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int failed;
|
||||
int total;
|
||||
} UnitTestState;
|
||||
|
||||
static UnitTestState UDPC_uts;
|
||||
|
||||
#endif
|
2
rust_binding/.gitignore
vendored
2
rust_binding/.gitignore
vendored
|
@ -1,2 +0,0 @@
|
|||
Cargo.lock
|
||||
target/
|
|
@ -1,11 +0,0 @@
|
|||
[package]
|
||||
name = "udpc_rs"
|
||||
version = "0.1.0"
|
||||
authors = ["Stephen Seo <seo.disparate@gmail.com>"]
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
|
||||
[build-dependencies]
|
||||
bindgen = "0.42.2"
|
||||
cmake = "0.1"
|
|
@ -1,56 +0,0 @@
|
|||
use cmake::Config;
|
||||
use bindgen;
|
||||
|
||||
use std::env;
|
||||
use std::path::PathBuf;
|
||||
|
||||
fn main() {
|
||||
let mut config = Config::new("../c_impl");
|
||||
if env::var("PROFILE").unwrap().eq("release") {
|
||||
config.define("CMAKE_BUILD_TYPE", "Release");
|
||||
} else {
|
||||
config.define("CMAKE_BUILD_TYPE", "Debug");
|
||||
}
|
||||
let mut dst = config.build();
|
||||
dst.push("lib");
|
||||
|
||||
println!("cargo:rustc-link-search=native={}", dst.display());
|
||||
println!("cargo:rustc-link-lib=static=UDPConnection");
|
||||
|
||||
let bindings = bindgen::Builder::default()
|
||||
.header("wrapper.h")
|
||||
.whitelist_type("UDPC_callback_connected")
|
||||
.whitelist_type("UDPC_callback_disconnected")
|
||||
.whitelist_type("UDPC_callback_received")
|
||||
.whitelist_type("UDPC_Context")
|
||||
.whitelist_function("UDPC_init")
|
||||
.whitelist_function("UDPC_init_threaded_update")
|
||||
.whitelist_function("UDPC_destroy")
|
||||
.whitelist_function("UDPC_set_callback_connected")
|
||||
.whitelist_function("UDPC_set_callback_disconnected")
|
||||
.whitelist_function("UDPC_set_callback_received")
|
||||
.whitelist_function("UDPC_check_events")
|
||||
.whitelist_function("UDPC_client_initiate_connection")
|
||||
.whitelist_function("UDPC_queue_send")
|
||||
.whitelist_function("UDPC_get_queue_send_available")
|
||||
.whitelist_function("UDPC_get_accept_new_connections")
|
||||
.whitelist_function("UDPC_set_accept_new_connections")
|
||||
.whitelist_function("UDPC_drop_connection")
|
||||
.whitelist_function("UDPC_get_protocol_id")
|
||||
.whitelist_function("UDPC_set_protocol_id")
|
||||
.whitelist_function("UDPC_get_error")
|
||||
.whitelist_function("UDPC_get_error_str")
|
||||
.whitelist_function("UDPC_set_logging_type")
|
||||
.whitelist_function("UDPC_update")
|
||||
.whitelist_function("UDPC_strtoa")
|
||||
.opaque_type("UDPC_Context")
|
||||
.opaque_type("UDPC_Deque")
|
||||
.opaque_type("UDPC_HashMap")
|
||||
.generate()
|
||||
.expect("Unable to generate bindings");
|
||||
|
||||
let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
|
||||
bindings
|
||||
.write_to_file(out_path.join("bindings.rs"))
|
||||
.expect("Couldn't write bindings!");
|
||||
}
|
|
@ -1,5 +0,0 @@
|
|||
#![allow(non_upper_case_globals)]
|
||||
#![allow(non_camel_case_types)]
|
||||
#![allow(non_snake_case)]
|
||||
|
||||
include!(concat!(env!("OUT_DIR"), "/bindings.rs"));
|
|
@ -1 +0,0 @@
|
|||
#include "../c_impl/src/UDPConnection.h"
|
Loading…
Reference in a new issue