Compare commits
25 Commits
memory_all
...
918588e0e4
| Author | SHA1 | Date | |
|---|---|---|---|
| 918588e0e4 | |||
| 6ba06dcc0c | |||
| b430846a0e | |||
| 7ba15b208f | |||
| 791ffe8633 | |||
| 0756b51950 | |||
| fd30713d29 | |||
| 930b35575c | |||
| 59b3772d5a | |||
| 9d2f5ddc2a | |||
| 336bde5fb0 | |||
| 550175fa92 | |||
| 1b93c0ca22 | |||
| 6135f3030f | |||
| c9969a1d96 | |||
| 53cf9875e6 | |||
| ccac9536e8 | |||
| f64a8368ac | |||
| 3d15cb35af | |||
| 85d6ba2216 | |||
| 288c73104c | |||
|
|
2efcf08ebe | ||
| c2b3e3997d | |||
| a55b2245bd | |||
| abfbc7eaa2 |
4
.gitignore
vendored
4
.gitignore
vendored
@@ -6,6 +6,10 @@ obj/
|
|||||||
.old*/
|
.old*/
|
||||||
.vs/
|
.vs/
|
||||||
.vshistory/
|
.vshistory/
|
||||||
|
tmp/
|
||||||
|
temp/
|
||||||
|
*.tmp
|
||||||
|
*.temp
|
||||||
.editorconfig
|
.editorconfig
|
||||||
*.user
|
*.user
|
||||||
*.vcxproj.filters
|
*.vcxproj.filters
|
||||||
|
|||||||
14
.vscode/launch.json
vendored
14
.vscode/launch.json
vendored
@@ -11,19 +11,7 @@
|
|||||||
"stopAtEntry": false,
|
"stopAtEntry": false,
|
||||||
"externalConsole": false,
|
"externalConsole": false,
|
||||||
"MIMode": "gdb",
|
"MIMode": "gdb",
|
||||||
"miDebuggerPath": "gdb",
|
"miDebuggerPath": "gdb"
|
||||||
"setupCommands": [
|
|
||||||
{
|
|
||||||
"description": "Enable pretty-printing for gdb",
|
|
||||||
"text": "-enable-pretty-printing",
|
|
||||||
"ignoreFailures": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "Set Disassembly Flavor to Intel",
|
|
||||||
"text": "-gdb-set disassembly-flavor intel",
|
|
||||||
"ignoreFailures": true
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "(gdb-pipe) Debug",
|
"name": "(gdb-pipe) Debug",
|
||||||
|
|||||||
2
Makefile
2
Makefile
@@ -57,7 +57,7 @@ gprof:
|
|||||||
# compiles program and runs it with callgrind (part of valgrind)
|
# compiles program and runs it with callgrind (part of valgrind)
|
||||||
# uses gprof2dot python script to generate function call tree (pip install gprof2dot)
|
# uses gprof2dot python script to generate function call tree (pip install gprof2dot)
|
||||||
# requires graphviz (https://www.graphviz.org/download/source/)
|
# requires graphviz (https://www.graphviz.org/download/source/)
|
||||||
# P.S. detailed rezults can be viewed in KCacheGrind
|
# P.S. detailed results can be viewed in KCacheGrind
|
||||||
callgrind:
|
callgrind:
|
||||||
@cbuild/call_task.sh callgrind 2>&1 | tee make_raw.log
|
@cbuild/call_task.sh callgrind 2>&1 | tee make_raw.log
|
||||||
|
|
||||||
|
|||||||
2
cbuild
2
cbuild
Submodule cbuild updated: ef6a3f82c4...c20e1e8f1c
@@ -1,6 +1,6 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
CBUILD_VERSION=7
|
CBUILD_VERSION=7
|
||||||
CONFIG_VERSION=7
|
CONFIG_VERSION=8
|
||||||
|
|
||||||
PROJECT="kerep"
|
PROJECT="kerep"
|
||||||
CMP_C="gcc"
|
CMP_C="gcc"
|
||||||
@@ -37,10 +37,12 @@ case "$OS" in
|
|||||||
WINDOWS)
|
WINDOWS)
|
||||||
EXEC_FILE="$PROJECT.exe"
|
EXEC_FILE="$PROJECT.exe"
|
||||||
SHARED_LIB_FILE="$PROJECT.dll"
|
SHARED_LIB_FILE="$PROJECT.dll"
|
||||||
|
LINKER_LIBS="-lpthread -lws2_32"
|
||||||
;;
|
;;
|
||||||
LINUX)
|
LINUX)
|
||||||
EXEC_FILE="$PROJECT"
|
EXEC_FILE="$PROJECT"
|
||||||
SHARED_LIB_FILE="$PROJECT.so"
|
SHARED_LIB_FILE="$PROJECT.so"
|
||||||
|
LINKER_LIBS=""
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
error "operating system $OS has no configuration variants"
|
error "operating system $OS has no configuration variants"
|
||||||
@@ -59,7 +61,7 @@ case "$TASK" in
|
|||||||
# -fdata-sections -ffunction-sections -Wl,--gc-sections removes unused code
|
# -fdata-sections -ffunction-sections -Wl,--gc-sections removes unused code
|
||||||
C_ARGS="-O2 -flto=auto -fuse-linker-plugin -fprofile-use -fprofile-prefix-path=$(realpath $OBJDIR)/objects -fdata-sections -ffunction-sections -Wl,--gc-sections"
|
C_ARGS="-O2 -flto=auto -fuse-linker-plugin -fprofile-use -fprofile-prefix-path=$(realpath $OBJDIR)/objects -fdata-sections -ffunction-sections -Wl,--gc-sections"
|
||||||
CPP_ARGS="$C_ARGS"
|
CPP_ARGS="$C_ARGS"
|
||||||
LINKER_ARGS="$CPP_ARGS"
|
LINKER_ARGS="$CPP_ARGS $LINKER_LIBS"
|
||||||
PRE_TASK_SCRIPT=
|
PRE_TASK_SCRIPT=
|
||||||
TASK_SCRIPT=cbuild/default_tasks/build_exec.sh
|
TASK_SCRIPT=cbuild/default_tasks/build_exec.sh
|
||||||
POST_TASK_SCRIPT=
|
POST_TASK_SCRIPT=
|
||||||
@@ -68,7 +70,7 @@ case "$TASK" in
|
|||||||
build_exec_dbg)
|
build_exec_dbg)
|
||||||
C_ARGS="-O0 -g3"
|
C_ARGS="-O0 -g3"
|
||||||
CPP_ARGS="$C_ARGS"
|
CPP_ARGS="$C_ARGS"
|
||||||
LINKER_ARGS="$CPP_ARGS"
|
LINKER_ARGS="$CPP_ARGS $LINKER_LIBS"
|
||||||
PRE_TASK_SCRIPT=
|
PRE_TASK_SCRIPT=
|
||||||
TASK_SCRIPT=cbuild/default_tasks/build_exec.sh
|
TASK_SCRIPT=cbuild/default_tasks/build_exec.sh
|
||||||
POST_TASK_SCRIPT=
|
POST_TASK_SCRIPT=
|
||||||
@@ -77,7 +79,7 @@ case "$TASK" in
|
|||||||
build_shared_lib)
|
build_shared_lib)
|
||||||
C_ARGS="-O2 -fpic -flto -shared"
|
C_ARGS="-O2 -fpic -flto -shared"
|
||||||
CPP_ARGS="$C_ARGS"
|
CPP_ARGS="$C_ARGS"
|
||||||
LINKER_ARGS="$CPP_ARGS -Wl,-soname,$SHARED_LIB_FILE"
|
LINKER_ARGS="$CPP_ARGS -Wl,-soname,$SHARED_LIB_FILE $LINKER_LIBS"
|
||||||
PRE_TASK_SCRIPT=
|
PRE_TASK_SCRIPT=
|
||||||
TASK_SCRIPT=cbuild/default_tasks/build_shared_lib.sh
|
TASK_SCRIPT=cbuild/default_tasks/build_shared_lib.sh
|
||||||
POST_TASK_SCRIPT=
|
POST_TASK_SCRIPT=
|
||||||
@@ -86,7 +88,7 @@ case "$TASK" in
|
|||||||
build_shared_lib_dbg)
|
build_shared_lib_dbg)
|
||||||
C_ARGS="-O0 -g3 -fpic -shared"
|
C_ARGS="-O0 -g3 -fpic -shared"
|
||||||
CPP_ARGS="$C_ARGS"
|
CPP_ARGS="$C_ARGS"
|
||||||
LINKER_ARGS="$CPP_ARGS -Wl,-soname,$SHARED_LIB_FILE"
|
LINKER_ARGS="$CPP_ARGS -Wl,-soname,$SHARED_LIB_FILE $LINKER_LIBS"
|
||||||
PRE_TASK_SCRIPT=
|
PRE_TASK_SCRIPT=
|
||||||
TASK_SCRIPT=cbuild/default_tasks/build_shared_lib.sh
|
TASK_SCRIPT=cbuild/default_tasks/build_shared_lib.sh
|
||||||
POST_TASK_SCRIPT=
|
POST_TASK_SCRIPT=
|
||||||
@@ -127,7 +129,7 @@ case "$TASK" in
|
|||||||
# -fprofile-prefix-path sets path where profiling info about objects will be saved
|
# -fprofile-prefix-path sets path where profiling info about objects will be saved
|
||||||
C_ARGS="-O2 -flto=auto -fuse-linker-plugin -fprofile-generate -fprofile-prefix-path=$(realpath $OBJDIR)/objects"
|
C_ARGS="-O2 -flto=auto -fuse-linker-plugin -fprofile-generate -fprofile-prefix-path=$(realpath $OBJDIR)/objects"
|
||||||
CPP_ARGS="$C_ARGS"
|
CPP_ARGS="$C_ARGS"
|
||||||
LINKER_ARGS="$CPP_ARGS"
|
LINKER_ARGS="$CPP_ARGS $LINKER_LIBS"
|
||||||
PRE_TASK_SCRIPT=cbuild/default_tasks/build_exec.sh
|
PRE_TASK_SCRIPT=cbuild/default_tasks/build_exec.sh
|
||||||
TASK_SCRIPT=cbuild/default_tasks/profile.sh
|
TASK_SCRIPT=cbuild/default_tasks/profile.sh
|
||||||
POST_TASK_SCRIPT=
|
POST_TASK_SCRIPT=
|
||||||
@@ -140,7 +142,7 @@ case "$TASK" in
|
|||||||
# -pg adds code to executable, that generates file containing function call info (gmon.out)
|
# -pg adds code to executable, that generates file containing function call info (gmon.out)
|
||||||
C_ARGS="-O2 -flto=auto -fuse-linker-plugin -pg"
|
C_ARGS="-O2 -flto=auto -fuse-linker-plugin -pg"
|
||||||
CPP_ARGS="$C_ARGS"
|
CPP_ARGS="$C_ARGS"
|
||||||
LINKER_ARGS="$CPP_ARGS"
|
LINKER_ARGS="$CPP_ARGS $LINKER_LIBS"
|
||||||
PRE_TASK_SCRIPT=cbuild/default_tasks/build_exec.sh
|
PRE_TASK_SCRIPT=cbuild/default_tasks/build_exec.sh
|
||||||
TASK_SCRIPT=cbuild/default_tasks/gprof.sh
|
TASK_SCRIPT=cbuild/default_tasks/gprof.sh
|
||||||
POST_TASK_SCRIPT=
|
POST_TASK_SCRIPT=
|
||||||
@@ -148,13 +150,13 @@ case "$TASK" in
|
|||||||
# compiles program and runs it with callgrind (part of valgrind)
|
# compiles program and runs it with callgrind (part of valgrind)
|
||||||
# uses gprof2dot python script to generate function call tree (pip install gprof2dot)
|
# uses gprof2dot python script to generate function call tree (pip install gprof2dot)
|
||||||
# requires graphviz (https://www.graphviz.org/download/source/)
|
# requires graphviz (https://www.graphviz.org/download/source/)
|
||||||
# P.S. detailed rezults can be viewed in KCacheGrind
|
# P.S. detailed results can be viewed in KCacheGrind
|
||||||
callgrind)
|
callgrind)
|
||||||
OUTDIR="$OUTDIR/callgrind"
|
OUTDIR="$OUTDIR/callgrind"
|
||||||
# -pg adds code to executable, that generates file containing function call info (gmon.out)
|
# -pg adds code to executable, that generates file containing function call info (gmon.out)
|
||||||
C_ARGS="-O2 -flto=auto -fuse-linker-plugin"
|
C_ARGS="-O2 -flto=auto -fuse-linker-plugin"
|
||||||
CPP_ARGS="$C_ARGS"
|
CPP_ARGS="$C_ARGS"
|
||||||
LINKER_ARGS="$CPP_ARGS"
|
LINKER_ARGS="$CPP_ARGS $LINKER_LIBS"
|
||||||
PRE_TASK_SCRIPT=tasks/pre_build.sh
|
PRE_TASK_SCRIPT=tasks/pre_build.sh
|
||||||
TASK_SCRIPT=cbuild/default_tasks/build_exec.sh
|
TASK_SCRIPT=cbuild/default_tasks/build_exec.sh
|
||||||
POST_TASK_SCRIPT=cbuild/default_tasks/callgrind.sh
|
POST_TASK_SCRIPT=cbuild/default_tasks/callgrind.sh
|
||||||
@@ -164,7 +166,7 @@ case "$TASK" in
|
|||||||
OUTDIR="$OUTDIR/sanitize"
|
OUTDIR="$OUTDIR/sanitize"
|
||||||
C_ARGS="-O0 -g3 -fsanitize=undefined,address"
|
C_ARGS="-O0 -g3 -fsanitize=undefined,address"
|
||||||
CPP_ARGS="$C_ARGS"
|
CPP_ARGS="$C_ARGS"
|
||||||
LINKER_ARGS="$CPP_ARGS"
|
LINKER_ARGS="$CPP_ARGS $LINKER_LIBS"
|
||||||
PRE_TASK_SCRIPT=cbuild/default_tasks/build_exec.sh
|
PRE_TASK_SCRIPT=cbuild/default_tasks/build_exec.sh
|
||||||
TASK_SCRIPT=cbuild/default_tasks/exec.sh
|
TASK_SCRIPT=cbuild/default_tasks/exec.sh
|
||||||
POST_TASK_SCRIPT=
|
POST_TASK_SCRIPT=
|
||||||
|
|||||||
@@ -64,64 +64,64 @@ Maybe file_close(FileHandle file){
|
|||||||
}
|
}
|
||||||
|
|
||||||
#define ioWriteCheck() \
|
#define ioWriteCheck() \
|
||||||
if(rezult==EOF) \
|
if(result==EOF) \
|
||||||
safethrow(ERR_IO_EOF,;); \
|
safethrow(ERR_IO_EOF,;); \
|
||||||
if(rezult!=0) \
|
if(result!=0) \
|
||||||
safethrow(ERR_IO,;);
|
safethrow(ERR_IO,;);
|
||||||
|
|
||||||
Maybe file_writeChar(FileHandle file, char byte){
|
Maybe file_writeChar(FileHandle file, char byte){
|
||||||
i32 rezult=fputc(byte, file);
|
i32 result=fputc(byte, file);
|
||||||
ioWriteCheck();
|
ioWriteCheck();
|
||||||
return MaybeNull;
|
return MaybeNull;
|
||||||
}
|
}
|
||||||
|
|
||||||
Maybe file_writeBuffer(FileHandle file, char* buffer, u64 length){
|
Maybe file_writeBuffer(FileHandle file, char* buffer, u64 length){
|
||||||
i32 rezult=0;
|
i32 result=0;
|
||||||
for(u64 i=0; i<length && !rezult; i++)
|
for(u64 i=0; i<length && !result; i++)
|
||||||
rezult=fputc(buffer[i], file);
|
result=fputc(buffer[i], file);
|
||||||
ioWriteCheck();
|
ioWriteCheck();
|
||||||
return MaybeNull;
|
return MaybeNull;
|
||||||
}
|
}
|
||||||
|
|
||||||
Maybe file_writeCptr(FileHandle file, char* cptr){
|
Maybe file_writeCptr(FileHandle file, char* cptr){
|
||||||
i32 rezult=fputs(cptr, file);
|
i32 result=fputs(cptr, file);
|
||||||
ioWriteCheck();
|
ioWriteCheck();
|
||||||
return MaybeNull;
|
return MaybeNull;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Maybe file_readChar(FileHandle file){
|
Maybe file_readChar(FileHandle file){
|
||||||
i32 rezult=fgetc(file);
|
i32 result=fgetc(file);
|
||||||
if(feof(file)) safethrow(ERR_IO_EOF,;);
|
if(feof(file)) safethrow(ERR_IO_EOF,;);
|
||||||
if(ferror(file)) safethrow(ERR_IO,;);
|
if(ferror(file)) safethrow(ERR_IO,;);
|
||||||
return SUCCESS(UniUInt64(rezult));
|
return SUCCESS(UniUInt64(result));
|
||||||
}
|
}
|
||||||
|
|
||||||
Maybe file_readBuffer(FileHandle file, char* buffer, u64 length){
|
Maybe file_readBuffer(FileHandle file, char* buffer, u64 length){
|
||||||
i32 rezult=0;
|
i32 result=0;
|
||||||
u64 i=0;
|
u64 i=0;
|
||||||
for(; i<length && rezult!=EOF; i++){
|
for(; i<length && result!=EOF; i++){
|
||||||
rezult=fgetc(file);
|
result=fgetc(file);
|
||||||
buffer[i]=(char)rezult;
|
buffer[i]=(char)result;
|
||||||
}
|
}
|
||||||
if(ferror(file)) safethrow(ERR_IO,;);
|
if(ferror(file)) safethrow(ERR_IO,;);
|
||||||
return SUCCESS(UniUInt64(i));
|
return SUCCESS(UniUInt64(i));
|
||||||
}
|
}
|
||||||
|
|
||||||
Maybe file_readAll(FileHandle file, char** allBytes){
|
Maybe file_readAll(FileHandle file, char** allBytes){
|
||||||
i32 rezult=0;
|
i32 result=0;
|
||||||
char buffer[256];
|
char buffer[256];
|
||||||
string bufStr={.ptr=buffer, .length=sizeof(buffer)};
|
string bufStr={.ptr=buffer, .length=sizeof(buffer)};
|
||||||
StringBuilder* sb=StringBuilder_create();
|
StringBuilder* sb=StringBuilder_create();
|
||||||
u64 i=0;
|
u64 i=0;
|
||||||
while(true){
|
while(true){
|
||||||
rezult=fgetc(file);
|
result=fgetc(file);
|
||||||
if(rezult==EOF){
|
if(result==EOF){
|
||||||
if(ferror(file))
|
if(ferror(file))
|
||||||
safethrow(ERR_IO, StringBuilder_free(sb));
|
safethrow(ERR_IO, StringBuilder_free(sb));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
buffer[i%sizeof(buffer)]=(char)rezult;
|
buffer[i%sizeof(buffer)]=(char)result;
|
||||||
i++;
|
i++;
|
||||||
if(!(i%sizeof(buffer)))
|
if(!(i%sizeof(buffer)))
|
||||||
StringBuilder_append_string(sb,bufStr);
|
StringBuilder_append_string(sb,bufStr);
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ char* __path_concat(u32 n, ...){
|
|||||||
const char* output=totality;
|
const char* output=totality;
|
||||||
totality[totalLength]=0;
|
totality[totalLength]=0;
|
||||||
|
|
||||||
// copying content of all strings to rezult
|
// copying content of all strings to result
|
||||||
u16 k=0;
|
u16 k=0;
|
||||||
for(; k<n-1; k++){
|
for(; k<n-1; k++){
|
||||||
memcopy(parts[k], totality, lengths[k]);
|
memcopy(parts[k], totality, lengths[k]);
|
||||||
@@ -74,11 +74,11 @@ char* path_parentDir(char* dir){
|
|||||||
|
|
||||||
char* path_basename(char* path, bool with_extension){
|
char* path_basename(char* path, bool with_extension){
|
||||||
i32 nameIndex=cptr_lastIndexOfChar(path, path_sep)+1;
|
i32 nameIndex=cptr_lastIndexOfChar(path, path_sep)+1;
|
||||||
string rezult=string_fromCptr(path+nameIndex);
|
string result=string_fromCptr(path+nameIndex);
|
||||||
if(!with_extension){
|
if(!with_extension){
|
||||||
i32 extIndex=cptr_lastIndexOfChar(rezult.ptr, '.');
|
i32 extIndex=cptr_lastIndexOfChar(result.ptr, '.');
|
||||||
if(extIndex!=0 && extIndex!=-1)
|
if(extIndex!=0 && extIndex!=-1)
|
||||||
rezult.length=extIndex;
|
result.length=extIndex;
|
||||||
}
|
}
|
||||||
return string_extract(rezult);
|
return string_extract(result);
|
||||||
}
|
}
|
||||||
|
|||||||
4
src/Network/README.md
Normal file
4
src/Network/README.md
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
# kerep network
|
||||||
|
|
||||||
|
Don't forget to call `kn_tryInit()` before doint anything with network.
|
||||||
|
|
||||||
44
src/Network/network.c
Normal file
44
src/Network/network.c
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
#include "network_internal.h"
|
||||||
|
|
||||||
|
Maybe kn_tryInit(){
|
||||||
|
#if _WIN32
|
||||||
|
// Initialize Winsock
|
||||||
|
WSADATA wsaData = {0};
|
||||||
|
int startupResult = WSAStartup(MAKEWORD(2,2), &wsaData);
|
||||||
|
if (startupResult != 0) {
|
||||||
|
char* errcode = toString_hex(&startupResult, sizeof(int), 0 , 1, 1);
|
||||||
|
safethrow(cptr_concat("WSAStartup failed with error: ", errcode), ;);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return SUCCESS(UniNull);
|
||||||
|
}
|
||||||
|
|
||||||
|
Maybe kt_tryDispose(){
|
||||||
|
#if _WIN32
|
||||||
|
// Deinitialize Winsock
|
||||||
|
int cleanupResult = WSACleanup();
|
||||||
|
if (cleanupResult != 0) {
|
||||||
|
char* errcode = toString_hex(&cleanupResult, sizeof(int), 0, 1, 1);
|
||||||
|
safethrow(cptr_concat("WSAStartup failed with error: ", errcode), ;);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return SUCCESS(UniNull);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Maybe __kn_StdSocket_shutdown(i64 socketfd, knShutdownType direction){
|
||||||
|
if(shutdown(socketfd, (int)direction) == -1)
|
||||||
|
safethrow("can't shutdown socket", ;);
|
||||||
|
return MaybeNull;
|
||||||
|
}
|
||||||
|
|
||||||
|
Maybe __kn_StdSocket_close(i64 socketfd){
|
||||||
|
#if KN_USE_WINSOCK
|
||||||
|
if(closesocket(socketfd) == -1)
|
||||||
|
#else
|
||||||
|
if(close(socketfd) == -1)
|
||||||
|
#endif
|
||||||
|
safethrow("can't close socket", ;);
|
||||||
|
|
||||||
|
return MaybeNull;
|
||||||
|
}
|
||||||
19
src/Network/network.h
Normal file
19
src/Network/network.h
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#if __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "../base/base.h"
|
||||||
|
|
||||||
|
#include "network_types.h"
|
||||||
|
#include "sockets/knSocketTCP.h"
|
||||||
|
#include "sockets/knSocketUDP.h"
|
||||||
|
#include "sockets/knSocketChanneled.h"
|
||||||
|
|
||||||
|
Maybe kn_tryInit();
|
||||||
|
Maybe kt_tryDispose();
|
||||||
|
|
||||||
|
#if __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
32
src/Network/network_internal.h
Normal file
32
src/Network/network_internal.h
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#if __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "network.h"
|
||||||
|
#include "socket_impl_includes.h"
|
||||||
|
|
||||||
|
/// shutdown TCP/UDP/other std socket
|
||||||
|
Maybe __kn_StdSocket_shutdown(i64 socketfd, knShutdownType direction);
|
||||||
|
|
||||||
|
/// close TCP/UDP/other std socket
|
||||||
|
Maybe __kn_StdSocket_close(i64 socketfd);
|
||||||
|
|
||||||
|
static inline struct sockaddr_in knIPV4Endpoint_toSockaddr(knIPV4Endpoint end){
|
||||||
|
struct sockaddr_in saddr = {0};
|
||||||
|
saddr.sin_family = AF_INET;
|
||||||
|
saddr.sin_addr.s_addr = end.address.UintBigEndian;
|
||||||
|
saddr.sin_port = htons(end.port); /* transforms port number to big endian (network order) */
|
||||||
|
return saddr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline knIPV4Endpoint knIPV4Endpoint_fromSockaddr(struct sockaddr_in saddr_ptr){
|
||||||
|
knIPV4Address ipv4 = knIPV4Address_fromU32(saddr_ptr.sin_addr.s_addr);
|
||||||
|
u16 port = ntohs(saddr_ptr.sin_port); /* transforms port number to little endian (normal order) */
|
||||||
|
return knIPV4Endpoint_create(ipv4, port);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
93
src/Network/network_types.c
Normal file
93
src/Network/network_types.c
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
#include "network_types.h"
|
||||||
|
|
||||||
|
char* __knIPV4Address_toString(void* p, u32 f){ return knIPV4Address_toString(p); }
|
||||||
|
char* __knIPV4Endpoint_toString(void* p, u32 f){ return knIPV4Endpoint_toString(p); }
|
||||||
|
|
||||||
|
kt_define(knIPV4Address, NULL, __knIPV4Address_toString);
|
||||||
|
kt_define(knIPV4Endpoint, NULL, __knIPV4Endpoint_toString);
|
||||||
|
|
||||||
|
|
||||||
|
Maybe knIPV4Address_fromStr(char* addrStr, knIPV4Address* addrVal){
|
||||||
|
char* addrStr_src=addrStr;
|
||||||
|
char* errmsg_extra="wrong char";
|
||||||
|
u8 c;
|
||||||
|
knIPV4Address addr;
|
||||||
|
addr.UintBigEndian=0;
|
||||||
|
u16 n=0;
|
||||||
|
for(u8 i=0; i<4; ){
|
||||||
|
c=*addrStr++;
|
||||||
|
switch (c){
|
||||||
|
case '\0':
|
||||||
|
if(i<3){
|
||||||
|
errmsg_extra="end of string";
|
||||||
|
goto default_case;
|
||||||
|
}
|
||||||
|
|
||||||
|
addr.bytes[i++]=n;
|
||||||
|
n=0;
|
||||||
|
break;
|
||||||
|
case '.':
|
||||||
|
addr.bytes[i++]=n;
|
||||||
|
n=0;
|
||||||
|
break;
|
||||||
|
case '0': case '1': case '2': case '3': case '4':
|
||||||
|
case '5': case '6': case '7': case '8': case '9':
|
||||||
|
n=n*10+c-'0';
|
||||||
|
if(n>255) {
|
||||||
|
errmsg_extra="one part of address > 255";
|
||||||
|
goto default_case;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default_case:
|
||||||
|
default:
|
||||||
|
u32 errmsgL=cptr_length(addrStr) + 80;
|
||||||
|
char* errmsg=malloc(errmsgL);
|
||||||
|
IFMSC(sprintf_s(errmsg, errmsgL, "wrong ip address string: %s\n %s", addrStr_src, errmsg_extra),
|
||||||
|
sprintf( errmsg, "wrong ip address string: %s\n %s", addrStr_src, errmsg_extra));
|
||||||
|
safethrow(errmsg,;);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*addrVal=addr;
|
||||||
|
return MaybeNull;
|
||||||
|
}
|
||||||
|
|
||||||
|
char* knIPV4Address_toString(knIPV4Address* address) {
|
||||||
|
char* a = toString_u64(address->bytes[0], 0, 0);
|
||||||
|
char* b = toString_u64(address->bytes[1], 0, 0);
|
||||||
|
char* c = toString_u64(address->bytes[2], 0, 0);
|
||||||
|
char* d = toString_u64(address->bytes[3], 0, 0);
|
||||||
|
char* s = cptr_concat(a,".",b,".",c,".",d);
|
||||||
|
free(a);
|
||||||
|
free(b);
|
||||||
|
free(c);
|
||||||
|
free(d);
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Maybe knIPV4Endpoint_fromStr(char* endStr, knIPV4Endpoint* endVal){
|
||||||
|
i32 sep_i = cptr_seekChar(endStr, ':', 0, 48);
|
||||||
|
if(sep_i < 7)
|
||||||
|
safethrow(cptr_concat("can't find ':' in '", endStr, "'"), ;);
|
||||||
|
char* portBegin = endStr+sep_i+1;
|
||||||
|
u64 port = knPort_INVALID;
|
||||||
|
if(sscanf(portBegin, IFWIN("%llu", "%lu"), &port)!=1)
|
||||||
|
safethrow(cptr_concat("can't recognise port number in '", portBegin, "'"), ;)
|
||||||
|
|
||||||
|
knIPV4Address addr = knIPV4Address_INVALID;
|
||||||
|
try(knIPV4Address_fromStr(endStr, &addr), _m865, ;);
|
||||||
|
|
||||||
|
*endVal = knIPV4Endpoint_create(addr, port);
|
||||||
|
return MaybeNull;
|
||||||
|
}
|
||||||
|
|
||||||
|
char* knIPV4Endpoint_toString(knIPV4Endpoint* end) {
|
||||||
|
char* a = knIPV4Address_toString(&end->address);
|
||||||
|
char* p = toString_u64(end->port, 0, 0);
|
||||||
|
char* s = cptr_concat(a,":",p);
|
||||||
|
free(a);
|
||||||
|
free(p);
|
||||||
|
return s;
|
||||||
|
}
|
||||||
58
src/Network/network_types.h
Normal file
58
src/Network/network_types.h
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#if __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "../base/base.h"
|
||||||
|
|
||||||
|
typedef u16 knPort;
|
||||||
|
#define knPort_INVALID ((knPort)~0)
|
||||||
|
#define knPort_isINVALID(PORT) (PORT == knPort_INVALID)
|
||||||
|
|
||||||
|
typedef union knIPV4Address {
|
||||||
|
u32 UintBigEndian;
|
||||||
|
char bytes[4];
|
||||||
|
} knIPV4Address;
|
||||||
|
kt_declare(knIPV4Address);
|
||||||
|
|
||||||
|
#define knIPV4Address_fromBytes(A, B, C, D) ((knIPV4Address){.bytes={A,B,C,D}})
|
||||||
|
#define knIPV4Address_fromU32(N) ((knIPV4Address){.UintBigEndian=N})
|
||||||
|
|
||||||
|
|
||||||
|
#define knIPV4Address_ANY knIPV4Address_fromBytes(0,0,0,0)
|
||||||
|
#define knIPV4Address_LOOPBACK knIPV4Address_fromBytes(127,0,0,1)
|
||||||
|
#define knIPV4Address_INVALID knIPV4Address_fromBytes(255,255,255,255)
|
||||||
|
#define knIPV4Address_isINVALID(ADDR) (ADDR.UintBigEndian == ~0)
|
||||||
|
|
||||||
|
///@return Maybe<null>
|
||||||
|
Maybe knIPV4Address_fromStr(char* addrStr, knIPV4Address* addrPtr);
|
||||||
|
|
||||||
|
char* knIPV4Address_toString(knIPV4Address* address);
|
||||||
|
|
||||||
|
|
||||||
|
STRUCT(knIPV4Endpoint,
|
||||||
|
knIPV4Address address;
|
||||||
|
knPort port;
|
||||||
|
)
|
||||||
|
|
||||||
|
#define knIPV4Endpoint_create(ADDR, PORT) ((knIPV4Endpoint){ADDR, PORT})
|
||||||
|
|
||||||
|
#define knIPV4Endpoint_INVALID knIPV4Endpoint_create(knIPV4Address_INVALID, knPort_INVALID)
|
||||||
|
#define knIPV4Endpoint_isINVALID(ENDP) (knIPV4Address_isINVALID(ENDP.address) || knPort_isINVALID(ENDP.port))
|
||||||
|
|
||||||
|
///@return Maybe<null>
|
||||||
|
Maybe knIPV4Endpoint_fromStr(char* endStr, knIPV4Endpoint* endVal);
|
||||||
|
|
||||||
|
char* knIPV4Endpoint_toString(knIPV4Endpoint* end);
|
||||||
|
|
||||||
|
|
||||||
|
typedef enum knShutdownType {
|
||||||
|
knShutdownType_Receive = 0,
|
||||||
|
knShutdownType_Send = 1,
|
||||||
|
knShutdownType_Both = 2,
|
||||||
|
} knShutdownType;
|
||||||
|
|
||||||
|
#if __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
27
src/Network/socket_impl_includes.h
Normal file
27
src/Network/socket_impl_includes.h
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#if __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(_WIN64) || defined(_WIN32)
|
||||||
|
#define KN_USE_WINSOCK 1
|
||||||
|
#else
|
||||||
|
#define KN_USE_WINSOCK 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if KN_USE_WINSOCK
|
||||||
|
#include <winsock2.h>
|
||||||
|
// #include <ws2tcpip.h>
|
||||||
|
#else
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#include <netdb.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
52
src/Network/sockets/knSocketChanneled.c
Normal file
52
src/Network/sockets/knSocketChanneled.c
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
#include "../network_internal.h"
|
||||||
|
|
||||||
|
void __knSocketChanneled_close(void* p){ knSocketChanneled_close(p); }
|
||||||
|
|
||||||
|
kt_define(knPackage, NULL, NULL);
|
||||||
|
kt_define(knPackageQueueElem, NULL, NULL);
|
||||||
|
kt_define(knChannel, NULL, NULL);
|
||||||
|
kt_define(knSocketChanneled, __knSocketChanneled_close, NULL);
|
||||||
|
|
||||||
|
Maybe knSocketChanneled_open(){
|
||||||
|
knSocketChanneled* newSocket=malloc(sizeof(knSocketChanneled));
|
||||||
|
newSocket->localEndpoint=knIPV4Endpoint_INVALID;
|
||||||
|
newSocket->remoteEndpoint=knIPV4Endpoint_INVALID;
|
||||||
|
newSocket->channels=NULL;
|
||||||
|
newSocket->channelsAmount=0;
|
||||||
|
return SUCCESS(UniHeapPtr(knSocketChanneled, newSocket));
|
||||||
|
}
|
||||||
|
|
||||||
|
Maybe knSocketChanneled_close(knSocketChanneled* socket){
|
||||||
|
try(__kn_StdSocket_close(socket->socketfd), _m762, ;);
|
||||||
|
free(socket);
|
||||||
|
return MaybeNull;
|
||||||
|
}
|
||||||
|
|
||||||
|
knChannel* __createChannel(){
|
||||||
|
knChannel* ch=malloc(sizeof(knChannel));
|
||||||
|
ch->queueStart=NULL;
|
||||||
|
return ch;
|
||||||
|
}
|
||||||
|
|
||||||
|
Maybe knSocketChanneled_createChannel(knSocketChanneled* socket){
|
||||||
|
if(socket->channelsAmount == 65535)
|
||||||
|
safethrow("max amount of channels",;);
|
||||||
|
u16 channelsAmountPrev=socket->channelsAmount;
|
||||||
|
socket->channelsAmount++;
|
||||||
|
if(channelsAmountPrev==0)
|
||||||
|
socket->channels=malloc(sizeof(knChannel*));
|
||||||
|
else
|
||||||
|
socket->channels=realloc(socket->channels, socket->channelsAmount*sizeof(knChannel*));
|
||||||
|
socket->channels[channelsAmountPrev]=__createChannel();
|
||||||
|
return SUCCESS(UniUInt64(channelsAmountPrev));
|
||||||
|
}
|
||||||
|
|
||||||
|
Maybe knSocketChanneled_listen(knSocketChanneled* socket, knIPV4Endpoint localEndp);
|
||||||
|
|
||||||
|
Maybe knSocketChanneled_connect(knSocketChanneled* socket, knIPV4Endpoint remoteEndp);
|
||||||
|
|
||||||
|
Maybe knSocketChanneled_accept(knSocketChanneled* socket);
|
||||||
|
|
||||||
|
Maybe knSocketChanneled_send(knSocketChanneled* socket, u16 destinationIndex, u8* data, u32 dataLength);
|
||||||
|
|
||||||
|
Maybe knSocketChanneled_receive(knSocketChanneled* socket, u16 destinationIndex, u8* buffer, u32 bufferLength);
|
||||||
77
src/Network/sockets/knSocketChanneled.h
Normal file
77
src/Network/sockets/knSocketChanneled.h
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#if __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "../network_types.h"
|
||||||
|
|
||||||
|
#define KNPAC_MAX_DATA_SIZE (65535-sizeof(knPackage)+sizeof(u8*))
|
||||||
|
|
||||||
|
|
||||||
|
typedef enum __attribute__((__packed__)) knPacVersion {
|
||||||
|
knPac_V1=1
|
||||||
|
} knPacVersion;
|
||||||
|
|
||||||
|
static const char knPacHeader[5]={'k','n','p','a','c'};
|
||||||
|
|
||||||
|
STRUCT(knPackage,
|
||||||
|
char header[5]; /* knpac */
|
||||||
|
knPacVersion version; /* protocol version */
|
||||||
|
u16 data_size; /* size of data block in bytes (1-KNPAC_MAX_DATA_SIZE) */
|
||||||
|
u32 channel_id; /* id of knChannel in socket */
|
||||||
|
u32 package_num; /* number in sequence of sent packages */
|
||||||
|
u64 data_hash; /* hash64 of data */
|
||||||
|
u8* data; /* ptr to data */
|
||||||
|
)
|
||||||
|
|
||||||
|
STRUCT(knPackageQueueElem,
|
||||||
|
knPackage package;
|
||||||
|
knPackageQueueElem* previousElem;
|
||||||
|
knPackageQueueElem* nextElem;
|
||||||
|
)
|
||||||
|
|
||||||
|
STRUCT(knChannel,
|
||||||
|
knPackageQueueElem* queueStart;
|
||||||
|
)
|
||||||
|
|
||||||
|
STRUCT(knSocketChanneled,
|
||||||
|
i64 socketfd;
|
||||||
|
knIPV4Endpoint localEndpoint;
|
||||||
|
knIPV4Endpoint remoteEndpoint;
|
||||||
|
u16 channelsAmount;
|
||||||
|
knChannel** channels;
|
||||||
|
)
|
||||||
|
|
||||||
|
///@return Maybe<knSocketChanneled*> new socket
|
||||||
|
Maybe knSocketChanneled_open();
|
||||||
|
|
||||||
|
///@return Maybe<void> error or nothing
|
||||||
|
Maybe knSocketChanneled_close(knSocketChanneled* socket);
|
||||||
|
|
||||||
|
///@return Maybe<u64> channel index
|
||||||
|
Maybe knSocketChanneled_createChannel(knSocketChanneled* socket);
|
||||||
|
|
||||||
|
///start listening at local endpoint
|
||||||
|
///@return Maybe<void> error or nothing
|
||||||
|
Maybe knSocketChanneled_listen(knSocketChanneled* socket, knIPV4Endpoint localEndp);
|
||||||
|
|
||||||
|
///sets socket remote endpoint
|
||||||
|
///@return Maybe<void> error or nothing
|
||||||
|
Maybe knSocketChanneled_connect(knSocketChanneled* socket, knIPV4Endpoint remoteEndp);
|
||||||
|
|
||||||
|
///@return Maybe<knSocketChanneled*> new socket connected to client
|
||||||
|
Maybe knSocketChanneled_accept(knSocketChanneled* socket);
|
||||||
|
|
||||||
|
///@param dataLength 0-4294967295
|
||||||
|
///@return Maybe<void>
|
||||||
|
Maybe knSocketChanneled_send(knSocketChanneled* socket, u16 destinationIndex, u8* data, u32 dataLength);
|
||||||
|
|
||||||
|
///@param buffer buffer for receiving data
|
||||||
|
///@param bufferLength 0-4294967295
|
||||||
|
///@return Maybe<u64> received bytes amount
|
||||||
|
Maybe knSocketChanneled_receive(knSocketChanneled* socket, u16 destinationIndex, u8* buffer, u32 bufferLength);
|
||||||
|
|
||||||
|
#if __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
102
src/Network/sockets/knSocketTCP.c
Normal file
102
src/Network/sockets/knSocketTCP.c
Normal file
@@ -0,0 +1,102 @@
|
|||||||
|
#include "../network_internal.h"
|
||||||
|
|
||||||
|
void __knSocketTCP_close(void* p){ knSocketTCP_close(p); }
|
||||||
|
|
||||||
|
kt_define(knSocketTCP, __knSocketTCP_close, NULL);
|
||||||
|
|
||||||
|
Maybe knSocketTCP_open(bool allowReuse){
|
||||||
|
knSocketTCP* newSocket=malloc(sizeof(knSocketTCP));
|
||||||
|
newSocket->localEndpoint=knIPV4Endpoint_INVALID;
|
||||||
|
newSocket->remoteEndpoint=knIPV4Endpoint_INVALID;
|
||||||
|
newSocket->socketfd=socket(AF_INET, SOCK_STREAM, 0);
|
||||||
|
if(newSocket->socketfd==-1 || newSocket->socketfd == ~0)
|
||||||
|
safethrow("can't create socket", free(newSocket));
|
||||||
|
|
||||||
|
// set value of REUSEADDR socket option
|
||||||
|
int opt_val = allowReuse;
|
||||||
|
if(setsockopt(newSocket->socketfd, SOL_SOCKET, SO_REUSEADDR, (void*)&opt_val, sizeof(opt_val)) != 0)
|
||||||
|
safethrow("can't set socket options", free(newSocket));
|
||||||
|
|
||||||
|
return SUCCESS(UniHeapPtr(knSocketTCP, newSocket));
|
||||||
|
}
|
||||||
|
|
||||||
|
Maybe knSocketTCP_shutdown(knSocketTCP* socket, knShutdownType direction){
|
||||||
|
try(__kn_StdSocket_shutdown(socket->socketfd, direction), _m875, ;);
|
||||||
|
return MaybeNull;
|
||||||
|
}
|
||||||
|
|
||||||
|
Maybe knSocketTCP_close(knSocketTCP* socket){
|
||||||
|
try(__kn_StdSocket_close(socket->socketfd), _m875, ;);
|
||||||
|
free(socket);
|
||||||
|
return MaybeNull;
|
||||||
|
}
|
||||||
|
|
||||||
|
Maybe knSocketTCP_bindAndListen(knSocketTCP* socket, knIPV4Endpoint localEndp){
|
||||||
|
struct sockaddr_in servaddr = knIPV4Endpoint_toSockaddr(localEndp);
|
||||||
|
|
||||||
|
if(bind(socket->socketfd, (void*)&servaddr, sizeof(servaddr)) != 0)
|
||||||
|
safethrow("socket bind failed", ;);
|
||||||
|
|
||||||
|
if(listen(socket->socketfd, 1024) != 0)
|
||||||
|
safethrow("socket listen failed", ;);
|
||||||
|
|
||||||
|
socket->localEndpoint = localEndp;
|
||||||
|
return MaybeNull;
|
||||||
|
}
|
||||||
|
|
||||||
|
Maybe knSocketTCP_connect(knSocketTCP* socket, knIPV4Endpoint remoteEnd){
|
||||||
|
struct sockaddr_in servaddr = knIPV4Endpoint_toSockaddr(remoteEnd);
|
||||||
|
|
||||||
|
if(connect(socket->socketfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) !=0)
|
||||||
|
safethrow("socket connect failed",;);
|
||||||
|
|
||||||
|
socket->remoteEndpoint=remoteEnd;
|
||||||
|
return MaybeNull;
|
||||||
|
}
|
||||||
|
|
||||||
|
Maybe knSocketTCP_accept(knSocketTCP* socket){
|
||||||
|
struct sockaddr_in remoteAddr = {0};
|
||||||
|
u64 remoteAddrSize = sizeof(remoteAddr);
|
||||||
|
|
||||||
|
i64 client_fd = accept(socket->socketfd, (struct sockaddr*)&remoteAddr, (void*)&remoteAddrSize);
|
||||||
|
if(client_fd == -1 || client_fd == ~0)
|
||||||
|
safethrow("can't accept client connection", ;);
|
||||||
|
|
||||||
|
// if accept() didn't set remoteAddr for some reason
|
||||||
|
if(remoteAddr.sin_addr.s_addr == 0 && remoteAddr.sin_port == 0 && remoteAddr.sin_family == 0){
|
||||||
|
if(getpeername(client_fd, (struct sockaddr*)&remoteAddr, (void*)&remoteAddrSize) != 0)
|
||||||
|
safethrow("can't get connected client address", ;);
|
||||||
|
}
|
||||||
|
|
||||||
|
knSocketTCP* clientSocket = malloc(sizeof(knSocketTCP));
|
||||||
|
clientSocket->socketfd = client_fd;
|
||||||
|
clientSocket->localEndpoint = socket->localEndpoint;
|
||||||
|
clientSocket->remoteEndpoint = knIPV4Endpoint_fromSockaddr(remoteAddr);
|
||||||
|
return SUCCESS(UniHeapPtr(knSocketTCP, clientSocket));
|
||||||
|
}
|
||||||
|
|
||||||
|
Maybe knSocketTCP_send(knSocketTCP* socket, char* buffer, u32 dataLength){
|
||||||
|
u32 sentTotal = 0;
|
||||||
|
while(sentTotal < dataLength){
|
||||||
|
int sentCount = send(socket->socketfd, buffer+sentTotal, dataLength-sentTotal, 0);
|
||||||
|
if(sentCount == -1){
|
||||||
|
safethrow(
|
||||||
|
cptr_concat("can't send ", toString_u64(dataLength-sentTotal,0,0),
|
||||||
|
" bytes out of ", toString_u64(dataLength,0,0),
|
||||||
|
" at index ", toString_u64(sentTotal,0,0)
|
||||||
|
),
|
||||||
|
;);
|
||||||
|
}
|
||||||
|
sentTotal += sentCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
return MaybeNull;
|
||||||
|
}
|
||||||
|
|
||||||
|
Maybe knSocketTCP_receive(knSocketTCP* socket, char* buffer, u32 bufferLength){
|
||||||
|
int receivedCount = recv(socket->socketfd, buffer, bufferLength, 0);
|
||||||
|
if(receivedCount == -1 || receivedCount == 0)
|
||||||
|
safethrow("can't receive data from socket", ;)
|
||||||
|
|
||||||
|
return SUCCESS(UniUInt64(receivedCount));
|
||||||
|
}
|
||||||
56
src/Network/sockets/knSocketTCP.h
Normal file
56
src/Network/sockets/knSocketTCP.h
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#if __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "../network_types.h"
|
||||||
|
|
||||||
|
STRUCT(knSocketTCP,
|
||||||
|
i64 socketfd;
|
||||||
|
knIPV4Endpoint localEndpoint;
|
||||||
|
knIPV4Endpoint remoteEndpoint;
|
||||||
|
/* TODO socket status enum */
|
||||||
|
)
|
||||||
|
|
||||||
|
///@note EXAMPLE 1: socket = open(false); bind(socket, localhost:8080); close(socket); - the socket on port 8080 still unavaliable for several minutes
|
||||||
|
///@note EXAMPLE 2: socket = open(true); bind(socket, localhost:8080); close(socket); - the socket on port 8080 can be opened again
|
||||||
|
///@param allowReuse enables binding multiple sockets to single port. Set to TRUE on a listening socket if you want to bind it to the same port after close.
|
||||||
|
///@return Maybe<knSocketTCP*> new socket
|
||||||
|
Maybe knSocketTCP_open(bool allowReuse);
|
||||||
|
|
||||||
|
///@param direction receive/send/both
|
||||||
|
///@return Maybe<void> error or nothing
|
||||||
|
Maybe knSocketTCP_shutdown(knSocketTCP* socket, knShutdownType direction);
|
||||||
|
|
||||||
|
/// closes file descriptor and frees socket pointer
|
||||||
|
///@return Maybe<void> error or nothing
|
||||||
|
Maybe knSocketTCP_close(knSocketTCP* socket);
|
||||||
|
|
||||||
|
/// binds socket to a local endpoint and starts listening for incoming TCP connections
|
||||||
|
///@return Maybe<void> error or nothing
|
||||||
|
Maybe knSocketTCP_bindAndListen(knSocketTCP* socket, knIPV4Endpoint localEndp);
|
||||||
|
|
||||||
|
/// establishes TCP connection with a remote endpoint
|
||||||
|
///@return Maybe<void> error or nothing
|
||||||
|
Maybe knSocketTCP_connect(knSocketTCP* socket, knIPV4Endpoint remoteEnd);
|
||||||
|
|
||||||
|
///@return Maybe<knSocketTCP*> new socket connected to client
|
||||||
|
Maybe knSocketTCP_accept(knSocketTCP* socket);
|
||||||
|
|
||||||
|
/// sends <dataLength> bytes from buffer
|
||||||
|
///@param buffer buffer for receiving data
|
||||||
|
///@param dataLength 0-4294967295
|
||||||
|
///@return Maybe<void>
|
||||||
|
Maybe knSocketTCP_send(knSocketTCP* socket, char* buffer, u32 dataLength);
|
||||||
|
|
||||||
|
/// receives a package of any size
|
||||||
|
/// (by TCP 32 bytes han be sent as 32x1byte, 4x8byte, 32x1byte or in any other combination)
|
||||||
|
///@param buffer buffer for receiving data
|
||||||
|
///@param bufferLength 0-4294967295
|
||||||
|
///@return Maybe<u64> received bytes amount
|
||||||
|
Maybe knSocketTCP_receive(knSocketTCP* socket, char* buffer, u32 bufferLength);
|
||||||
|
|
||||||
|
#if __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
86
src/Network/sockets/knSocketUDP.c
Normal file
86
src/Network/sockets/knSocketUDP.c
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
#include "../network_internal.h"
|
||||||
|
|
||||||
|
void __knSocketUDP_close(void* p){ knSocketUDP_close(p); }
|
||||||
|
|
||||||
|
kt_define(knSocketUDP, __knSocketUDP_close, NULL);
|
||||||
|
|
||||||
|
Maybe knSocketUDP_open(bool allowReuse){
|
||||||
|
knSocketUDP* newSocket=malloc(sizeof(knSocketUDP));
|
||||||
|
newSocket->localEndpoint=knIPV4Endpoint_INVALID;
|
||||||
|
newSocket->socketfd=socket(AF_INET, SOCK_DGRAM, 0);
|
||||||
|
if(newSocket->socketfd==-1 || newSocket->socketfd == ~0)
|
||||||
|
safethrow("can't create socket", free(newSocket));
|
||||||
|
|
||||||
|
// set value of REUSEADDR socket option
|
||||||
|
int opt_val = allowReuse;
|
||||||
|
if(setsockopt(newSocket->socketfd, SOL_SOCKET, SO_REUSEADDR, (void*)&opt_val, sizeof(opt_val)) != 0)
|
||||||
|
safethrow("can't set socket options", free(newSocket));
|
||||||
|
|
||||||
|
return SUCCESS(UniHeapPtr(knSocketUDP, newSocket));
|
||||||
|
}
|
||||||
|
|
||||||
|
Maybe knSocketUDP_shutdown(knSocketUDP* socket, knShutdownType direction){
|
||||||
|
try(__kn_StdSocket_shutdown(socket->socketfd, direction), _m875, ;);
|
||||||
|
return MaybeNull;
|
||||||
|
}
|
||||||
|
|
||||||
|
Maybe knSocketUDP_close(knSocketUDP* socket){
|
||||||
|
try(__kn_StdSocket_close(socket->socketfd), _m875, ;);
|
||||||
|
free(socket);
|
||||||
|
return MaybeNull;
|
||||||
|
}
|
||||||
|
|
||||||
|
Maybe knSocketUDP_bind(knSocketUDP* socket, knIPV4Endpoint localEndp){
|
||||||
|
struct sockaddr_in servaddr = {
|
||||||
|
.sin_family = AF_INET,
|
||||||
|
.sin_addr.s_addr = localEndp.address.UintBigEndian,
|
||||||
|
.sin_port = htons(localEndp.port) /* transforms port to big endian */
|
||||||
|
};
|
||||||
|
|
||||||
|
if(bind(socket->socketfd, (void*)&servaddr, sizeof(servaddr)) != 0)
|
||||||
|
safethrow("socket bind failed", ;);
|
||||||
|
|
||||||
|
socket->localEndpoint = localEndp;
|
||||||
|
return MaybeNull;
|
||||||
|
}
|
||||||
|
|
||||||
|
Maybe knSocketUDP_sendTo(knSocketUDP* socket, char* buffer, u32 dataLength, knIPV4Endpoint destEnd){
|
||||||
|
struct sockaddr_in dest_saddr = knIPV4Endpoint_toSockaddr(destEnd);
|
||||||
|
u32 sentCount = sendto(
|
||||||
|
socket->socketfd,
|
||||||
|
buffer,
|
||||||
|
dataLength,
|
||||||
|
0,
|
||||||
|
(struct sockaddr*)&dest_saddr,
|
||||||
|
sizeof(struct sockaddr_in)
|
||||||
|
);
|
||||||
|
|
||||||
|
if(sentCount != dataLength) {
|
||||||
|
safethrow(
|
||||||
|
cptr_concat("can't send ", toString_u64(dataLength-sentCount,0,0),
|
||||||
|
" bytes out of ", toString_u64(dataLength,0,0)
|
||||||
|
),
|
||||||
|
;);
|
||||||
|
}
|
||||||
|
|
||||||
|
return MaybeNull;
|
||||||
|
}
|
||||||
|
|
||||||
|
Maybe knSocketUDP_receiveAny(knSocketUDP* socket, char* buffer, u32 bufferLength, knIPV4Endpoint* senderEnd){
|
||||||
|
struct sockaddr_in remote_saddr = {0};
|
||||||
|
u64 remote_saddr_size = sizeof(remote_saddr);
|
||||||
|
int receivedCount = recvfrom(
|
||||||
|
socket->socketfd,
|
||||||
|
buffer,
|
||||||
|
bufferLength,
|
||||||
|
0,
|
||||||
|
(struct sockaddr*)&remote_saddr,
|
||||||
|
(void*)&remote_saddr_size
|
||||||
|
);
|
||||||
|
|
||||||
|
if(receivedCount == -1 || receivedCount == 0)
|
||||||
|
safethrow("can't receive data from socket", ;)
|
||||||
|
|
||||||
|
*senderEnd = knIPV4Endpoint_fromSockaddr(remote_saddr);
|
||||||
|
return SUCCESS(UniUInt64(receivedCount));
|
||||||
|
}
|
||||||
49
src/Network/sockets/knSocketUDP.h
Normal file
49
src/Network/sockets/knSocketUDP.h
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#if __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "../network_types.h"
|
||||||
|
|
||||||
|
STRUCT(knSocketUDP,
|
||||||
|
i64 socketfd;
|
||||||
|
knIPV4Endpoint localEndpoint;
|
||||||
|
/* TODO socket status enum */
|
||||||
|
)
|
||||||
|
|
||||||
|
///@note EXAMPLE 1: socket = open(false); bind(socket, localhost:8080); close(socket); - the socket on port 8080 still unavaliable for several minutes
|
||||||
|
///@note EXAMPLE 2: socket = open(true); bind(socket, localhost:8080); close(socket); - the socket on port 8080 can be opened again
|
||||||
|
///@param allowReuse enables binding multiple sockets to single port. Set to TRUE on a listening socket if you want to bind it to the same port after close.
|
||||||
|
///@return Maybe<knSocketUDP*> new socket
|
||||||
|
Maybe knSocketUDP_open(bool allowReuse);
|
||||||
|
|
||||||
|
///@param direction receive/send/both
|
||||||
|
///@return Maybe<void> error or nothing
|
||||||
|
Maybe knSocketUDP_shutdown(knSocketUDP* socket, knShutdownType direction);
|
||||||
|
|
||||||
|
/// closes file descriptor and frees socket pointer
|
||||||
|
///@return Maybe<void> error or nothing
|
||||||
|
Maybe knSocketUDP_close(knSocketUDP* socket);
|
||||||
|
|
||||||
|
/// binds socket to a local endpoint
|
||||||
|
///@return Maybe<void> error or nothing
|
||||||
|
Maybe knSocketUDP_bind(knSocketUDP* socket, knIPV4Endpoint localEndp);
|
||||||
|
|
||||||
|
/// sends one package to destination endpoint
|
||||||
|
///@param buffer buffer for receiving data
|
||||||
|
///@param dataLength 0-64k
|
||||||
|
///@param destEnd destination endpoint
|
||||||
|
///@return Maybe<void>
|
||||||
|
Maybe knSocketUDP_sendTo(knSocketUDP* socket, char* buffer, u32 dataLength, knIPV4Endpoint destEnd);
|
||||||
|
|
||||||
|
/// receives one package from anywhere
|
||||||
|
///@param buffer buffer for receiving data
|
||||||
|
///@param bufferLength 0-64k
|
||||||
|
///@param senderEnd [OUT] endpoint UPD package was sent from
|
||||||
|
///@return Maybe<u64> received bytes amount
|
||||||
|
Maybe knSocketUDP_receiveAny(knSocketUDP* socket, char* buffer, u32 bufferLength, knIPV4Endpoint* senderEnd);
|
||||||
|
|
||||||
|
#if __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
@@ -160,7 +160,7 @@ char* __cptr_concat(u32 n, ...){
|
|||||||
char* output=totality;
|
char* output=totality;
|
||||||
totality[totalLength]=0;
|
totality[totalLength]=0;
|
||||||
|
|
||||||
// copying content of all strings to rezult
|
// copying content of all strings to result
|
||||||
for(u16 k=0; k<n; k++){
|
for(u16 k=0; k<n; k++){
|
||||||
memcopy(strs[k], totality, lengths[k]);
|
memcopy(strs[k], totality, lengths[k]);
|
||||||
totality+=lengths[k];
|
totality+=lengths[k];
|
||||||
@@ -212,6 +212,6 @@ char* cptr_replaceIn(const char* src, const char* str_old, const char* str_new,
|
|||||||
u32 src_remains_len=cptr_length(src);
|
u32 src_remains_len=cptr_length(src);
|
||||||
if(src_remains_len>0)
|
if(src_remains_len>0)
|
||||||
StringBuilder_append_string(sb, (string){.ptr=(char*)src, .length=src_remains_len});
|
StringBuilder_append_string(sb, (string){.ptr=(char*)src, .length=src_remains_len});
|
||||||
string rezult=StringBuilder_build(sb);
|
string result=StringBuilder_build(sb);
|
||||||
return rezult.ptr;
|
return result.ptr;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,23 +25,23 @@ char* errname(ErrorId err){
|
|||||||
|
|
||||||
char* __genErrMsg(const char* errmsg, const char* srcfile, i32 line, const char* funcname){
|
char* __genErrMsg(const char* errmsg, const char* srcfile, i32 line, const char* funcname){
|
||||||
size_t bufsize=ERRMSG_MAXLENGTH;
|
size_t bufsize=ERRMSG_MAXLENGTH;
|
||||||
char* rezult=malloc(bufsize);
|
char* result=malloc(bufsize);
|
||||||
IFMSC(
|
IFMSC(
|
||||||
sprintf_s(rezult,bufsize,"[%s:%d] %s() throwed error: %s",srcfile,line,funcname,errmsg),
|
sprintf_s(result,bufsize,"[%s:%d] %s() throwed error: %s",srcfile,line,funcname,errmsg),
|
||||||
sprintf(rezult,"[%s:%d] %s() throwed error: %s",srcfile,line,funcname,errmsg)
|
sprintf(result,"[%s:%d] %s() throwed error: %s",srcfile,line,funcname,errmsg)
|
||||||
);
|
);
|
||||||
return rezult;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
char* __extendErrMsg(const char* errmsg, const char* srcfile, i32 line, const char* funcname){
|
char* __extendErrMsg(const char* errmsg, const char* srcfile, i32 line, const char* funcname){
|
||||||
size_t bufsize=cptr_length(errmsg)+ERRMSG_MAXLENGTH;
|
size_t bufsize=cptr_length(errmsg)+ERRMSG_MAXLENGTH;
|
||||||
char* rezult=malloc(bufsize);
|
char* result=malloc(bufsize);
|
||||||
IFMSC(
|
IFMSC(
|
||||||
sprintf_s(rezult,bufsize,"%s\n \\___[%s:%d] %s()",errmsg,srcfile,line,funcname),
|
sprintf_s(result,bufsize,"%s\n \\___[%s:%d] %s()",errmsg,srcfile,line,funcname),
|
||||||
sprintf(rezult,"%s\n \\___[%s:%d] %s()",errmsg,srcfile,line,funcname)
|
sprintf(result,"%s\n \\___[%s:%d] %s()",errmsg,srcfile,line,funcname)
|
||||||
);
|
);
|
||||||
free(errmsg);
|
free(errmsg);
|
||||||
return rezult;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Maybe_free(Maybe e){
|
void Maybe_free(Maybe e){
|
||||||
|
|||||||
@@ -60,10 +60,10 @@ char* __unknownErr( );
|
|||||||
__RETURN_EXCEPTION(((char*)__genErrMsg(E, __FILE__,__LINE__,__func__))); \
|
__RETURN_EXCEPTION(((char*)__genErrMsg(E, __FILE__,__LINE__,__func__))); \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define try_cpp(_funcCall, _rezult, freeMem) Maybe _rezult=_funcCall; if(_rezult.errmsg){ \
|
#define try_cpp(_funcCall, _result, freeMem) Maybe _result=_funcCall; if(_result.errmsg){ \
|
||||||
freeMem; \
|
freeMem; \
|
||||||
_rezult.errmsg=__extendErrMsg(_rezult.errmsg, __FILE__,__LINE__,__func__); \
|
_result.errmsg=__extendErrMsg(_result.errmsg, __FILE__,__LINE__,__func__); \
|
||||||
return _rezult; \
|
return _result; \
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
@@ -73,16 +73,16 @@ char* __unknownErr( );
|
|||||||
__RETURN_EXCEPTION(((char*)__genErrMsg((__stringify_err(E)), __FILE__,__LINE__,__func__))); \
|
__RETURN_EXCEPTION(((char*)__genErrMsg((__stringify_err(E)), __FILE__,__LINE__,__func__))); \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define try(_funcCall, _rezult, freeMem) Maybe _rezult=_funcCall; if(_rezult.errmsg){ \
|
#define try(_funcCall, _result, freeMem) Maybe _result=_funcCall; if(_result.errmsg){ \
|
||||||
freeMem; \
|
freeMem; \
|
||||||
_rezult.errmsg=__extendErrMsg(_rezult.errmsg, __FILE__,__LINE__,__func__); \
|
_result.errmsg=__extendErrMsg(_result.errmsg, __FILE__,__LINE__,__func__); \
|
||||||
return _rezult; \
|
return _result; \
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define tryLast(_funcCall, _rezult, ON_EXIT) Maybe _rezult=_funcCall; if(_rezult.errmsg){ \
|
#define tryLast(_funcCall, _result, ON_EXIT) Maybe _result=_funcCall; if(_result.errmsg){ \
|
||||||
_rezult.errmsg=__extendErrMsg(_rezult.errmsg, __FILE__,__LINE__,__func__); \
|
_result.errmsg=__extendErrMsg(_result.errmsg, __FILE__,__LINE__,__func__); \
|
||||||
__EXIT(_rezult.errmsg); \
|
__EXIT(_result.errmsg); \
|
||||||
}
|
}
|
||||||
|
|
||||||
#if __cplusplus
|
#if __cplusplus
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
#include "../../Hashtable/Hashtable.h"
|
#include "../../Hashtable/Hashtable.h"
|
||||||
#include "../../String/StringBuilder.h"
|
#include "../../String/StringBuilder.h"
|
||||||
#include "../../Filesystem/filesystem.h"
|
#include "../../Filesystem/filesystem.h"
|
||||||
|
#include "../../Network/network.h"
|
||||||
#include "base_toString.h"
|
#include "base_toString.h"
|
||||||
|
|
||||||
void kt_initKerepTypes(){
|
void kt_initKerepTypes(){
|
||||||
@@ -84,4 +85,11 @@ void kt_initKerepTypes(){
|
|||||||
|
|
||||||
// File
|
// File
|
||||||
kt_register(FileHandle);
|
kt_register(FileHandle);
|
||||||
|
|
||||||
|
// Network
|
||||||
|
kt_register(knIPV4Address);
|
||||||
|
kt_register(knIPV4Endpoint);
|
||||||
|
kt_register(knSocketTCP);
|
||||||
|
kt_register(knSocketUDP);
|
||||||
|
kt_register(knSocketChanneled);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -52,9 +52,14 @@ ktid ktid_last=-1;
|
|||||||
ENUM(ktDescriptorsState,
|
ENUM(ktDescriptorsState,
|
||||||
NotInitialized, Initializing, Initialized
|
NotInitialized, Initializing, Initialized
|
||||||
)
|
)
|
||||||
|
|
||||||
ktDescriptorsState initState=NotInitialized;
|
ktDescriptorsState initState=NotInitialized;
|
||||||
|
|
||||||
void kt_beginInit(){
|
bool _printDebugMessages = false;
|
||||||
|
|
||||||
|
void kt_beginInit(bool printDebugMessages){
|
||||||
|
_printDebugMessages = printDebugMessages;
|
||||||
|
if(printDebugMessages)
|
||||||
kprintf("\e[94mtype descriptors initializing...\n");
|
kprintf("\e[94mtype descriptors initializing...\n");
|
||||||
__descriptorPointers=Autoarr_create(Pointer, 256, 256);
|
__descriptorPointers=Autoarr_create(Pointer, 256, 256);
|
||||||
}
|
}
|
||||||
@@ -65,6 +70,7 @@ void kt_endInit(){
|
|||||||
typeDescriptors=(ktDescriptor**)Autoarr_toArray(__descriptorPointers);
|
typeDescriptors=(ktDescriptor**)Autoarr_toArray(__descriptorPointers);
|
||||||
Autoarr_free(__descriptorPointers,true);
|
Autoarr_free(__descriptorPointers,true);
|
||||||
if(typeDescriptors==NULL) throw(ERR_NULLPTR);
|
if(typeDescriptors==NULL) throw(ERR_NULLPTR);
|
||||||
|
if(_printDebugMessages)
|
||||||
kprintf("\e[92minitialized %u type descriptors\n", ktid_last);
|
kprintf("\e[92minitialized %u type descriptors\n", ktid_last);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -74,10 +80,9 @@ void __kt_register(ktDescriptor* descriptor){
|
|||||||
}
|
}
|
||||||
|
|
||||||
ktDescriptor* ktDescriptor_get(ktid id){
|
ktDescriptor* ktDescriptor_get(ktid id){
|
||||||
if(id>ktid_last || id==ktid_undefined) {
|
if(id>ktid_last || id==ktid_undefined)
|
||||||
kprintf("\ntype id: %u\n",id);
|
throw(cptr_concat("invalid type id ", toString_i64(id)));
|
||||||
throw("invalid type id");
|
|
||||||
}
|
|
||||||
return typeDescriptors[id];
|
return typeDescriptors[id];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ void __kt_register(ktDescriptor* descriptor);
|
|||||||
__kt_register(&ktDescriptor_##TYPE##_Ptr); \
|
__kt_register(&ktDescriptor_##TYPE##_Ptr); \
|
||||||
ktid_##TYPE##_Ptr=ktid_last;
|
ktid_##TYPE##_Ptr=ktid_last;
|
||||||
|
|
||||||
void kt_beginInit();
|
void kt_beginInit(bool printDebugMessages);
|
||||||
void kt_endInit();
|
void kt_endInit();
|
||||||
|
|
||||||
/// @param id id of registered type
|
/// @param id id of registered type
|
||||||
|
|||||||
@@ -85,11 +85,11 @@ char *Unitype_toString(Unitype u, u32 fmt)
|
|||||||
valuestr = type->toString(u.VoidPtr, fmt);
|
valuestr = type->toString(u.VoidPtr, fmt);
|
||||||
else
|
else
|
||||||
valuestr = "ERR_NO_TOSTRING_FUNC";
|
valuestr = "ERR_NO_TOSTRING_FUNC";
|
||||||
char *rezult = cptr_concat("{ type: ", type->name, ", allocated on heap: ", (u.allocatedInHeap ? "true" : "false"),
|
char *result = cptr_concat("{ type: ", type->name, ", allocated on heap: ", (u.allocatedInHeap ? "true" : "false"),
|
||||||
", value:", valuestr, " }");
|
", value:", valuestr, " }");
|
||||||
if (type->toString)
|
if (type->toString)
|
||||||
free(valuestr);
|
free(valuestr);
|
||||||
return rezult;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void printuni(Unitype v)
|
void printuni(Unitype v)
|
||||||
|
|||||||
@@ -39,8 +39,8 @@ Maybe __next_toString(kp_fmt f, void* object){
|
|||||||
}
|
}
|
||||||
|
|
||||||
Maybe check_argsN(u8 n){
|
Maybe check_argsN(u8 n){
|
||||||
if(n%2 != 0) safethrow("kprint recieved non-even number of arguments",;);
|
if(n%2 != 0) safethrow("kprint received non-even number of arguments",;);
|
||||||
if(n > 32) safethrow("kprint recieved >32 number of arguments",;);
|
if(n > 32) safethrow("kprint received >32 number of arguments",;);
|
||||||
return MaybeNull;
|
return MaybeNull;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -53,8 +53,8 @@ Maybe __ksprint(u8 n, kp_fmt* formats, __kp_value_union* objects){
|
|||||||
StringBuilder_append_cptr(strb, mStr.value.VoidPtr);
|
StringBuilder_append_cptr(strb, mStr.value.VoidPtr);
|
||||||
Unitype_free(mStr.value);
|
Unitype_free(mStr.value);
|
||||||
}
|
}
|
||||||
char* rezult=StringBuilder_build(strb).ptr;
|
char* result=StringBuilder_build(strb).ptr;
|
||||||
return SUCCESS(UniHeapPtr(char, rezult));
|
return SUCCESS(UniHeapPtr(char, result));
|
||||||
}
|
}
|
||||||
|
|
||||||
Maybe __kfprint(FILE* file, u8 n, kp_fmt* formats, __kp_value_union* objects){
|
Maybe __kfprint(FILE* file, u8 n, kp_fmt* formats, __kp_value_union* objects){
|
||||||
@@ -90,7 +90,6 @@ void __kprint(u8 n, kp_fmt* formats, __kp_value_union* objects){
|
|||||||
#define FOREGROUND_YELLOW FOREGROUND_GREEN | FOREGROUND_RED
|
#define FOREGROUND_YELLOW FOREGROUND_GREEN | FOREGROUND_RED
|
||||||
|
|
||||||
DWORD kp_fgColor_toWin(kp_fgColor f){
|
DWORD kp_fgColor_toWin(kp_fgColor f){
|
||||||
//kprintf("fg: %x\n", f);
|
|
||||||
switch(f){
|
switch(f){
|
||||||
case kp_fgBlack: return 0;
|
case kp_fgBlack: return 0;
|
||||||
case kp_fgRedD: return FOREGROUND_RED;
|
case kp_fgRedD: return FOREGROUND_RED;
|
||||||
@@ -113,7 +112,6 @@ DWORD kp_fgColor_toWin(kp_fgColor f){
|
|||||||
}
|
}
|
||||||
|
|
||||||
DWORD kp_bgColor_toWin(kp_bgColor f){
|
DWORD kp_bgColor_toWin(kp_bgColor f){
|
||||||
//kprintf("bg: %x\n", f);
|
|
||||||
switch(f){
|
switch(f){
|
||||||
case kp_bgBlack: return 0;
|
case kp_bgBlack: return 0;
|
||||||
case kp_bgRedD: return BACKGROUND_RED;
|
case kp_bgRedD: return BACKGROUND_RED;
|
||||||
@@ -199,12 +197,12 @@ static const char* _kp_colorNames[16]={
|
|||||||
"white"
|
"white"
|
||||||
};
|
};
|
||||||
|
|
||||||
char* kp_bgColor_toString(kp_fmt c){
|
char* kp_bgColor_toString(kp_bgColor c){
|
||||||
u32 color_index=(c&0x00f00000)>>20;
|
u32 color_index=(c&0x00f00000)>>20;
|
||||||
if(color_index>15) throw(ERR_WRONGINDEX);
|
if(color_index>15) throw(ERR_WRONGINDEX);
|
||||||
return _kp_colorNames[color_index];
|
return _kp_colorNames[color_index];
|
||||||
}
|
}
|
||||||
char* kp_fgColor_toString(kp_fmt c){
|
char* kp_fgColor_toString(kp_fgColor c){
|
||||||
u32 color_index=(c&0x00f00000)>>24;
|
u32 color_index=(c&0x00f00000)>>24;
|
||||||
if(color_index>15) throw(ERR_WRONGINDEX);
|
if(color_index>15) throw(ERR_WRONGINDEX);
|
||||||
return _kp_colorNames[color_index];
|
return _kp_colorNames[color_index];
|
||||||
|
|||||||
@@ -4,6 +4,8 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "../base/type_system/typedef_macros.h"
|
||||||
|
|
||||||
// 10000000 00000000 00000000 00000000
|
// 10000000 00000000 00000000 00000000
|
||||||
// ^ ^^^^
|
// ^ ^^^^
|
||||||
// | color num
|
// | color num
|
||||||
|
|||||||
@@ -9,6 +9,49 @@ extern "C" {
|
|||||||
// cross-platform printf analog
|
// cross-platform printf analog
|
||||||
void kprintf(const char* format, ...);
|
void kprintf(const char* format, ...);
|
||||||
|
|
||||||
|
// printf format terminal color sequence
|
||||||
|
#define _PRINTF_COLOR(N) "\e["#N"m"
|
||||||
|
|
||||||
|
// foreground dark color codes
|
||||||
|
#define FBLK _PRINTF_COLOR(30)
|
||||||
|
#define FREDD _PRINTF_COLOR(31)
|
||||||
|
#define FGRND _PRINTF_COLOR(32)
|
||||||
|
#define FYELD _PRINTF_COLOR(33)
|
||||||
|
#define FBLUD _PRINTF_COLOR(34)
|
||||||
|
#define FMAGD _PRINTF_COLOR(35)
|
||||||
|
#define FCYND _PRINTF_COLOR(36)
|
||||||
|
#define FGRY _PRINTF_COLOR(37)
|
||||||
|
|
||||||
|
// foreground bright color codes
|
||||||
|
#define FGRYD _PRINTF_COLOR(90)
|
||||||
|
#define FRED _PRINTF_COLOR(91)
|
||||||
|
#define FGRN _PRINTF_COLOR(92)
|
||||||
|
#define FYEL _PRINTF_COLOR(93)
|
||||||
|
#define FBLU _PRINTF_COLOR(94)
|
||||||
|
#define FMAG _PRINTF_COLOR(95)
|
||||||
|
#define FCYN _PRINTF_COLOR(96)
|
||||||
|
#define FWHI _PRINTF_COLOR(97)
|
||||||
|
|
||||||
|
// background dark color codes
|
||||||
|
#define BBLK _PRINTF_COLOR(40)
|
||||||
|
#define BREDD _PRINTF_COLOR(41)
|
||||||
|
#define BGRND _PRINTF_COLOR(42)
|
||||||
|
#define BYELD _PRINTF_COLOR(43)
|
||||||
|
#define BBLUD _PRINTF_COLOR(44)
|
||||||
|
#define BMAGD _PRINTF_COLOR(45)
|
||||||
|
#define BCYND _PRINTF_COLOR(46)
|
||||||
|
#define BGRY _PRINTF_COLOR(47)
|
||||||
|
|
||||||
|
// background bright color codes
|
||||||
|
#define BGRYD _PRINTF_COLOR(100)
|
||||||
|
#define BRED _PRINTF_COLOR(101)
|
||||||
|
#define BGRN _PRINTF_COLOR(102)
|
||||||
|
#define BYEL _PRINTF_COLOR(103)
|
||||||
|
#define BBLU _PRINTF_COLOR(104)
|
||||||
|
#define BMAG _PRINTF_COLOR(105)
|
||||||
|
#define BCYN _PRINTF_COLOR(106)
|
||||||
|
#define BWHI _PRINTF_COLOR(107)
|
||||||
|
|
||||||
#if __cplusplus
|
#if __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -3,11 +3,11 @@
|
|||||||
i32 main(){
|
i32 main(){
|
||||||
if(setlocale(LC_CTYPE, "C.UTF-8")!=0)
|
if(setlocale(LC_CTYPE, "C.UTF-8")!=0)
|
||||||
kprintf("\e[93msetlocale failed\n");
|
kprintf("\e[93msetlocale failed\n");
|
||||||
kt_beginInit();
|
kt_beginInit(true);
|
||||||
kt_initKerepTypes();
|
kt_initKerepTypes();
|
||||||
kt_endInit();
|
kt_endInit();
|
||||||
test_all();
|
test_all();
|
||||||
kt_free();
|
kt_free();
|
||||||
kprintf("\e[0m\n");
|
kprintf("\e[37m\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ void test_kprint(){
|
|||||||
//int
|
//int
|
||||||
kprint(kp_fgCyan|
|
kprint(kp_fgCyan|
|
||||||
kp_i,-8888, kp_c,' ', kp_i,0, kp_c,' ', kp_i,1234567890987654321LL,kp_s,"\n");
|
kp_i,-8888, kp_c,' ', kp_i,0, kp_c,' ', kp_i,1234567890987654321LL,kp_s,"\n");
|
||||||
//u
|
//uint
|
||||||
kprint(kp_fgGreen|
|
kprint(kp_fgGreen|
|
||||||
kp_u|kp_post,-8888, kp_c|kp_post|kp_upper,' ', kp_u,0, kp_c,' ',
|
kp_u|kp_post,-8888, kp_c|kp_post|kp_upper,' ', kp_u,0, kp_c,' ',
|
||||||
kp_u,1234567890987654321LL, kp_c,'\n');
|
kp_u,1234567890987654321LL, kp_c,'\n');
|
||||||
@@ -15,7 +15,7 @@ void test_kprint(){
|
|||||||
kp_f,-1.0f, kp_c,' ', kp_f,0.0f, kp_c,' ', kp_f,1.0f, kp_c,'\n',
|
kp_f,-1.0f, kp_c,' ', kp_f,0.0f, kp_c,' ', kp_f,1.0f, kp_c,'\n',
|
||||||
kp_f|kp_post,0.000020004f, kp_c,' ',
|
kp_f|kp_post,0.000020004f, kp_c,' ',
|
||||||
kp_f|kp_post|kp_upper,4000.0109f, kp_c,'\n');
|
kp_f|kp_post|kp_upper,4000.0109f, kp_c,'\n');
|
||||||
//f64
|
//double
|
||||||
kprint(kp_fgYellowD|
|
kprint(kp_fgYellowD|
|
||||||
kp_f,-4000.0109, kp_c,' ', kp_f,-0.000020004, kp_c,'\n',
|
kp_f,-4000.0109, kp_c,' ', kp_f,-0.000020004, kp_c,'\n',
|
||||||
kp_f,-1.0, kp_c,' ', kp_f,0.0, kp_c,' ', kp_f,1.0, kp_c,'\n',
|
kp_f,-1.0, kp_c,' ', kp_f,0.0, kp_c,' ', kp_f,1.0, kp_c,'\n',
|
||||||
|
|||||||
231
tests/test_network.c
Normal file
231
tests/test_network.c
Normal file
@@ -0,0 +1,231 @@
|
|||||||
|
#include "tests.h"
|
||||||
|
#include "../src/Network/network.h"
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
|
static void __test_knIPV4Address_fromStr(char* addrStr, u8 a, u8 b, u8 c, u8 d){
|
||||||
|
knIPV4Address addr;
|
||||||
|
tryLast(knIPV4Address_fromStr(addrStr, &addr), maybeAddr, ;)
|
||||||
|
kprintf("\e[92mknIPV4Address_fromStr(\e[96m%s\e[92m) -> ", addrStr);
|
||||||
|
if(addr.UintBigEndian != knIPV4Address_fromBytes(a,b,c,d).UintBigEndian){
|
||||||
|
kprintf("\e[91m%u.%u.%u.%u\n",
|
||||||
|
(u8)addr.bytes[0], (u8)addr.bytes[1], (u8)addr.bytes[2], (u8)addr.bytes[3]);
|
||||||
|
throw("knIPV4Address_fromStr returned wrong value");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
kprintf("\e[94m%u.%u.%u.%u\n",
|
||||||
|
(u8)addr.bytes[0], (u8)addr.bytes[1], (u8)addr.bytes[2], (u8)addr.bytes[3]);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
#define test_knIPV4Address_fromStr(a,b,c,d) __test_knIPV4Address_fromStr(#a"."#b"."#c"."#d, a,b,c,d)
|
||||||
|
|
||||||
|
static void test_network_types(){
|
||||||
|
PRINT_SIZEOF(knIPV4Address);
|
||||||
|
PRINT_SIZEOF(knPort);
|
||||||
|
PRINT_SIZEOF(knIPV4Endpoint);
|
||||||
|
PRINT_SIZEOF(knSocketTCP);
|
||||||
|
PRINT_SIZEOF(knSocketUDP);
|
||||||
|
PRINT_SIZEOF(knPackage);
|
||||||
|
PRINT_SIZEOF(knChannel);
|
||||||
|
|
||||||
|
test_knIPV4Address_fromStr(127,0,0,1);
|
||||||
|
test_knIPV4Address_fromStr(34,255,45,0);
|
||||||
|
test_knIPV4Address_fromStr(3,3,3,128);
|
||||||
|
fflush(stdout);
|
||||||
|
}
|
||||||
|
|
||||||
|
static pthread_mutex_t stdout_mutex = {0};
|
||||||
|
|
||||||
|
// thread-safe print
|
||||||
|
#define kprintf_safe(ARGS...) pthread_mutex_lock(&stdout_mutex); kprintf(ARGS); fflush(stdout); pthread_mutex_unlock(&stdout_mutex);
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
knSocketTCP* socket_client;
|
||||||
|
knIPV4Endpoint serverEnd;
|
||||||
|
} tcp_client_connect_async_data;
|
||||||
|
|
||||||
|
void* tcp_client_connect_async(void* _data){
|
||||||
|
tcp_client_connect_async_data* data = _data;
|
||||||
|
tryLast(knSocketTCP_connect(data->socket_client, data->serverEnd), _m8531,;);
|
||||||
|
|
||||||
|
kprintf_safe("\e[92mclient socket connected to server\n");
|
||||||
|
free(data);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_tcp(){
|
||||||
|
kprintf("\e[96m----------[test_network/tcp]----------\n");
|
||||||
|
knIPV4Endpoint serverEnd = knIPV4Endpoint_create(knIPV4Address_LOOPBACK, 4444);
|
||||||
|
knSocketTCP *socket_server, *clientConnection, *socket_client;
|
||||||
|
// server
|
||||||
|
{
|
||||||
|
tryLast(knSocketTCP_open(true), m_socketS, ;);
|
||||||
|
socket_server=m_socketS.value.VoidPtr;
|
||||||
|
kprintf("\e[92mTCP server socket created\n");
|
||||||
|
|
||||||
|
tryLast(knSocketTCP_bindAndListen(socket_server, serverEnd), _m81775, ;)
|
||||||
|
kprintf("\e[92mserver socket is listening\n");
|
||||||
|
}
|
||||||
|
// client
|
||||||
|
{
|
||||||
|
tryLast(knSocketTCP_open(false), m_socketC, ;);
|
||||||
|
socket_client=m_socketC.value.VoidPtr;
|
||||||
|
kprintf("\e[92mTCP client socket created\n");
|
||||||
|
|
||||||
|
tcp_client_connect_async_data* client_connection_data = malloc(sizeof(tcp_client_connect_async_data));
|
||||||
|
client_connection_data->serverEnd = serverEnd;
|
||||||
|
client_connection_data->socket_client = socket_client;
|
||||||
|
pthread_t client_connection_thread;
|
||||||
|
fflush(stdout);
|
||||||
|
if(pthread_create(&client_connection_thread, NULL, tcp_client_connect_async, client_connection_data) != 0)
|
||||||
|
throw("can't create client connection thread");
|
||||||
|
if(pthread_detach(client_connection_thread) != 0)
|
||||||
|
throw("can't detatch client connection thread");
|
||||||
|
}
|
||||||
|
// server
|
||||||
|
{
|
||||||
|
tryLast(knSocketTCP_accept(socket_server), m_connection, ;);
|
||||||
|
clientConnection = m_connection.value.VoidPtr;
|
||||||
|
kprintf_safe("\e[92mserver accepted client connection\n");
|
||||||
|
}
|
||||||
|
// client
|
||||||
|
{
|
||||||
|
const char client_msg[] = "ping";
|
||||||
|
tryLast(knSocketTCP_send(socket_client, client_msg, sizeof(client_msg)), _mu75q2, ;);
|
||||||
|
kprintf("\e[92mmessage sent to server\n\e[94m");
|
||||||
|
}
|
||||||
|
// server
|
||||||
|
{
|
||||||
|
char received_client_msg[32];
|
||||||
|
tryLast(knSocketTCP_receive(clientConnection, received_client_msg, sizeof(received_client_msg)), m_recCount, ;);
|
||||||
|
u64 recCount = m_recCount.value.UInt64;
|
||||||
|
fwrite(received_client_msg, sizeof(char), recCount, stdout);
|
||||||
|
fputc('\n', stdout);
|
||||||
|
if(!cptr_equals(received_client_msg, "ping"))
|
||||||
|
throw("received_client_msg != \"ping\"");
|
||||||
|
kprintf("\e[92mmessage received by server\n");
|
||||||
|
|
||||||
|
const char server_msg[] = "pong";
|
||||||
|
tryLast(knSocketTCP_send(clientConnection, server_msg, sizeof(server_msg)), _mu75q2, ;);
|
||||||
|
kprintf("\e[92mmessage sent to client\n\e[94m");
|
||||||
|
fflush(stdout);
|
||||||
|
}
|
||||||
|
// client
|
||||||
|
{
|
||||||
|
char received_server_msg[32];
|
||||||
|
tryLast(knSocketTCP_receive(socket_client, received_server_msg, sizeof(received_server_msg)), m_recCount, ;);
|
||||||
|
u64 recCount = m_recCount.value.UInt64;
|
||||||
|
fwrite(received_server_msg, sizeof(char), recCount, stdout);
|
||||||
|
fputc('\n', stdout);
|
||||||
|
if(!cptr_equals(received_server_msg, "pong"))
|
||||||
|
throw("received_server_msg != \"pong\"");
|
||||||
|
kprintf("\e[92mmessage received by client\n");
|
||||||
|
fflush(stdout);
|
||||||
|
}
|
||||||
|
// server
|
||||||
|
{
|
||||||
|
tryLast(knSocketTCP_shutdown(clientConnection, knShutdownType_Both), _m2351, ;);
|
||||||
|
tryLast(knSocketTCP_close(clientConnection), _m9776, ;);
|
||||||
|
kprintf("\e[92mclient connection closed\n");
|
||||||
|
|
||||||
|
tryLast(knSocketTCP_close(socket_server), _m676, ;);
|
||||||
|
kprintf("\e[92mTCP server socket closed\n");
|
||||||
|
}
|
||||||
|
// client
|
||||||
|
{
|
||||||
|
tryLast(knSocketTCP_close(socket_client), _m964, ;);
|
||||||
|
kprintf("\e[92mTCP client socket closed\n");
|
||||||
|
}
|
||||||
|
fflush(stdout);
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_udp(){
|
||||||
|
kprintf("\e[96m----------[test_network/udp]----------\n");
|
||||||
|
knIPV4Endpoint serverEnd = knIPV4Endpoint_create(knIPV4Address_LOOPBACK, 4444);
|
||||||
|
knSocketUDP *socket_server, *socket_client;
|
||||||
|
// server
|
||||||
|
{
|
||||||
|
tryLast(knSocketUDP_open(true), m_socketS, ;);
|
||||||
|
socket_server=m_socketS.value.VoidPtr;
|
||||||
|
kprintf("\e[92mUDP server socket created\n");
|
||||||
|
|
||||||
|
tryLast(knSocketUDP_bind(socket_server, serverEnd), _m81775, ;)
|
||||||
|
kprintf("\e[92mserver socket is bound\n");
|
||||||
|
}
|
||||||
|
// client
|
||||||
|
{
|
||||||
|
tryLast(knSocketUDP_open(false), m_socketC, ;);
|
||||||
|
socket_client=m_socketC.value.VoidPtr;
|
||||||
|
kprintf("\e[92mUDP client socket created\n");
|
||||||
|
|
||||||
|
const char client_msg[] = "ping";
|
||||||
|
tryLast(knSocketUDP_sendTo(socket_client, client_msg, sizeof(client_msg), serverEnd), _mu75q2, ;);
|
||||||
|
kprintf("\e[92mmessage sent to server\n\e[94m");
|
||||||
|
}
|
||||||
|
// server
|
||||||
|
{
|
||||||
|
char received_client_msg[32];
|
||||||
|
knIPV4Endpoint clientEnd = knIPV4Endpoint_INVALID;
|
||||||
|
tryLast(knSocketUDP_receiveAny(socket_server, received_client_msg, sizeof(received_client_msg), &clientEnd), m_recCount, ;);
|
||||||
|
u64 recCount = m_recCount.value.UInt64;
|
||||||
|
fwrite(received_client_msg, sizeof(char), recCount, stdout);
|
||||||
|
fputc('\n', stdout);
|
||||||
|
if(!cptr_equals(received_client_msg, "ping"))
|
||||||
|
throw("received_client_msg != \"ping\"");
|
||||||
|
kprintf("\e[92mmessage received by server\n");
|
||||||
|
|
||||||
|
const char server_msg[] = "pong";
|
||||||
|
tryLast(knSocketUDP_sendTo(socket_server, server_msg, sizeof(server_msg), clientEnd), _mu75q2, ;);
|
||||||
|
char* adrstr = knIPV4Endpoint_toString(&clientEnd);
|
||||||
|
kprintf("\e[92mmessage sent to client (%s)\n\e[94m", adrstr);
|
||||||
|
free(adrstr);
|
||||||
|
fflush(stdout);
|
||||||
|
}
|
||||||
|
// client
|
||||||
|
{
|
||||||
|
char received_server_msg[32];
|
||||||
|
knIPV4Endpoint senderEnd = knIPV4Endpoint_INVALID;
|
||||||
|
tryLast(knSocketUDP_receiveAny(socket_client, received_server_msg, sizeof(received_server_msg), &senderEnd), m_recCount, ;);
|
||||||
|
u64 recCount = m_recCount.value.UInt64;
|
||||||
|
fwrite(received_server_msg, sizeof(char), recCount, stdout);
|
||||||
|
fputc('\n', stdout);
|
||||||
|
if(!cptr_equals(received_server_msg, "pong"))
|
||||||
|
throw("received_server_msg != \"pong\"");
|
||||||
|
char* adrstr = knIPV4Endpoint_toString(&serverEnd);
|
||||||
|
kprintf("\e[92mmessage received by client (%s)\n", adrstr);
|
||||||
|
free(adrstr);
|
||||||
|
fflush(stdout);
|
||||||
|
}
|
||||||
|
// server
|
||||||
|
{
|
||||||
|
tryLast(knSocketUDP_close(socket_server), _m676, ;);
|
||||||
|
kprintf("\e[92mUDP server socket closed\n");
|
||||||
|
}
|
||||||
|
// client
|
||||||
|
{
|
||||||
|
tryLast(knSocketUDP_close(socket_client), _m964, ;);
|
||||||
|
kprintf("\e[92mUDP client socket closed\n");
|
||||||
|
}
|
||||||
|
fflush(stdout);
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_network(){
|
||||||
|
optime(__func__,1,({
|
||||||
|
kprintf("\e[96m------------[test_network]------------\n");
|
||||||
|
tryLast(kn_tryInit(), _mjj64g, ;);
|
||||||
|
kprintf("\e[92mkerepNetwork initialized\n");
|
||||||
|
|
||||||
|
if(pthread_mutex_init(&stdout_mutex, NULL) != 0)
|
||||||
|
throw("can't init mutex");
|
||||||
|
|
||||||
|
test_network_types();
|
||||||
|
test_tcp();
|
||||||
|
test_udp();
|
||||||
|
|
||||||
|
if(pthread_mutex_destroy(&stdout_mutex) != 0)
|
||||||
|
throw("can't destroy mutex");
|
||||||
|
|
||||||
|
tryLast(kt_tryDispose(), _m88ag, ;);
|
||||||
|
kprintf("\e[92mkerepNetwork disposed\n");
|
||||||
|
}));
|
||||||
|
}
|
||||||
@@ -19,6 +19,7 @@ void test_rng_algorithms();
|
|||||||
void test_kprint_colors();
|
void test_kprint_colors();
|
||||||
void test_kprint();
|
void test_kprint();
|
||||||
void test_type_system();
|
void test_type_system();
|
||||||
|
void test_network();
|
||||||
|
|
||||||
inline void test_all(){
|
inline void test_all(){
|
||||||
kprintf("\e[97mkerep tests are starting!\n");
|
kprintf("\e[97mkerep tests are starting!\n");
|
||||||
@@ -36,6 +37,7 @@ inline void test_all(){
|
|||||||
test_hash_functions();
|
test_hash_functions();
|
||||||
test_hashtable();
|
test_hashtable();
|
||||||
test_dtsod();
|
test_dtsod();
|
||||||
|
test_network();
|
||||||
kprintf("\e[96m--------------------------------------\e[0m\n");
|
kprintf("\e[96m--------------------------------------\e[0m\n");
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user