mirror of
https://github.com/CPunch/Laika.git
synced 2025-09-26 20:00:08 +00:00
Inital commit
lib/ is just [FoxNet](https://git.openpunk.com/CPunch/FoxNet) ported to C99
This commit is contained in:
54
lib/include/hashmap.h
Normal file
54
lib/include/hashmap.h
Normal file
@@ -0,0 +1,54 @@
|
||||
// Copyright 2020 Joshua J Baker. All rights reserved.
|
||||
// Use of this source code is governed by an MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
#ifndef HASHMAP_H
|
||||
#define HASHMAP_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
struct hashmap;
|
||||
|
||||
struct hashmap *hashmap_new(size_t elsize, size_t cap,
|
||||
uint64_t seed0, uint64_t seed1,
|
||||
uint64_t (*hash)(const void *item,
|
||||
uint64_t seed0, uint64_t seed1),
|
||||
int (*compare)(const void *a, const void *b,
|
||||
void *udata),
|
||||
void (*elfree)(void *item),
|
||||
void *udata);
|
||||
struct hashmap *hashmap_new_with_allocator(
|
||||
void *(*malloc)(size_t),
|
||||
void *(*realloc)(void *, size_t),
|
||||
void (*free)(void*),
|
||||
size_t elsize, size_t cap,
|
||||
uint64_t seed0, uint64_t seed1,
|
||||
uint64_t (*hash)(const void *item,
|
||||
uint64_t seed0, uint64_t seed1),
|
||||
int (*compare)(const void *a, const void *b,
|
||||
void *udata),
|
||||
void (*elfree)(void *item),
|
||||
void *udata);
|
||||
void hashmap_free(struct hashmap *map);
|
||||
void hashmap_clear(struct hashmap *map, bool update_cap);
|
||||
size_t hashmap_count(struct hashmap *map);
|
||||
bool hashmap_oom(struct hashmap *map);
|
||||
void *hashmap_get(struct hashmap *map, const void *item);
|
||||
void *hashmap_set(struct hashmap *map, void *item);
|
||||
void *hashmap_delete(struct hashmap *map, void *item);
|
||||
void *hashmap_probe(struct hashmap *map, uint64_t position);
|
||||
bool hashmap_scan(struct hashmap *map,
|
||||
bool (*iter)(const void *item, void *udata), void *udata);
|
||||
|
||||
uint64_t hashmap_sip(const void *data, size_t len,
|
||||
uint64_t seed0, uint64_t seed1);
|
||||
uint64_t hashmap_murmur(const void *data, size_t len,
|
||||
uint64_t seed0, uint64_t seed1);
|
||||
|
||||
|
||||
// DEPRECATED: use `hashmap_new_with_allocator`
|
||||
void hashmap_set_allocator(void *(*malloc)(size_t), void (*free)(void*));
|
||||
|
||||
#endif
|
13
lib/include/laika.h
Normal file
13
lib/include/laika.h
Normal file
@@ -0,0 +1,13 @@
|
||||
#ifndef LAIKA_LAIKA_H
|
||||
#define LAIKA_LAIKA_H
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#define ARRAY_START 4
|
||||
|
||||
#endif
|
47
lib/include/lerror.h
Normal file
47
lib/include/lerror.h
Normal file
@@ -0,0 +1,47 @@
|
||||
#ifndef LAIKA_ERROR_H
|
||||
#define LAIKA_ERROR_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <setjmp.h>
|
||||
|
||||
/* defines errorstack size */
|
||||
#define LAIKA_MAXERRORS 32
|
||||
|
||||
/* DO NOT RETURN/GOTO/BREAK or otherwise skip LAIKA_TRYEND */
|
||||
#define LAIKA_TRY if (setjmp(eLaika_errStack[++eLaika_errIndx]) == 0) {
|
||||
#define LAIKA_CATCH } else {
|
||||
#define LAIKA_TRYEND } --eLaika_errIndx;
|
||||
|
||||
/* if eLaika_errIndx is >= 0, we have a safe spot to jump too if an error is thrown */
|
||||
#define LAIKA_ISPROTECTED (eLaika_errIndx >= 0)
|
||||
|
||||
/* CERROR(printf args):
|
||||
if called after a LAIKA_TRY block will jump to the previous LAIKA_CATCH/LAIKA_TRYEND block,
|
||||
otherwise program is exit()'d. if DEBUG is defined printf is called with passed args, else
|
||||
arguments are ignored.
|
||||
*/
|
||||
#ifndef DEBUG
|
||||
#define CERROR(...) { \
|
||||
if (LAIKA_ISPROTECTED) \
|
||||
longjmp(eLaika_errStack[eLaika_errIndx], 1); \
|
||||
else \
|
||||
exit(1); \
|
||||
}
|
||||
#define CWARN(...)
|
||||
#else
|
||||
#define CERROR(...) { \
|
||||
printf("[ERROR] : " __VA_ARGS__); \
|
||||
if (LAIKA_ISPROTECTED) \
|
||||
longjmp(eLaika_errStack[eLaika_errIndx], 1); \
|
||||
else \
|
||||
exit(1); \
|
||||
}
|
||||
|
||||
#define CWARN(...) \
|
||||
printf("[WARN] : " __VA_ARGS__);
|
||||
#endif
|
||||
|
||||
extern int eLaika_errIndx;
|
||||
extern jmp_buf eLaika_errStack[LAIKA_MAXERRORS];
|
||||
|
||||
#endif
|
26
lib/include/lmem.h
Normal file
26
lib/include/lmem.h
Normal file
@@ -0,0 +1,26 @@
|
||||
#ifndef LAIKA_MEM_H
|
||||
#define LAIKA_MEM_H
|
||||
|
||||
#include "laika.h"
|
||||
|
||||
#define GROW_FACTOR 2
|
||||
|
||||
#define laikaM_malloc(sz) laikaM_realloc(NULL, sz)
|
||||
#define laikaM_free(buf) laikaM_realloc(buf, 0)
|
||||
#define laikaM_free(buf) laikaM_realloc(buf, 0)
|
||||
|
||||
#define laikaM_growarray(type, buf, count, capacity) \
|
||||
if (count >= capacity || buf == NULL) { \
|
||||
capacity *= GROW_FACTOR; \
|
||||
buf = (type*)cosmoM_realloc(buf, sizeof(type)*capacity); \
|
||||
}
|
||||
|
||||
/* moves array elements above indx down by numElem, removing numElem elements at indx */
|
||||
#define laikaM_rmvarray(type, buf, count, indx, numElem) { \
|
||||
memmove(&buf[indx], &buf[indx+numElem], ((count-indx)-numElem)*sizeof(type)); \
|
||||
count -= numElem; \
|
||||
}
|
||||
|
||||
void *laikaM_realloc(void *buf, size_t sz);
|
||||
|
||||
#endif
|
10
lib/include/lpacket.h
Normal file
10
lib/include/lpacket.h
Normal file
@@ -0,0 +1,10 @@
|
||||
#ifndef LAIKA_PACKET_H
|
||||
#define LAIKA_PACKET_H
|
||||
|
||||
typedef enum {
|
||||
LAIKAPKT_HANDSHAKE_REQ,
|
||||
LAIKAPKT_HANDSHAKE_RES,
|
||||
LAIKAPKT_MAXNONE
|
||||
} LAIKAPKT_ID;
|
||||
|
||||
#endif
|
25
lib/include/lpeer.h
Normal file
25
lib/include/lpeer.h
Normal file
@@ -0,0 +1,25 @@
|
||||
#ifndef LAIKA_PEER_H
|
||||
#define LAIKA_PEER_H
|
||||
|
||||
#include "laika.h"
|
||||
#include "lsocket.h"
|
||||
#include "lpacket.h"
|
||||
#include "lpolllist.h"
|
||||
|
||||
struct sLaika_peer {
|
||||
struct sLaika_socket sock;
|
||||
struct sLaika_pollList *pList; /* pollList we're active in */
|
||||
void (*pktHandler)(struct sLaika_peer *peer, LAIKAPKT_ID id);
|
||||
size_t pktSize; /* current pkt size */
|
||||
LAIKAPKT_ID pktID; /* current pkt ID */
|
||||
size_t *pktSizeTable; /* const table to pull pkt size data from */
|
||||
bool setPollOut; /* if EPOLLOUT/POLLOUT is set on sock's pollfd */
|
||||
};
|
||||
|
||||
struct sLaika_peer *laikaS_newPeer(void (*pktHandler)(struct sLaika_peer *peer, LAIKAPKT_ID id), struct sLaika_pollList *pList, size_t *pktSizeTable);
|
||||
void laikaS_freePeer(struct sLaika_peer *peer);
|
||||
|
||||
bool laikaS_handlePeerIn(struct sLaika_peer *peer);
|
||||
bool laikaS_handlePeerOut(struct sLaika_peer *peer);
|
||||
|
||||
#endif
|
43
lib/include/lpolllist.h
Normal file
43
lib/include/lpolllist.h
Normal file
@@ -0,0 +1,43 @@
|
||||
#ifndef LAIKA_POLLLIST_H
|
||||
#define LAIKA_POLLLIST_H
|
||||
|
||||
#include "laika.h"
|
||||
#include "lsocket.h"
|
||||
#include "hashmap.h"
|
||||
|
||||
/* number of pollFDs or epollFDs we expect to start with */
|
||||
#define POLLSTARTCAP 8
|
||||
|
||||
struct sLaika_pollEvent {
|
||||
struct sLaika_socket *sock;
|
||||
bool pollIn;
|
||||
bool pollOut;
|
||||
};
|
||||
|
||||
struct sLaika_pollList {
|
||||
struct hashmap *sockets;
|
||||
struct sLaika_pollEvent *revents;
|
||||
#ifdef LAIKA_USE_EPOLL
|
||||
/* epoll */
|
||||
struct epoll_event ev, ep_events[MAX_EPOLL_EVENTS];
|
||||
SOCKET epollfd;
|
||||
#else
|
||||
/* raw poll descriptor */
|
||||
PollFD *fds;
|
||||
int fdCapacity;
|
||||
int fdCount;
|
||||
#endif
|
||||
int reventCapacity;
|
||||
int reventCount;
|
||||
};
|
||||
|
||||
void laikaP_initPList(struct sLaika_pollList *pList);
|
||||
void laikaP_cleanPList(struct sLaika_pollList *pList); /* free's all members */
|
||||
void laikaP_addSock(struct sLaika_pollList *pList, struct sLaika_socket *sock);
|
||||
void laikaP_rmvSock(struct sLaika_pollList *pList, struct sLaika_socket *sock);
|
||||
void laikaP_addPollOut(struct sLaika_pollList *pList, struct sLaika_socket *sock);
|
||||
void laikaP_rmvPollOut(struct sLaika_pollList *pList, struct sLaika_socket *sock);
|
||||
|
||||
struct sLaika_pollEvent *laikaP_poll(struct sLaika_pollList *pList, int timeout, int *nevents);
|
||||
|
||||
#endif
|
86
lib/include/lsocket.h
Normal file
86
lib/include/lsocket.h
Normal file
@@ -0,0 +1,86 @@
|
||||
/* socket/winsock headers */
|
||||
#ifdef _WIN32
|
||||
/* windows */
|
||||
#ifndef NOMINMAX
|
||||
#define NOMINMAX
|
||||
#endif
|
||||
#define _WINSOCK_DEPRECATED_NO_WARNINGS
|
||||
#include <winsock2.h>
|
||||
#include <windows.h>
|
||||
#include <ws2tcpip.h>
|
||||
#pragma comment(lib, "Ws2_32.lib")
|
||||
|
||||
typedef char buffer_t;
|
||||
#define PollFD WSAPOLLFD
|
||||
#define poll WSAPoll
|
||||
#define LN_ERRNO WSAGetLastError()
|
||||
#define LN_EWOULD WSAEWOULDBLOCK
|
||||
#define LN_MSG_NOSIGNAL 0
|
||||
#define SOCKETINVALID(x) (x == INVALID_SOCKET)
|
||||
#define SOCKETERROR(x) (x == SOCKET_ERROR)
|
||||
#else
|
||||
/* posix platform */
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netdb.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <poll.h>
|
||||
#ifdef __linux__
|
||||
#include <sys/epoll.h>
|
||||
/* max events for epoll() */
|
||||
#define MAX_EPOLL_EVENTS 128
|
||||
#define LAIKA_USE_EPOLL
|
||||
#endif
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
|
||||
typedef int SOCKET;
|
||||
typedef void buffer_t;
|
||||
#define PollFD struct pollfd
|
||||
#define LN_ERRNO errno
|
||||
#define LN_EWOULD EWOULDBLOCK
|
||||
#define LN_MSG_NOSIGNAL MSG_NOSIGNAL
|
||||
#define INVALID_SOCKET -1
|
||||
#define SOCKETINVALID(x) (x < 0)
|
||||
#define SOCKETERROR(x) (x == -1)
|
||||
#endif
|
||||
#include <fcntl.h>
|
||||
|
||||
typedef enum {
|
||||
RAWSOCK_OK,
|
||||
RAWSOCK_ERROR,
|
||||
RAWSOCK_CLOSED,
|
||||
RAWSOCK_POLL
|
||||
} RAWSOCKCODE;
|
||||
|
||||
struct sLaika_socket {
|
||||
uint8_t *outBuf; /* raw data to be sent() */
|
||||
uint8_t *inBuf; /* raw data we recv()'d */
|
||||
SOCKET sock; /* raw socket fd */
|
||||
int outCount;
|
||||
int inCount;
|
||||
int outCap;
|
||||
int inCap;
|
||||
};
|
||||
|
||||
#define laikaS_isAlive(sock) (sock->sock != INVALID_SOCKET)
|
||||
|
||||
void laikaS_init(void);
|
||||
void laikaS_cleanUp(void);
|
||||
|
||||
void laikaS_initSocket(struct sLaika_socket *sock);
|
||||
void laikaS_cleanSocket(struct sLaika_socket *sock);
|
||||
void laikaS_kill(struct sLaika_socket *sock); /* kills a socket */
|
||||
void laikaS_connect(struct sLaika_socket *sock, char *ip, char *port); /* connect to ip & port */
|
||||
void laikaS_bind(struct sLaika_socket *sock, uint16_t port); /* bind sock to port */
|
||||
bool laikaS_setNonBlock(struct sLaika_socket *sock);
|
||||
|
||||
void laikaS_read(struct sLaika_socket *sock, void *buf, size_t sz); /* reads from inBuf */
|
||||
void laikaS_write(struct sLaika_socket *sock, void *buf, size_t sz); /* writes to outBuf */
|
||||
|
||||
void laikaS_writeByte(struct sLaika_socket *sock, uint8_t data);
|
||||
uint8_t laikaS_readByte(struct sLaika_socket *sock);
|
||||
|
||||
RAWSOCKCODE laikaS_rawRecv(struct sLaika_socket *sock, size_t sz, int *processed);
|
||||
RAWSOCKCODE laikaS_rawSend(struct sLaika_socket *sock, size_t sz, int *processed);
|
Reference in New Issue
Block a user