hio/stio/lib/stio.h

325 lines
8.1 KiB
C

/*
* $Id$
*
Copyright (c) 2015-2016 Chung, Hyung-Hwan. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WAfRRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _STIO_H_
#define _STIO_H_
/* TODO: remove these headers */
#include <assert.h>
#include <string.h>
#include <stdio.h>
#include <sys/socket.h>
typedef signed char stio_int8_t;
typedef unsigned char stio_uint8_t;
typedef unsigned long stio_size_t;
#define STIO_MEMSET(dst,byte,count) memset(dst,byte,count)
#define STIO_ASSERT assert
#define STIO_SIZEOF(x) sizeof(x)
#define STIO_COUNTOF(x) (sizeof(x) / sizeof(x[0]))
#define STIO_NULL ((void*)0)
typedef struct stio_mmgr_t stio_mmgr_t;
typedef void* (*stio_mmgr_alloc_t) (stio_mmgr_t* mmgr, stio_size_t size);
typedef void (*stio_mmgr_free_t) (stio_mmgr_t* mmgr, void* ptr);
struct stio_mmgr_t
{
stio_mmgr_alloc_t alloc;
stio_mmgr_free_t free;
void* ctx;
};
#define STIO_MMGR_ALLOC(mmgr,size) (mmgr)->alloc(mmgr,size)
#define STIO_MMGR_FREE(mmgr,ptr) (mmgr)->free(mmgr,ptr)
struct stio_sckadr_t
{
int family;
stio_uint8_t data[64]; /* TODO: use the actual sockaddr size */
};
typedef struct stio_sckadr_t stio_sckadr_t;
#if defined(_WIN32)
# define STIO_IOCP_KEY 1
typedef int stio_scklen_t;
typedef SOCKET stio_sckhnd_t;
# define STIO_SCKHND_INVALID (INVALID_SOCKET)
typedef HANDLE stio_syshnd_t;
#else
typedef socklen_t stio_scklen_t;
typedef int stio_sckhnd_t;
# define STIO_SCKHND_INVALID (-1)
typedef int stio_syshnd_t;
#endif
/* ------------------------------------------------------------------------- */
typedef struct stio_t stio_t;
typedef struct stio_dev_t stio_dev_t;
typedef struct stio_dev_mth_t stio_dev_mth_t;
typedef struct stio_dev_evcb_t stio_dev_evcb_t;
typedef unsigned int stio_len_t; /* TODO: remove it? */
enum stio_errnum_t
{
STIO_ENOERR,
STIO_ENOMEM,
STIO_EINVAL,
STIO_ENOSUP, /* not supported */
STIO_EDEVMAKE
};
typedef enum stio_errnum_t stio_errnum_t;
struct stio_dev_mth_t
{
/* --------------------------------------------------------------------------------------------- */
int (*make) (stio_dev_t* dev, void* ctx); /* mandatory. called in stix_makedev() */
void (*kill) (stio_dev_t* dev); /* mandatory. called in stix_killdev(). called in stix_makedev() upon failure after make() success */
stio_syshnd_t (*getsyshnd) (stio_dev_t* dev); /* mandatory. called in stix_makedev() after successful make() */
int (*ioctl) (stio_dev_t* dev, int cmd, void* arg);
/* --------------------------------------------------------------------------------------------- */
int (*recv) (stio_dev_t* dev, void* data, stio_len_t* len);
/* --------------------------------------------------------------------------------------------- */
int (*send) (stio_dev_t* dev, const void* data, stio_len_t* len);
/* --------------------------------------------------------------------------------------------- */
};
struct stio_dev_evcb_t
{
int (*ready) (stio_dev_t* dev, int events);
/*int (*on_error) (stio_dev_t* dev);
int (*on_hangup) (stio_dev_t* dev);*/
int (*on_recv) (stio_dev_t* dev, const void* data, stio_len_t len);
int (*on_sent) (stio_dev_t* dev, const void* data, stio_len_t len);
};
#define STIO_DEV_HEADERS \
stio_t* stio; \
stio_dev_mth_t* mth; \
stio_dev_evcb_t* evcb; \
stio_dev_t* prev; \
stio_dev_t* next
struct stio_dev_t
{
STIO_DEV_HEADERS;
};
enum stio_dev_event_cmd_t
{
STIO_DEV_EVENT_ADD,
STIO_DEV_EVENT_MOD,
STIO_DEV_EVENT_DEL
};
typedef enum stio_dev_event_cmd_t stio_dev_event_cmd_t;
enum stio_dev_event_flag_t
{
STIO_DEV_EVENT_IN = (1 << 0),
STIO_DEV_EVENT_OUT = (1 << 1),
STIO_DEV_EVENT_PRI = (1 << 2),
STIO_DEV_EVENT_HUP = (1 << 3),
STIO_DEV_EVENT_ERR = (1 << 4)
};
typedef enum stio_dev_event_flag_t stio_dev_event_flag_t;
/* -------------------------------------------------------------------------- */
enum stio_dev_tcp_ioctl_cmd_t
{
STIO_DEV_TCP_BIND,
STIO_DEV_TCP_CONNECT,
STIO_DEV_TCP_LISTEN
};
typedef enum stio_dev_tcp_ioctl_cmd_t stio_dev_tcp_ioctl_cmd_t;
enum stio_dev_tcp_state_t
{
STIO_DEV_TCP_CONNECTING = (1 << 0),
STIO_DEV_TCP_CONNECTED = (1 << 1),
STIO_DEV_TCP_LISTENING = (1 << 2),
STIO_DEV_TCP_ACCEPTED = (1 << 3)
};
typedef enum stio_dev_tcp_state_t stio_dev_tcp_state_t;
typedef struct stio_dev_tcp_t stio_dev_tcp_t;
typedef void (*stio_dev_tcp_on_connected_t) (stio_dev_tcp_t* dev);
typedef void (*stio_dev_tcp_on_accepted_t) (stio_dev_tcp_t* dev, stio_dev_tcp_t* clidev);
typedef void (*stio_dev_tcp_on_disconnected_t) (stio_dev_tcp_t* dev);
struct stio_dev_tcp_t
{
STIO_DEV_HEADERS;
stio_sckhnd_t sck;
unsigned int state;
/* peer address - valid if one of the followings is set:
* STIO_DEV_TCP_ACCEPTED
* STIO_DEV_TCP_CONNECTED
* STIO_DEV_TCP_CONNECTING */
stio_sckadr_t peer;
/* parent tcp device. valid if STIO_DEV_TCP_ACCEPTED is set */
stio_dev_tcp_t* parent;
stio_dev_tcp_on_connected_t on_connected;
stio_dev_tcp_on_disconnected_t on_disconnected;
stio_dev_tcp_on_accepted_t on_accepted;
};
typedef struct stio_dev_tcp_bind_t stio_dev_tcp_bind_t;
struct stio_dev_tcp_bind_t
{
int options; /* TODO: REUSEADDR , TRANSPARENT, etc or someting?? */
stio_sckadr_t addr;
/* TODO: add device name for BIND_TO_DEVICE */
};
#if 0
struct stio_dev_tcp_make_t
{
set io callbacks..
};
#endif
typedef struct stio_dev_tcp_connect_t stio_dev_tcp_connect_t;
struct stio_dev_tcp_connect_t
{
stio_sckadr_t addr;
stio_dev_tcp_on_connected_t on_connected;
stio_dev_tcp_on_disconnected_t on_disconnected;
};
typedef struct stio_dev_tcp_listen_t stio_dev_tcp_listen_t;
struct stio_dev_tcp_listen_t
{
int backlogs;
stio_dev_tcp_on_accepted_t on_accepted; /* optional, but new connections are dropped immediately without this */
stio_dev_tcp_on_disconnected_t on_disconnected;
};
typedef struct stio_dev_tcp_accept_t stio_dev_tcp_accept_t;
struct stio_dev_tcp_accept_t
{
stio_syshnd_t sck;
stio_dev_tcp_t* parent;
stio_sckadr_t peer;
};
/* -------------------------------------------------------------------------- */
typedef struct stio_dev_udp_t stio_dev_udp_t;
struct stio_dev_udp_t
{
STIO_DEV_HEADERS;
stio_sckhnd_t sck;
stio_sckadr_t peer;
};
/* -------------------------------------------------------------------------- */
#ifdef __cplusplus
extern "C" {
#endif
stio_t* stio_open (
stio_mmgr_t* mmgr,
stio_size_t xtnsize,
stio_errnum_t* errnum
);
void stio_close (
stio_t* stio
);
stio_dev_t* stio_makedev (
stio_t* stio,
stio_size_t dev_size,
stio_dev_mth_t* dev_mth,
stio_dev_evcb_t* dev_evcb,
void* make_ctx
);
void stio_killdev (
stio_t* stio,
stio_dev_t* dev
);
stio_dev_tcp_t* stio_dev_tcp_make (
stio_t* stio,
stio_sckadr_t* addr
);
void stio_dev_tcp_kill (
stio_dev_tcp_t* tcp
);
stio_dev_udp_t* stio_dev_udp_make (
stio_t* stio,
stio_sckadr_t* addr
);
void stio_dev_udp_kill (
stio_dev_udp_t* udp
);
#ifdef __cplusplus
}
#endif
#endif