fixing conflicts caused during renaming

This commit is contained in:
2021-07-22 07:43:01 +00:00
parent be13508e07
commit bac43079a5
47 changed files with 11610 additions and 11773 deletions

View File

@ -1,5 +1,5 @@
#
# hawk -f generr.awk mio.h
# hawk -f generr.awk hio.h
#
@pragma striprecspc on
@ -16,7 +16,7 @@ capture == 1 {
{
capture = 0;
}
else if ($1 ~ /^MIO_E[[:alnum:]]+,*/)
else if ($1 ~ /^HIO_E[[:alnum:]]+,*/)
{
msg = "";
for (i = 3; i < NF; i++)
@ -25,7 +25,7 @@ capture == 1 {
msg = msg $i;
}
printf ("static mio_ooch_t errstr_%d[] = {", msgcount);
printf ("static hio_ooch_t errstr_%d[] = {", msgcount);
len = length(msg);
for (i = 1; i <= len; i++)
{
@ -35,14 +35,14 @@ capture == 1 {
msgcount++;
}
}
/^enum mio_errnum_t$/ {
/^enum hio_errnum_t$/ {
getline x; # consume the next line
capture = 1;
}
END {
printf ("static mio_ooch_t* errstr[] =\n");
printf ("static hio_ooch_t* errstr[] =\n");
printf ("{\n\t");
for (i = 0; i < msgcount; i++)
{

View File

@ -538,157 +538,157 @@
#undef LT_OBJDIR
/* AF_INET */
#undef MIO_AF_INET
#undef HIO_AF_INET
/* AF_INET6 */
#undef MIO_AF_INET6
#undef HIO_AF_INET6
/* AF_PACKET */
#undef MIO_AF_PACKET
#undef HIO_AF_PACKET
/* AF_UNIX */
#undef MIO_AF_UNIX
#undef HIO_AF_UNIX
/* AF_UNSPEC */
#undef MIO_AF_UNSPEC
#undef HIO_AF_UNSPEC
/* use libunwind for backtracing stack frames */
#undef MIO_ENABLE_LIBUNWIND
#undef HIO_ENABLE_LIBUNWIND
/* build the mariadb device */
#undef MIO_ENABLE_MARIADB
#undef HIO_ENABLE_MARIADB
/* Use the wide-character type as the default character type */
#undef MIO_ENABLE_WIDE_CHAR
#undef HIO_ENABLE_WIDE_CHAR
/* Big Endian */
#undef MIO_ENDIAN_BIG
#undef HIO_ENDIAN_BIG
/* Little Endian */
#undef MIO_ENDIAN_LITTLE
#undef HIO_ENDIAN_LITTLE
/* Unknown Endian */
#undef MIO_ENDIAN_UNKNOWN
#undef HIO_ENDIAN_UNKNOWN
/* MB_LEN_MAX */
#undef MIO_MBLEN_MAX
#undef HIO_MBLEN_MAX
/* NSIG */
#undef MIO_NSIG
#undef HIO_NSIG
/* offsetof(struct sockaddr, sa_family) */
#undef MIO_OFFSETOF_SA_FAMILY
#undef HIO_OFFSETOF_SA_FAMILY
/* Author */
#undef MIO_PACKAGE_AUTHOR
#undef HIO_PACKAGE_AUTHOR
/* package name */
#undef MIO_PACKAGE_NAME
#undef HIO_PACKAGE_NAME
/* Project URL */
#undef MIO_PACKAGE_URL
#undef HIO_PACKAGE_URL
/* Package version */
#undef MIO_PACKAGE_VERSION
#undef HIO_PACKAGE_VERSION
/* Major version number */
#undef MIO_PACKAGE_VERSION_MAJOR
#undef HIO_PACKAGE_VERSION_MAJOR
/* Minor version number */
#undef MIO_PACKAGE_VERSION_MINOR
#undef HIO_PACKAGE_VERSION_MINOR
/* Patch level */
#undef MIO_PACKAGE_VERSION_PATCH
#undef HIO_PACKAGE_VERSION_PATCH
/* Define if sa_family_t is signed */
#undef MIO_SA_FAMILY_T_IS_SIGNED
#undef HIO_SA_FAMILY_T_IS_SIGNED
/* sizeof(char) */
#undef MIO_SIZEOF_CHAR
#undef HIO_SIZEOF_CHAR
/* sizeof(double) */
#undef MIO_SIZEOF_DOUBLE
#undef HIO_SIZEOF_DOUBLE
/* sizeof(float) */
#undef MIO_SIZEOF_FLOAT
#undef HIO_SIZEOF_FLOAT
/* sizeof(int) */
#undef MIO_SIZEOF_INT
#undef HIO_SIZEOF_INT
/* sizeof(long) */
#undef MIO_SIZEOF_LONG
#undef HIO_SIZEOF_LONG
/* sizeof(long double) */
#undef MIO_SIZEOF_LONG_DOUBLE
#undef HIO_SIZEOF_LONG_DOUBLE
/* sizeof(long long) */
#undef MIO_SIZEOF_LONG_LONG
#undef HIO_SIZEOF_LONG_LONG
/* sizeof(mbstate_t) */
#undef MIO_SIZEOF_MBSTATE_T
#undef HIO_SIZEOF_MBSTATE_T
/* sizeof(off64_t) */
#undef MIO_SIZEOF_OFF64_T
#undef HIO_SIZEOF_OFF64_T
/* sizeof(off_t) */
#undef MIO_SIZEOF_OFF_T
#undef HIO_SIZEOF_OFF_T
/* sizeof(short) */
#undef MIO_SIZEOF_SHORT
#undef HIO_SIZEOF_SHORT
/* sizeof(socklen_t) */
#undef MIO_SIZEOF_SOCKLEN_T
#undef HIO_SIZEOF_SOCKLEN_T
/* sizeof(struct sockaddr_dl) */
#undef MIO_SIZEOF_STRUCT_SOCKADDR_DL
#undef HIO_SIZEOF_STRUCT_SOCKADDR_DL
/* sizeof(struct sockaddr_in) */
#undef MIO_SIZEOF_STRUCT_SOCKADDR_IN
#undef HIO_SIZEOF_STRUCT_SOCKADDR_IN
/* sizeof(struct sockaddr_in6) */
#undef MIO_SIZEOF_STRUCT_SOCKADDR_IN6
#undef HIO_SIZEOF_STRUCT_SOCKADDR_IN6
/* sizeof(struct sockaddr_ll) */
#undef MIO_SIZEOF_STRUCT_SOCKADDR_LL
#undef HIO_SIZEOF_STRUCT_SOCKADDR_LL
/* sizeof(struct sockaddr_un) */
#undef MIO_SIZEOF_STRUCT_SOCKADDR_UN
#undef HIO_SIZEOF_STRUCT_SOCKADDR_UN
/* sizeof(void*) */
#undef MIO_SIZEOF_VOID_P
#undef HIO_SIZEOF_VOID_P
/* sizeof(wchar_t) */
#undef MIO_SIZEOF_WCHAR_T
#undef HIO_SIZEOF_WCHAR_T
/* sizeof(__float128) */
#undef MIO_SIZEOF___FLOAT128
#undef HIO_SIZEOF___FLOAT128
/* sizeof(__int128) */
#undef MIO_SIZEOF___INT128
#undef HIO_SIZEOF___INT128
/* sizeof(__int128_t) */
#undef MIO_SIZEOF___INT128_T
#undef HIO_SIZEOF___INT128_T
/* sizeof(__int16) */
#undef MIO_SIZEOF___INT16
#undef HIO_SIZEOF___INT16
/* sizeof(__int32) */
#undef MIO_SIZEOF___INT32
#undef HIO_SIZEOF___INT32
/* sizeof(__int64) */
#undef MIO_SIZEOF___INT64
#undef HIO_SIZEOF___INT64
/* sizeof(__int8) */
#undef MIO_SIZEOF___INT8
#undef HIO_SIZEOF___INT8
/* sizeof(__uint128_t) */
#undef MIO_SIZEOF___UINT128_T
#undef HIO_SIZEOF___UINT128_T
/* Define if socklen_t is signed */
#undef MIO_SOCKLEN_T_IS_SIGNED
#undef HIO_SOCKLEN_T_IS_SIGNED
/* Wide-character type size */
#undef MIO_WIDE_CHAR_SIZE
#undef HIO_WIDE_CHAR_SIZE
/* The size of `AF_INET', as computed by valueof. */
#undef NUMVALOF_AF_INET

382
hio/lib/hio-chr.h Normal file
View File

@ -0,0 +1,382 @@
/*
* $Id$
*
Copyright (c) 2016-2020 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 WARRANTIES
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 _HIO_CHR_H_
#define _HIO_CHR_H_
#include <hio-cmn.h>
enum hio_ooch_prop_t
{
HIO_OOCH_PROP_UPPER = (1 << 0),
#define HIO_UCH_PROP_UPPER HIO_OOCH_PROP_UPPER
#define HIO_BCH_PROP_UPPER HIO_OOCH_PROP_UPPER
HIO_OOCH_PROP_LOWER = (1 << 1),
#define HIO_UCH_PROP_LOWER HIO_OOCH_PROP_LOWER
#define HIO_BCH_PROP_LOWER HIO_OOCH_PROP_LOWER
HIO_OOCH_PROP_ALPHA = (1 << 2),
#define HIO_UCH_PROP_ALPHA HIO_OOCH_PROP_ALPHA
#define HIO_BCH_PROP_ALPHA HIO_OOCH_PROP_ALPHA
HIO_OOCH_PROP_DIGIT = (1 << 3),
#define HIO_UCH_PROP_DIGIT HIO_OOCH_PROP_DIGIT
#define HIO_BCH_PROP_DIGIT HIO_OOCH_PROP_DIGIT
HIO_OOCH_PROP_XDIGIT = (1 << 4),
#define HIO_UCH_PROP_XDIGIT HIO_OOCH_PROP_XDIGIT
#define HIO_BCH_PROP_XDIGIT HIO_OOCH_PROP_XDIGIT
HIO_OOCH_PROP_ALNUM = (1 << 5),
#define HIO_UCH_PROP_ALNUM HIO_OOCH_PROP_ALNUM
#define HIO_BCH_PROP_ALNUM HIO_OOCH_PROP_ALNUM
HIO_OOCH_PROP_SPACE = (1 << 6),
#define HIO_UCH_PROP_SPACE HIO_OOCH_PROP_SPACE
#define HIO_BCH_PROP_SPACE HIO_OOCH_PROP_SPACE
HIO_OOCH_PROP_PRINT = (1 << 8),
#define HIO_UCH_PROP_PRINT HIO_OOCH_PROP_PRINT
#define HIO_BCH_PROP_PRINT HIO_OOCH_PROP_PRINT
HIO_OOCH_PROP_GRAPH = (1 << 9),
#define HIO_UCH_PROP_GRAPH HIO_OOCH_PROP_GRAPH
#define HIO_BCH_PROP_GRAPH HIO_OOCH_PROP_GRAPH
HIO_OOCH_PROP_CNTRL = (1 << 10),
#define HIO_UCH_PROP_CNTRL HIO_OOCH_PROP_CNTRL
#define HIO_BCH_PROP_CNTRL HIO_OOCH_PROP_CNTRL
HIO_OOCH_PROP_PUNCT = (1 << 11),
#define HIO_UCH_PROP_PUNCT HIO_OOCH_PROP_PUNCT
#define HIO_BCH_PROP_PUNCT HIO_OOCH_PROP_PUNCT
HIO_OOCH_PROP_BLANK = (1 << 12)
#define HIO_UCH_PROP_BLANK HIO_OOCH_PROP_BLANK
#define HIO_BCH_PROP_BLANK HIO_OOCH_PROP_BLANK
};
typedef enum hio_ooch_prop_t hio_ooch_prop_t;
typedef enum hio_ooch_prop_t hio_uch_prop_t;
typedef enum hio_ooch_prop_t hio_bch_prop_t;
#define HIO_DIGIT_TO_NUM(c) (((c) >= '0' && (c) <= '9')? ((c) - '0'): -1)
#define HIO_XDIGIT_TO_NUM(c) \
(((c) >= '0' && (c) <= '9')? ((c) - '0'): \
((c) >= 'A' && (c) <= 'F')? ((c) - 'A' + 10): \
((c) >= 'a' && (c) <= 'f')? ((c) - 'a' + 10): -1)
#define HIO_ZDIGIT_TO_NUM(c,base) \
(((c) >= '0' && (c) <= '9')? ((c) - '0'): \
((c) >= 'A' && (c) <= 'Z')? ((c) - 'A' + 10): \
((c) >= 'a' && (c) <= 'Z')? ((c) - 'a' + 10): base)
#if defined(__cplusplus)
extern "C" {
#endif
HIO_EXPORT int hio_is_uch_type (hio_uch_t c, hio_uch_prop_t type);
HIO_EXPORT int hio_is_uch_upper (hio_uch_t c);
HIO_EXPORT int hio_is_uch_lower (hio_uch_t c);
HIO_EXPORT int hio_is_uch_alpha (hio_uch_t c);
HIO_EXPORT int hio_is_uch_digit (hio_uch_t c);
HIO_EXPORT int hio_is_uch_xdigit (hio_uch_t c);
HIO_EXPORT int hio_is_uch_alnum (hio_uch_t c);
HIO_EXPORT int hio_is_uch_space (hio_uch_t c);
HIO_EXPORT int hio_is_uch_print (hio_uch_t c);
HIO_EXPORT int hio_is_uch_graph (hio_uch_t c);
HIO_EXPORT int hio_is_uch_cntrl (hio_uch_t c);
HIO_EXPORT int hio_is_uch_punct (hio_uch_t c);
HIO_EXPORT int hio_is_uch_blank (hio_uch_t c);
HIO_EXPORT hio_uch_t hio_to_uch_upper (hio_uch_t c);
HIO_EXPORT hio_uch_t hio_to_uch_lower (hio_uch_t c);
/* ------------------------------------------------------------------------- */
HIO_EXPORT int hio_is_bch_type (hio_bch_t c, hio_bch_prop_t type);
#if defined(__has_builtin)
# if __has_builtin(__builtin_isupper)
# define hio_is_bch_upper __builtin_isupper
# endif
# if __has_builtin(__builtin_islower)
# define hio_is_bch_lower __builtin_islower
# endif
# if __has_builtin(__builtin_isalpha)
# define hio_is_bch_alpha __builtin_isalpha
# endif
# if __has_builtin(__builtin_isdigit)
# define hio_is_bch_digit __builtin_isdigit
# endif
# if __has_builtin(__builtin_isxdigit)
# define hio_is_bch_xdigit __builtin_isxdigit
# endif
# if __has_builtin(__builtin_isalnum)
# define hio_is_bch_alnum __builtin_isalnum
# endif
# if __has_builtin(__builtin_isspace)
# define hio_is_bch_space __builtin_isspace
# endif
# if __has_builtin(__builtin_isprint)
# define hio_is_bch_print __builtin_isprint
# endif
# if __has_builtin(__builtin_isgraph)
# define hio_is_bch_graph __builtin_isgraph
# endif
# if __has_builtin(__builtin_iscntrl)
# define hio_is_bch_cntrl __builtin_iscntrl
# endif
# if __has_builtin(__builtin_ispunct)
# define hio_is_bch_punct __builtin_ispunct
# endif
# if __has_builtin(__builtin_isblank)
# define hio_is_bch_blank __builtin_isblank
# endif
# if __has_builtin(__builtin_toupper)
# define hio_to_bch_upper __builtin_toupper
# endif
# if __has_builtin(__builtin_tolower)
# define hio_to_bch_lower __builtin_tolower
# endif
#elif (__GNUC__ >= 14)
# define hio_is_bch_upper __builtin_isupper
# define hio_is_bch_lower __builtin_islower
# define hio_is_bch_alpha __builtin_isalpha
# define hio_is_bch_digit __builtin_isdigit
# define hio_is_bch_xdigit __builtin_isxdigit
# define hio_is_bch_alnum __builtin_isalnum
# define hio_is_bch_space __builtin_isspace
# define hio_is_bch_print __builtin_isprint
# define hio_is_bch_graph __builtin_isgraph
# define hio_is_bch_cntrl __builtin_iscntrl
# define hio_is_bch_punct __builtin_ispunct
# define hio_is_bch_blank __builtin_isblank
# define hio_to_bch_upper __builtin_toupper
# define hio_to_bch_lower __builtin_tolower
#endif
/* the bch class functions support no locale.
* these implemenent latin-1 only */
#if !defined(hio_is_bch_upper) && defined(HIO_HAVE_INLINE)
static HIO_INLINE int hio_is_bch_upper (hio_bch_t c) { return (hio_bcu_t)c - 'A' < 26; }
#elif !defined(hio_is_bch_upper)
# define hio_is_bch_upper(c) ((hio_bcu_t)(c) - 'A' < 26)
#endif
#if !defined(hio_is_bch_lower) && defined(HIO_HAVE_INLINE)
static HIO_INLINE int hio_is_bch_lower (hio_bch_t c) { return (hio_bcu_t)c - 'a' < 26; }
#elif !defined(hio_is_bch_lower)
# define hio_is_bch_lower(c) ((hio_bcu_t)(c) - 'a' < 26)
#endif
#if !defined(hio_is_bch_alpha) && defined(HIO_HAVE_INLINE)
static HIO_INLINE int hio_is_bch_alpha (hio_bch_t c) { return ((hio_bcu_t)c | 32) - 'a' < 26; }
#elif !defined(hio_is_bch_alpha)
# define hio_is_bch_alpha(c) (((hio_bcu_t)(c) | 32) - 'a' < 26)
#endif
#if !defined(hio_is_bch_digit) && defined(HIO_HAVE_INLINE)
static HIO_INLINE int hio_is_bch_digit (hio_bch_t c) { return (hio_bcu_t)c - '0' < 10; }
#elif !defined(hio_is_bch_digit)
# define hio_is_bch_digit(c) ((hio_bcu_t)(c) - '0' < 10)
#endif
#if !defined(hio_is_bch_xdigit) && defined(HIO_HAVE_INLINE)
static HIO_INLINE int hio_is_bch_xdigit (hio_bch_t c) { return hio_is_bch_digit(c) || ((hio_bcu_t)c | 32) - 'a' < 6; }
#elif !defined(hio_is_bch_xdigit)
# define hio_is_bch_xdigit(c) (hio_is_bch_digit(c) || ((hio_bcu_t)(c) | 32) - 'a' < 6)
#endif
#if !defined(hio_is_bch_alnum) && defined(HIO_HAVE_INLINE)
static HIO_INLINE int hio_is_bch_alnum (hio_bch_t c) { return hio_is_bch_alpha(c) || hio_is_bch_digit(c); }
#elif !defined(hio_is_bch_alnum)
# define hio_is_bch_alnum(c) (hio_is_bch_alpha(c) || hio_is_bch_digit(c))
#endif
#if !defined(hio_is_bch_space) && defined(HIO_HAVE_INLINE)
static HIO_INLINE int hio_is_bch_space (hio_bch_t c) { return c == ' ' || (hio_bcu_t)c - '\t' < 5; }
#elif !defined(hio_is_bch_space)
# define hio_is_bch_space(c) ((c) == ' ' || (hio_bcu_t)(c) - '\t' < 5)
#endif
#if !defined(hio_is_bch_print) && defined(HIO_HAVE_INLINE)
static HIO_INLINE int hio_is_bch_print (hio_bch_t c) { return (hio_bcu_t)c - ' ' < 95; }
#elif !defined(hio_is_bch_print)
# define hio_is_bch_print(c) ((hio_bcu_t)(c) - ' ' < 95)
#endif
#if !defined(hio_is_bch_graph) && defined(HIO_HAVE_INLINE)
static HIO_INLINE int hio_is_bch_graph (hio_bch_t c) { return (hio_bcu_t)c - '!' < 94; }
#elif !defined(hio_is_bch_graph)
# define hio_is_bch_graph(c) ((hio_bcu_t)(c) - '!' < 94)
#endif
#if !defined(hio_is_bch_cntrl) && defined(HIO_HAVE_INLINE)
static HIO_INLINE int hio_is_bch_cntrl (hio_bch_t c) { return (hio_bcu_t)c < ' ' || (hio_bcu_t)c == 127; }
#elif !defined(hio_is_bch_cntrl)
# define hio_is_bch_cntrl(c) ((hio_bcu_t)(c) < ' ' || (hio_bcu_t)(c) == 127)
#endif
#if !defined(hio_is_bch_punct) && defined(HIO_HAVE_INLINE)
static HIO_INLINE int hio_is_bch_punct (hio_bch_t c) { return hio_is_bch_graph(c) && !hio_is_bch_alnum(c); }
#elif !defined(hio_is_bch_punct)
# define hio_is_bch_punct(c) (hio_is_bch_graph(c) && !hio_is_bch_alnum(c))
#endif
#if !defined(hio_is_bch_blank) && defined(HIO_HAVE_INLINE)
static HIO_INLINE int hio_is_bch_blank (hio_bch_t c) { return c == ' ' || c == '\t'; }
#elif !defined(hio_is_bch_blank)
# define hio_is_bch_blank(c) ((c) == ' ' || (c) == '\t')
#endif
#if !defined(hio_to_bch_upper)
HIO_EXPORT hio_bch_t hio_to_bch_upper (hio_bch_t c);
#endif
#if !defined(hio_to_bch_lower)
HIO_EXPORT hio_bch_t hio_to_bch_lower (hio_bch_t c);
#endif
#if defined(HIO_OOCH_IS_UCH)
# define hio_is_ooch_type hio_is_uch_type
# define hio_is_ooch_upper hio_is_uch_upper
# define hio_is_ooch_lower hio_is_uch_lower
# define hio_is_ooch_alpha hio_is_uch_alpha
# define hio_is_ooch_digit hio_is_uch_digit
# define hio_is_ooch_xdigit hio_is_uch_xdigit
# define hio_is_ooch_alnum hio_is_uch_alnum
# define hio_is_ooch_space hio_is_uch_space
# define hio_is_ooch_print hio_is_uch_print
# define hio_is_ooch_graph hio_is_uch_graph
# define hio_is_ooch_cntrl hio_is_uch_cntrl
# define hio_is_ooch_punct hio_is_uch_punct
# define hio_is_ooch_blank hio_is_uch_blank
# define hio_to_ooch_upper hio_to_uch_upper
# define hio_to_ooch_lower hio_to_uch_lower
#else
# define hio_is_ooch_type hio_is_bch_type
# define hio_is_ooch_upper hio_is_bch_upper
# define hio_is_ooch_lower hio_is_bch_lower
# define hio_is_ooch_alpha hio_is_bch_alpha
# define hio_is_ooch_digit hio_is_bch_digit
# define hio_is_ooch_xdigit hio_is_bch_xdigit
# define hio_is_ooch_alnum hio_is_bch_alnum
# define hio_is_ooch_space hio_is_bch_space
# define hio_is_ooch_print hio_is_bch_print
# define hio_is_ooch_graph hio_is_bch_graph
# define hio_is_ooch_cntrl hio_is_bch_cntrl
# define hio_is_ooch_punct hio_is_bch_punct
# define hio_is_ooch_blank hio_is_bch_blank
# define hio_to_ooch_upper hio_to_bch_upper
# define hio_to_ooch_lower hio_to_bch_lower
#endif
HIO_EXPORT int hio_ucstr_to_uch_prop (
const hio_uch_t* name,
hio_uch_prop_t* id
);
HIO_EXPORT int hio_uchars_to_uch_prop (
const hio_uch_t* name,
hio_oow_t len,
hio_uch_prop_t* id
);
HIO_EXPORT int hio_bcstr_to_bch_prop (
const hio_bch_t* name,
hio_bch_prop_t* id
);
HIO_EXPORT int hio_bchars_to_bch_prop (
const hio_bch_t* name,
hio_oow_t len,
hio_bch_prop_t* id
);
#if defined(HIO_OOCH_IS_UCH)
# define hio_oocstr_to_ooch_prop hio_ucstr_to_uch_prop
# define hio_oochars_to_ooch_prop hio_uchars_to_uch_prop
#else
# define hio_oocstr_to_ooch_prop hio_bcstr_to_bch_prop
# define hio_oochars_to_ooch_prop hio_bchars_to_bch_prop
#endif
/* ------------------------------------------------------------------------- */
HIO_EXPORT int hio_get_ucwidth (
hio_uch_t uc
);
/* ------------------------------------------------------------------------- */
HIO_EXPORT hio_oow_t hio_uc_to_utf8 (
hio_uch_t uc,
hio_bch_t* utf8,
hio_oow_t size
);
HIO_EXPORT hio_oow_t hio_utf8_to_uc (
const hio_bch_t* utf8,
hio_oow_t size,
hio_uch_t* uc
);
/* ------------------------------------------------------------------------- */
HIO_EXPORT hio_oow_t hio_uc_to_utf16 (
hio_uch_t uc,
hio_bch_t* utf16,
hio_oow_t size
);
HIO_EXPORT hio_oow_t hio_utf16_to_uc (
const hio_bch_t* utf16,
hio_oow_t size,
hio_uch_t* uc
);
/* ------------------------------------------------------------------------- */
HIO_EXPORT hio_oow_t hio_uc_to_mb8 (
hio_uch_t uc,
hio_bch_t* mb8,
hio_oow_t size
);
HIO_EXPORT hio_oow_t hio_mb8_to_uc (
const hio_bch_t* mb8,
hio_oow_t size,
hio_uch_t* uc
);
#if defined(__cplusplus)
}
#endif
#endif

1028
hio/lib/hio-cmn.h Normal file

File diff suppressed because it is too large Load Diff

609
hio/lib/hio-dns.h Normal file
View File

@ -0,0 +1,609 @@
/*
* $Id$
*
Copyright (c) 2016-2020 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 _HIO_DNS_H_
#define _HIO_DNS_H_
#include <hio.h>
#include <hio-skad.h>
#define HIO_DNS_PORT (53)
enum hio_dns_opcode_t
{
HIO_DNS_OPCODE_QUERY = 0, /* standard query */
HIO_DNS_OPCODE_IQUERY = 1, /* inverse query */
HIO_DNS_OPCODE_STATUS = 2, /* status request */
/* 3 unassigned */
HIO_DNS_OPCODE_NOTIFY = 4,
HIO_DNS_OPCODE_UPDATE = 5
};
typedef enum hio_dns_opcode_t hio_dns_opcode_t;
enum hio_dns_rcode_t
{
HIO_DNS_RCODE_NOERROR = 0,
HIO_DNS_RCODE_FORMERR = 1, /* format error */
HIO_DNS_RCODE_SERVFAIL = 2, /* server failure */
HIO_DNS_RCODE_NXDOMAIN = 3, /* non-existent domain */
HIO_DNS_RCODE_NOTIMPL = 4, /* not implemented */
HIO_DNS_RCODE_REFUSED = 5, /* query refused */
HIO_DNS_RCODE_YXDOMAIN = 6, /* name exists when it should not */
HIO_DNS_RCODE_YXRRSET = 7, /* RR set exists when it should not */
HIO_DNS_RCODE_NXRRSET = 8, /* RR set exists when it should not */
HIO_DNS_RCODE_NOTAUTH = 9, /* not authorized or server not authoritative for zone*/
HIO_DNS_RCODE_NOTZONE = 10, /* name not contained in zone */
/* the standard rcode field is 4 bit long. so the max is 15. */
/* items belows require EDNS0 */
HIO_DNS_RCODE_BADVERS = 16,
HIO_DNS_RCODE_BADSIG = 17,
HIO_DNS_RCODE_BADTIME = 18,
HIO_DNS_RCODE_BADMODE = 19,
HIO_DNS_RCODE_BADNAME = 20,
HIO_DNS_RCODE_BADALG = 21,
HIO_DNS_RCODE_BADTRUNC = 22,
HIO_DNS_RCODE_BADCOOKIE = 23
};
typedef enum hio_dns_rcode_t hio_dns_rcode_t;
enum hio_dns_rrt_t
{
/*
* [RFC1035]
* TYPE fields are used in resource records. Note that these types are a
* subset of QTYPEs.
*/
HIO_DNS_RRT_A = 1,
HIO_DNS_RRT_NS = 2,
HIO_DNS_RRT_MD = 3, /* mail destination. RFC973 replaced this with MX*/
HIO_DNS_RRT_MF = 4, /* mail forwarder. RFC973 replaced this with MX */
HIO_DNS_RRT_CNAME = 5,
HIO_DNS_RRT_SOA = 6,
HIO_DNS_RRT_MB = 7, /* kind of obsoleted. RFC1035, RFC2505 */
HIO_DNS_RRT_MG = 8, /* kind of obsoleted. RFC1035, RFC2505 */
HIO_DNS_RRT_MR = 9, /* kind of obsoleted. RFC1035, RFC2505 */
HIO_DNS_RRT_NULL = 10,
HIO_DNS_RRT_PTR = 12,
HIO_DNS_RRT_MINFO = 15, /* kind of obsoleted. RFC1035, RFC2505 */
HIO_DNS_RRT_MX = 15,
HIO_DNS_RRT_TXT = 16,
HIO_DNS_RRT_AAAA = 28,
HIO_DNS_RRT_EID = 31,
HIO_DNS_RRT_SRV = 33,
HIO_DNS_RRT_OPT = 41,
HIO_DNS_RRT_RRSIG = 46,
/*
* [RFC1035]
* QTYPE fields appear in the question part of a query. QTYPES are a
* superset of TYPEs, hence all TYPEs are valid QTYPEs. In addition, the
* following QTYPEs are defined:
*/
HIO_DNS_RRT_Q_AFXR = 252, /* A request for a transfer of an entire zone */
HIO_DNS_RRT_Q_MAILB = 253, /* A request for mailbox-related records (MB, MG or MR) */
HIO_DNS_RRT_Q_MAILA = 254, /* A request for mail agent RRs (Obsolete - see MX) */
HIO_DNS_RRT_Q_ANY = 255 /* A request for all records */
};
typedef enum hio_dns_rrt_t hio_dns_rrt_t;
/*
* CLASS fields appear in resource records. The following CLASS mnemonics
* and values are defined:
*/
enum hio_dns_rrc_t
{
HIO_DNS_RRC_IN = 1, /* internet */
HIO_DNS_RRC_CH = 3, /* chaos */
HIO_DNS_RRC_HS = 4, /* Hesiod [Dyer 87] */
HIO_DNS_RRC_NONE = 254,
/*
*
* QCLASS fields appear in the question section of a query. QCLASS values
* are a superset of CLASS values; every CLASS is a valid QCLASS. In
* addition to CLASS values, the following QCLASSes are defined:
*/
HIO_DNS_RRC_Q_ANY = 255
};
typedef enum hio_dns_rrc_t hio_dns_rrc_t;
enum hio_dns_eopt_code_t
{
HIO_DNS_EOPT_NSID = 3,
HIO_DNS_EOPT_DAU = 5,
HIO_DNS_EOPT_DHU = 6,
HIO_DNS_EOPT_N3U = 7,
HIO_DNS_EOPT_ECS = 8,
HIO_DNS_EOPT_EXPIRE = 9,
HIO_DNS_EOPT_COOKIE = 10,
HIO_DNS_EOPT_TCPKEEPALIVE = 11,
HIO_DNS_EOPT_PADDING = 12,
HIO_DNS_EOPT_CHAIN = 13,
HIO_DNS_EOPT_KEYTAG = 14,
};
typedef enum hio_dns_eopt_code_t hio_dns_eopt_code_t;
/* dns message preamble */
typedef struct hio_dns_msg_t hio_dns_msg_t;
struct hio_dns_msg_t
{
hio_oow_t msglen;
hio_oow_t ednsrrtroff; /* offset to trailing data after the name in the dns0 RR*/
hio_oow_t pktlen;
hio_oow_t pktalilen;
};
#include <hio-pac1.h>
struct hio_dns_pkt_t /* dns packet header */
{
hio_uint16_t id;
#if defined(HIO_ENDIAN_BIG)
hio_uint16_t qr: 1; /* query(0), answer(1) */
hio_uint16_t opcode: 4; /* operation type */
hio_uint16_t aa: 1; /* authoritative answer */
hio_uint16_t tc: 1; /* truncated. response too large for UDP */
hio_uint16_t rd: 1; /* recursion desired */
hio_uint16_t ra: 1; /* recursion available */
hio_uint16_t unused_1: 1;
hio_uint16_t ad: 1; /* authentication data - dnssec */
hio_uint16_t cd: 1; /* checking disabled - dnssec */
hio_uint16_t rcode: 4; /* reply code - for reply only */
#else
hio_uint16_t rd: 1;
hio_uint16_t tc: 1;
hio_uint16_t aa: 1;
hio_uint16_t opcode: 4;
hio_uint16_t qr: 1;
hio_uint16_t rcode: 4;
hio_uint16_t cd: 1;
hio_uint16_t ad: 1;
hio_uint16_t unused_1: 1;
hio_uint16_t ra: 1;
#endif
hio_uint16_t qdcount; /* number of questions */
hio_uint16_t ancount; /* number of answers (answer part) */
hio_uint16_t nscount; /* number of name servers (authority part. only NS types) */
hio_uint16_t arcount; /* number of additional resource (additional part) */
};
typedef struct hio_dns_pkt_t hio_dns_pkt_t;
struct hio_dns_pkt_alt_t
{
hio_uint16_t id;
hio_uint16_t flags;
hio_uint16_t rrcount[4];
};
typedef struct hio_dns_pkt_alt_t hio_dns_pkt_alt_t;
/* question
* name, qtype, qclass
* answer
* name, qtype, qclass, ttl, rlength, rdata
*/
/* trailing part after the domain name in a resource record in a question */
struct hio_dns_qrtr_t
{
/* qname upto 64 bytes */
hio_uint16_t qtype;
hio_uint16_t qclass;
};
typedef struct hio_dns_qrtr_t hio_dns_qrtr_t;
/* trailing part after the domain name in a resource record in an answer */
struct hio_dns_rrtr_t
{
/* qname upto 64 bytes */
hio_uint16_t rrtype;
hio_uint16_t rrclass;
hio_uint32_t ttl;
hio_uint16_t dlen; /* data length */
/* actual data if if dlen > 0 */
};
typedef struct hio_dns_rrtr_t hio_dns_rrtr_t;
struct hio_dns_eopt_t
{
hio_uint16_t code;
hio_uint16_t dlen;
/* actual data if if dlen > 0 */
};
typedef struct hio_dns_eopt_t hio_dns_eopt_t;
#include <hio-upac.h>
/* ---------------------------------------------------------------- */
/*
#define HIO_DNS_HEADER_MAKE_FLAGS(qr,opcode,aa,tc,rd,ra,ad,cd,rcode) \
((((qr) & 0x01) << 15) | (((opcode) & 0x0F) << 14) | (((aa) & 0x01) << 10) | (((tc) & 0x01) << 9) | \
(((rd) & 0x01) << 8) | (((ra) & 0x01) << 7) | (((ad) & 0x01) << 5) | (((cd) & 0x01) << 4) | ((rcode) & 0x0F))
*/
/* breakdown of the dns message id and flags. it excludes rr count fields.*/
struct hio_dns_bhdr_t
{
hio_int32_t id;
hio_uint8_t qr; /* query(0), answer(1) */
hio_uint8_t opcode; /* operation type */
hio_uint8_t aa; /* authoritative answer */
hio_uint8_t tc; /* truncated. response too large for UDP */
hio_uint8_t rd; /* recursion desired */
hio_uint8_t ra; /* recursion available */
hio_uint8_t ad; /* authentication data - dnssec */
hio_uint8_t cd; /* checking disabled - dnssec */
hio_uint8_t rcode; /* reply code - for reply only */
};
typedef struct hio_dns_bhdr_t hio_dns_bhdr_t;
/* breakdown of question record */
struct hio_dns_bqr_t
{
hio_bch_t* qname;
hio_uint16_t qtype;
hio_uint16_t qclass;
};
typedef struct hio_dns_bqr_t hio_dns_bqr_t;
enum hio_dns_rr_part_t
{
HIO_DNS_RR_PART_ANSWER,
HIO_DNS_RR_PART_AUTHORITY,
HIO_DNS_RR_PART_ADDITIONAL
};
typedef enum hio_dns_rr_part_t hio_dns_rr_part_t;
/* breakdown of resource record */
struct hio_dns_brr_t
{
hio_dns_rr_part_t part;
hio_bch_t* rrname;
hio_uint16_t rrtype;
hio_uint16_t rrclass;
hio_uint32_t ttl;
hio_uint16_t dlen;
void* dptr;
};
typedef struct hio_dns_brr_t hio_dns_brr_t;
#if 0
/* A RDATA */
struct hio_dns_brrd_a_t
{
};
typedef struct hio_dns_brrd_a_t hio_dns_brrd_a_t;
/* 3.3.1 CNAME RDATA format */
struct hio_dns_brrd_cname_t
{
};
typedef struct hio_dns_brrd_cname_t hio_dns_brc_cname_t;
#endif
/* 3.3.9 MX RDATA format */
struct hio_dns_brrd_mx_t
{
hio_uint16_t preference;
hio_bch_t* exchange;
};
typedef struct hio_dns_brrd_mx_t hio_dns_brrd_mx_t;
/* 3.3.13. SOA RDATA format */
struct hio_dns_brrd_soa_t
{
hio_bch_t* mname;
hio_bch_t* rname;
hio_uint32_t serial;
hio_uint32_t refresh;
hio_uint32_t retry;
hio_uint32_t expire;
hio_uint32_t minimum;
};
typedef struct hio_dns_brrd_soa_t hio_dns_brrd_soa_t;
struct hio_dns_beopt_t
{
hio_uint16_t code;
hio_uint16_t dlen;
void* dptr;
};
typedef struct hio_dns_beopt_t hio_dns_beopt_t;
/* the full rcode must be given. the macro takes the upper 8 bits */
#define HIO_DNS_EDNS_MAKE_TTL(rcode,version,dnssecok) ((((((hio_uint32_t)rcode) >> 4) & 0xFF) << 24) | (((hio_uint32_t)version & 0xFF) << 16) | (((hio_uint32_t)dnssecok & 0x1) << 15))
struct hio_dns_bedns_t
{
hio_uint16_t uplen; /* udp payload len - will be placed in the qclass field of RR. */
/* the ttl field(32 bits) of RR holds extended rcode, version, dnssecok */
hio_uint8_t version;
hio_uint8_t dnssecok;
hio_oow_t beonum; /* option count */
hio_dns_beopt_t* beoptr;
};
typedef struct hio_dns_bedns_t hio_dns_bedns_t;
/* ---------------------------------------------------------------- */
typedef struct hio_svc_dns_t hio_svc_dns_t; /* server service */
typedef struct hio_svc_dnc_t hio_svc_dnc_t; /* client service */
typedef struct hio_svc_dnr_t hio_svc_dnr_t; /* recursor service */
typedef void (*hio_svc_dnc_on_done_t) (
hio_svc_dnc_t* dnc,
hio_dns_msg_t* reqmsg,
hio_errnum_t status,
const void* data,
hio_oow_t len
);
typedef void (*hio_svc_dnc_on_resolve_t) (
hio_svc_dnc_t* dnc,
hio_dns_msg_t* reqmsg,
hio_errnum_t status,
const void* data,
hio_oow_t len
);
enum hio_svc_dnc_send_flag_t
{
HIO_SVC_DNC_SEND_FLAG_PREFER_TCP = (1 << 0),
HIO_SVC_DNC_SEND_FLAG_TCP_IF_TC = (1 << 1), // retry over tcp if the truncated bit is set in an answer over udp.
HIO_SVC_DNC_SEND_FLAG_ALL = (HIO_SVC_DNC_SEND_FLAG_PREFER_TCP | HIO_SVC_DNC_SEND_FLAG_TCP_IF_TC)
};
typedef enum hio_svc_dnc_send_flag_t hio_svc_dnc_send_flag_t;
enum hio_svc_dnc_resolve_flag_t
{
HIO_SVC_DNC_RESOLVE_FLAG_PREFER_TCP = HIO_SVC_DNC_SEND_FLAG_PREFER_TCP,
HIO_SVC_DNC_RESOLVE_FLAG_TCP_IF_TC = HIO_SVC_DNC_SEND_FLAG_TCP_IF_TC,
/* the following flag bits are resolver specific. it must not overlap with send flag bits */
HIO_SVC_DNC_RESOLVE_FLAG_BRIEF = (1 << 8),
HIO_SVC_DNC_RESOLVE_FLAG_COOKIE = (1 << 9),
HIO_SVC_DNC_RESOLVE_FLAG_DNSSEC = (1 << 10),
HIO_SVC_DNC_RESOLVE_FLAG_ALL = (HIO_SVC_DNC_RESOLVE_FLAG_PREFER_TCP | HIO_SVC_DNC_RESOLVE_FLAG_TCP_IF_TC | HIO_SVC_DNC_RESOLVE_FLAG_BRIEF | HIO_SVC_DNC_RESOLVE_FLAG_COOKIE | HIO_SVC_DNC_RESOLVE_FLAG_DNSSEC)
};
typedef enum hio_svc_dnc_resolve_flag_t hio_svc_dnc_resolve_flag_t;
/* ---------------------------------------------------------------- */
#define HIO_DNS_COOKIE_CLIENT_LEN (8)
#define HIO_DNS_COOKIE_SERVER_MIN_LEN (16)
#define HIO_DNS_COOKIE_SERVER_MAX_LEN (40)
#define HIO_DNS_COOKIE_MAX_LEN (HIO_DNS_COOKIE_CLIENT_LEN + HIO_DNS_COOKIE_SERVER_MAX_LEN)
typedef struct hio_dns_cookie_data_t hio_dns_cookie_data_t;
#include <hio-pac1.h>
struct hio_dns_cookie_data_t
{
hio_uint8_t client[HIO_DNS_COOKIE_CLIENT_LEN];
hio_uint8_t server[HIO_DNS_COOKIE_SERVER_MAX_LEN];
};
#include <hio-upac.h>
typedef struct hio_dns_cookie_t hio_dns_cookie_t;
struct hio_dns_cookie_t
{
hio_dns_cookie_data_t data;
hio_uint8_t client_len;
hio_uint8_t server_len;
hio_uint8_t key[16];
};
/* ---------------------------------------------------------------- */
struct hio_dns_pkt_info_t
{
/* the following 5 fields are internal use only */
hio_uint8_t* _start;
hio_uint8_t* _end;
hio_uint8_t* _ptr;
hio_oow_t _rrdlen; /* length needed to store RRs decoded */
hio_uint8_t* _rrdptr;
/* you may access the following fields */
hio_dns_bhdr_t hdr;
struct
{
int exist;
hio_uint16_t uplen; /* udp payload len - will be placed in the qclass field of RR. */
hio_uint8_t version;
hio_uint8_t dnssecok;
hio_dns_cookie_t cookie;
} edns;
hio_uint16_t qdcount; /* number of questions */
hio_uint16_t ancount; /* number of answers (answer part) */
hio_uint16_t nscount; /* number of name servers (authority part. only NS types) */
hio_uint16_t arcount; /* number of additional resource (additional part) */
struct
{
hio_dns_bqr_t* qd;
hio_dns_brr_t* an;
hio_dns_brr_t* ns;
hio_dns_brr_t* ar;
} rr;
};
typedef struct hio_dns_pkt_info_t hio_dns_pkt_info_t;
/* ---------------------------------------------------------------- */
#if defined(__cplusplus)
extern "C" {
#endif
HIO_EXPORT hio_svc_dnc_t* hio_svc_dnc_start (
hio_t* hio,
const hio_skad_t* serv_addr, /* required */
const hio_skad_t* bind_addr, /* optional. can be HIO_NULL */
const hio_ntime_t* send_tmout, /* required */
const hio_ntime_t* reply_tmout, /* required */
hio_oow_t max_tries /* required */
);
HIO_EXPORT void hio_svc_dnc_stop (
hio_svc_dnc_t* dnc
);
#if defined(HIO_HAVE_INLINE)
static HIO_INLINE hio_t* hio_svc_dns_gethio(hio_svc_dns_t* svc) { return hio_svc_gethio((hio_svc_t*)svc); }
static HIO_INLINE hio_t* hio_svc_dnc_gethio(hio_svc_dnc_t* svc) { return hio_svc_gethio((hio_svc_t*)svc); }
static HIO_INLINE hio_t* hio_svc_dnr_gethio(hio_svc_dnr_t* svc) { return hio_svc_gethio((hio_svc_t*)svc); }
#else
# define hio_svc_dns_gethio(svc) hio_svc_gethio(svc)
# define hio_svc_dnc_gethio(svc) hio_svc_gethio(svc)
# define hio_svc_dnr_gethio(svc) hio_svc_gethio(svc)
#endif
HIO_EXPORT hio_dns_msg_t* hio_svc_dnc_sendmsg (
hio_svc_dnc_t* dnc,
hio_dns_bhdr_t* bdns,
hio_dns_bqr_t* qr,
hio_oow_t qr_count,
hio_dns_brr_t* rr,
hio_oow_t rr_count,
hio_dns_bedns_t* edns,
int send_flags,
hio_svc_dnc_on_done_t on_done,
hio_oow_t xtnsize
);
HIO_EXPORT hio_dns_msg_t* hio_svc_dnc_sendreq (
hio_svc_dnc_t* dnc,
hio_dns_bhdr_t* bdns,
hio_dns_bqr_t* qr,
hio_dns_bedns_t* edns,
int send_flags,
hio_svc_dnc_on_done_t on_done,
hio_oow_t xtnsize
);
HIO_EXPORT hio_dns_msg_t* hio_svc_dnc_resolve (
hio_svc_dnc_t* dnc,
const hio_bch_t* qname,
hio_dns_rrt_t qtype,
int resolve_flags,
hio_svc_dnc_on_resolve_t on_resolve,
hio_oow_t xtnsize
);
/*
* -1: cookie in the request but no client cookie in the response. this may be ok or not ok depending on your policy
* 0: client cookie mismatch in the request in the response
* 1: client cookie match in the request in the response
* 2: no client cookie in the requset. so it deson't case about the response
*/
HIO_EXPORT int hio_svc_dnc_checkclientcookie (
hio_svc_dnc_t* dnc,
hio_dns_msg_t* reqmsg,
hio_dns_pkt_info_t* respi
);
/* ---------------------------------------------------------------- */
HIO_EXPORT hio_dns_pkt_info_t* hio_dns_make_pkt_info (
hio_t* hio,
const hio_dns_pkt_t* pkt,
hio_oow_t len
);
HIO_EXPORT void hio_dns_free_pkt_info (
hio_t* hio,
hio_dns_pkt_info_t* pi
);
/* ---------------------------------------------------------------- */
#if defined(HIO_HAVE_INLINE)
static HIO_INLINE hio_dns_pkt_t* hio_dns_msg_to_pkt (hio_dns_msg_t* msg) { return (hio_dns_pkt_t*)(msg + 1); }
#else
# define hio_dns_msg_to_pkt(msg) ((hio_dns_pkt_t*)((hio_dns_msg_t*)(msg) + 1))
#endif
HIO_EXPORT hio_dns_msg_t* hio_dns_make_msg (
hio_t* hio,
hio_dns_bhdr_t* bhdr,
hio_dns_bqr_t* qr,
hio_oow_t qr_count,
hio_dns_brr_t* rr,
hio_oow_t rr_count,
hio_dns_bedns_t* edns,
hio_oow_t xtnsize
);
HIO_EXPORT void hio_dns_free_msg (
hio_t* hio,
hio_dns_msg_t* msg
);
/*
* return the pointer to the client cookie data in the packet.
* if cookie is not HIO_NULL, it copies the client cookie there.
*/
HIO_EXPORT hio_uint8_t* hio_dns_find_client_cookie_in_msg (
hio_dns_msg_t* reqmsg,
hio_uint8_t (*cookie)[HIO_DNS_COOKIE_CLIENT_LEN]
);
HIO_EXPORT hio_bch_t* hio_dns_rcode_to_bcstr (
hio_dns_rcode_t rcode
);
#if defined(__cplusplus)
}
#endif
#endif

635
hio/lib/hio-ecs.h Normal file
View File

@ -0,0 +1,635 @@
/*
* $Id$
*
Copyright (c) 2016-2020 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 WARRANTIES
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 _HIO_ECS_H_
#define _HIO_ECS_H_
#include <hio.h>
#include <stdarg.h>
/** string pointer and length as a aggregate */
#define HIO_BECS_BCS(s) (&((s)->val))
/** string length */
#define HIO_BECS_LEN(s) ((s)->val.len)
/** string pointer */
#define HIO_BECS_PTR(s) ((s)->val.ptr)
/** pointer to a particular position */
#define HIO_BECS_CPTR(s,idx) (&(s)->val.ptr[idx])
/** string capacity */
#define HIO_BECS_CAPA(s) ((s)->capa)
/** character at the given position */
#define HIO_BECS_CHAR(s,idx) ((s)->val.ptr[idx])
/**< last character. unsafe if length <= 0 */
#define HIO_BECS_LASTCHAR(s) ((s)->val.ptr[(s)->val.len-1])
/** string pointer and length as a aggregate */
#define HIO_UECS_UCS(s) (&((s)->val))
/** string length */
#define HIO_UECS_LEN(s) ((s)->val.len)
/** string pointer */
#define HIO_UECS_PTR(s) ((s)->val.ptr)
/** pointer to a particular position */
#define HIO_UECS_CPTR(s,idx) (&(s)->val.ptr[idx])
/** string capacity */
#define HIO_UECS_CAPA(s) ((s)->capa)
/** character at the given position */
#define HIO_UECS_CHAR(s,idx) ((s)->val.ptr[idx])
/**< last character. unsafe if length <= 0 */
#define HIO_UECS_LASTCHAR(s) ((s)->val.ptr[(s)->val.len-1])
typedef struct hio_becs_t hio_becs_t;
typedef struct hio_uecs_t hio_uecs_t;
typedef hio_oow_t (*hio_becs_sizer_t) (
hio_becs_t* data,
hio_oow_t hint
);
typedef hio_oow_t (*hio_uecs_sizer_t) (
hio_uecs_t* data,
hio_oow_t hint
);
#if defined(HIO_OOCH_IS_UCH)
# define HIO_OOECS_OOCS(s) HIO_UECS_UCS(s)
# define HIO_OOECS_LEN(s) HIO_UECS_LEN(s)
# define HIO_OOECS_PTR(s) HIO_UECS_PTR(s)
# define HIO_OOECS_CPTR(s,idx) HIO_UECS_CPTR(s,idx)
# define HIO_OOECS_CAPA(s) HIO_UECS_CAPA(s)
# define HIO_OOECS_CHAR(s,idx) HIO_UECS_CHAR(s,idx)
# define HIO_OOECS_LASTCHAR(s) HIO_UECS_LASTCHAR(s)
# define hio_ooecs_t hio_uecs_t
# define hio_ooecs_sizer_t hio_uecs_sizer_t
#else
# define HIO_OOECS_OOCS(s) HIO_BECS_BCS(s)
# define HIO_OOECS_LEN(s) HIO_BECS_LEN(s)
# define HIO_OOECS_PTR(s) HIO_BECS_PTR(s)
# define HIO_OOECS_CPTR(s,idx) HIO_BECS_CPTR(s,idx)
# define HIO_OOECS_CAPA(s) HIO_BECS_CAPA(s)
# define HIO_OOECS_CHAR(s,idx) HIO_BECS_CHAR(s,idx)
# define HIO_OOECS_LASTCHAR(s) HIO_BECS_LASTCHAR(s)
# define hio_ooecs_t hio_becs_t
# define hio_ooecs_sizer_t hio_becs_sizer_t
#endif
/**
* The hio_becs_t type defines a dynamically resizable multi-byte string.
*/
struct hio_becs_t
{
hio_t* hio;
hio_becs_sizer_t sizer; /**< buffer resizer function */
hio_bcs_t val; /**< buffer/string pointer and lengh */
hio_oow_t capa; /**< buffer capacity */
};
/**
* The hio_uecs_t type defines a dynamically resizable wide-character string.
*/
struct hio_uecs_t
{
hio_t* hio;
hio_uecs_sizer_t sizer; /**< buffer resizer function */
hio_ucs_t val; /**< buffer/string pointer and lengh */
hio_oow_t capa; /**< buffer capacity */
};
#if defined(__cplusplus)
extern "C" {
#endif
/**
* The hio_becs_open() function creates a dynamically resizable multibyte string.
*/
HIO_EXPORT hio_becs_t* hio_becs_open (
hio_t* hio,
hio_oow_t xtnsize,
hio_oow_t capa
);
HIO_EXPORT void hio_becs_close (
hio_becs_t* becs
);
/**
* The hio_becs_init() function initializes a dynamically resizable string
* If the parameter capa is 0, it doesn't allocate the internal buffer
* in advance and always succeeds.
* \return 0 on success, -1 on failure.
*/
HIO_EXPORT int hio_becs_init (
hio_becs_t* becs,
hio_t* hio,
hio_oow_t capa
);
/**
* The hio_becs_fini() function finalizes a dynamically resizable string.
*/
HIO_EXPORT void hio_becs_fini (
hio_becs_t* becs
);
#if defined(HIO_HAVE_INLINE)
static HIO_INLINE void* hio_becs_getxtn (hio_becs_t* becs) { return (void*)(becs + 1); }
#else
#define hio_becs_getxtn(becs) ((void*)((hio_becs_t*)(becs) + 1))
#endif
/**
* The hio_becs_yield() function assigns the buffer to an variable of the
* #hio_bcs_t type and recreate a new buffer of the \a new_capa capacity.
* The function fails if it fails to allocate a new buffer.
* \return 0 on success, and -1 on failure.
*/
HIO_EXPORT int hio_becs_yield (
hio_becs_t* becs, /**< string */
hio_bcs_t* buf, /**< buffer pointer */
hio_oow_t newcapa /**< new capacity */
);
HIO_EXPORT hio_bch_t* hio_becs_yieldptr (
hio_becs_t* becs, /**< string */
hio_oow_t newcapa /**< new capacity */
);
/**
* The hio_becs_getsizer() function gets the sizer.
* \return sizer function set or HIO_NULL if no sizer is set.
*/
#if defined(HIO_HAVE_INLINE)
static HIO_INLINE hio_becs_sizer_t hio_becs_getsizer (hio_becs_t* becs) { return becs->sizer; }
#else
# define hio_becs_getsizer(becs) ((becs)->sizer)
#endif
/**
* The hio_becs_setsizer() function specify a new sizer for a dynamic string.
* With no sizer specified, the dynamic string doubles the current buffer
* when it needs to increase its size. The sizer function is passed a dynamic
* string and the minimum capacity required to hold data after resizing.
* The string is truncated if the sizer function returns a smaller number
* than the hint passed.
*/
#if defined(HIO_HAVE_INLINE)
static HIO_INLINE void hio_becs_setsizer (hio_becs_t* becs, hio_becs_sizer_t sizer) { becs->sizer = sizer; }
#else
# define hio_becs_setsizer(becs,sizerfn) ((becs)->sizer = (sizerfn))
#endif
/**
* The hio_becs_getcapa() function returns the current capacity.
* You may use HIO_STR_CAPA(str) macro for performance sake.
* \return current capacity in number of characters.
*/
#if defined(HIO_HAVE_INLINE)
static HIO_INLINE hio_oow_t hio_becs_getcapa (hio_becs_t* becs) { return HIO_BECS_CAPA(becs); }
#else
# define hio_becs_getcapa(becs) HIO_BECS_CAPA(becs)
#endif
/**
* The hio_becs_setcapa() function sets the new capacity. If the new capacity
* is smaller than the old, the overflowing characters are removed from
* from the buffer.
* \return (hio_oow_t)-1 on failure, new capacity on success
*/
HIO_EXPORT hio_oow_t hio_becs_setcapa (
hio_becs_t* becs,
hio_oow_t capa
);
/**
* The hio_becs_getlen() function return the string length.
*/
#if defined(HIO_HAVE_INLINE)
static HIO_INLINE hio_oow_t hio_becs_getlen (hio_becs_t* becs) { return HIO_BECS_LEN(becs); }
#else
# define hio_becs_getlen(becs) HIO_BECS_LEN(becs)
#endif
/**
* The hio_becs_setlen() function changes the string length.
* \return (hio_oow_t)-1 on failure, new length on success
*/
HIO_EXPORT hio_oow_t hio_becs_setlen (
hio_becs_t* becs,
hio_oow_t len
);
/**
* The hio_becs_clear() funtion deletes all characters in a string and sets
* the length to 0. It doesn't resize the internal buffer.
*/
HIO_EXPORT void hio_becs_clear (
hio_becs_t* becs
);
/**
* The hio_becs_swap() function exchanges the pointers to a buffer between
* two strings. It updates the length and the capacity accordingly.
*/
HIO_EXPORT void hio_becs_swap (
hio_becs_t* becs1,
hio_becs_t* becs2
);
HIO_EXPORT hio_oow_t hio_becs_cpy (
hio_becs_t* becs,
const hio_bch_t* s
);
HIO_EXPORT hio_oow_t hio_becs_ncpy (
hio_becs_t* becs,
const hio_bch_t* s,
hio_oow_t len
);
HIO_EXPORT hio_oow_t hio_becs_cat (
hio_becs_t* becs,
const hio_bch_t* s
);
HIO_EXPORT hio_oow_t hio_becs_ncat (
hio_becs_t* becs,
const hio_bch_t* s,
hio_oow_t len
);
HIO_EXPORT hio_oow_t hio_becs_nrcat (
hio_becs_t* becs,
const hio_bch_t* s,
hio_oow_t len
);
HIO_EXPORT hio_oow_t hio_becs_ccat (
hio_becs_t* becs,
hio_bch_t c
);
HIO_EXPORT hio_oow_t hio_becs_nccat (
hio_becs_t* becs,
hio_bch_t c,
hio_oow_t len
);
HIO_EXPORT hio_oow_t hio_becs_del (
hio_becs_t* becs,
hio_oow_t index,
hio_oow_t size
);
HIO_EXPORT hio_oow_t hio_becs_amend (
hio_becs_t* becs,
hio_oow_t index,
hio_oow_t size,
const hio_bch_t* repl
);
HIO_EXPORT hio_oow_t hio_becs_vfcat (
hio_becs_t* str,
const hio_bch_t* fmt,
va_list ap
);
HIO_EXPORT hio_oow_t hio_becs_fcat (
hio_becs_t* str,
const hio_bch_t* fmt,
...
);
HIO_EXPORT hio_oow_t hio_becs_vfmt (
hio_becs_t* str,
const hio_bch_t* fmt,
va_list ap
);
HIO_EXPORT hio_oow_t hio_becs_fmt (
hio_becs_t* str,
const hio_bch_t* fmt,
...
);
/* ------------------------------------------------------------------------ */
/**
* The hio_uecs_open() function creates a dynamically resizable multibyte string.
*/
HIO_EXPORT hio_uecs_t* hio_uecs_open (
hio_t* hio,
hio_oow_t xtnsize,
hio_oow_t capa
);
HIO_EXPORT void hio_uecs_close (
hio_uecs_t* uecs
);
/**
* The hio_uecs_init() function initializes a dynamically resizable string
* If the parameter capa is 0, it doesn't allocate the internal buffer
* in advance and always succeeds.
* \return 0 on success, -1 on failure.
*/
HIO_EXPORT int hio_uecs_init (
hio_uecs_t* uecs,
hio_t* hio,
hio_oow_t capa
);
/**
* The hio_uecs_fini() function finalizes a dynamically resizable string.
*/
HIO_EXPORT void hio_uecs_fini (
hio_uecs_t* uecs
);
#if defined(HIO_HAVE_INLINE)
static HIO_INLINE void* hio_uecs_getxtn (hio_uecs_t* uecs) { return (void*)(uecs + 1); }
#else
#define hio_uecs_getxtn(uecs) ((void*)((hio_uecs_t*)(uecs) + 1))
#endif
/**
* The hio_uecs_yield() function assigns the buffer to an variable of the
* #hio_ucs_t type and recreate a new buffer of the \a new_capa capacity.
* The function fails if it fails to allocate a new buffer.
* \return 0 on success, and -1 on failure.
*/
HIO_EXPORT int hio_uecs_yield (
hio_uecs_t* uecs, /**< string */
hio_ucs_t* buf, /**< buffer pointer */
hio_oow_t newcapa /**< new capacity */
);
HIO_EXPORT hio_uch_t* hio_uecs_yieldptr (
hio_uecs_t* uecs, /**< string */
hio_oow_t newcapa /**< new capacity */
);
/**
* The hio_uecs_getsizer() function gets the sizer.
* \return sizer function set or HIO_NULL if no sizer is set.
*/
#if defined(HIO_HAVE_INLINE)
static HIO_INLINE hio_uecs_sizer_t hio_uecs_getsizer (hio_uecs_t* uecs) { return uecs->sizer; }
#else
# define hio_uecs_getsizer(uecs) ((uecs)->sizer)
#endif
/**
* The hio_uecs_setsizer() function specify a new sizer for a dynamic string.
* With no sizer specified, the dynamic string doubles the current buffer
* when it needs to increase its size. The sizer function is passed a dynamic
* string and the minimum capacity required to hold data after resizing.
* The string is truncated if the sizer function returns a smaller number
* than the hint passed.
*/
#if defined(HIO_HAVE_INLINE)
static HIO_INLINE void hio_uecs_setsizer (hio_uecs_t* uecs, hio_uecs_sizer_t sizer) { uecs->sizer = sizer; }
#else
# define hio_uecs_setsizer(uecs,sizerfn) ((uecs)->sizer = (sizerfn))
#endif
/**
* The hio_uecs_getcapa() function returns the current capacity.
* You may use HIO_STR_CAPA(str) macro for performance sake.
* \return current capacity in number of characters.
*/
#if defined(HIO_HAVE_INLINE)
static HIO_INLINE hio_oow_t hio_uecs_getcapa (hio_uecs_t* uecs) { return HIO_UECS_CAPA(uecs); }
#else
# define hio_uecs_getcapa(uecs) HIO_UECS_CAPA(uecs)
#endif
/**
* The hio_uecs_setcapa() function sets the new capacity. If the new capacity
* is smaller than the old, the overflowing characters are removed from
* from the buffer.
* \return (hio_oow_t)-1 on failure, new capacity on success
*/
HIO_EXPORT hio_oow_t hio_uecs_setcapa (
hio_uecs_t* uecs,
hio_oow_t capa
);
/**
* The hio_uecs_getlen() function return the string length.
*/
#if defined(HIO_HAVE_INLINE)
static HIO_INLINE hio_oow_t hio_uecs_getlen (hio_uecs_t* uecs) { return HIO_UECS_LEN(uecs); }
#else
# define hio_uecs_getlen(uecs) HIO_UECS_LEN(uecs)
#endif
/**
* The hio_uecs_setlen() function changes the string length.
* \return (hio_oow_t)-1 on failure, new length on success
*/
HIO_EXPORT hio_oow_t hio_uecs_setlen (
hio_uecs_t* uecs,
hio_oow_t len
);
/**
* The hio_uecs_clear() funtion deletes all characters in a string and sets
* the length to 0. It doesn't resize the internal buffer.
*/
HIO_EXPORT void hio_uecs_clear (
hio_uecs_t* uecs
);
/**
* The hio_uecs_swap() function exchanges the pointers to a buffer between
* two strings. It updates the length and the capacity accordingly.
*/
HIO_EXPORT void hio_uecs_swap (
hio_uecs_t* uecs1,
hio_uecs_t* uecs2
);
HIO_EXPORT hio_oow_t hio_uecs_cpy (
hio_uecs_t* uecs,
const hio_uch_t* s
);
HIO_EXPORT hio_oow_t hio_uecs_ncpy (
hio_uecs_t* uecs,
const hio_uch_t* s,
hio_oow_t len
);
HIO_EXPORT hio_oow_t hio_uecs_cat (
hio_uecs_t* uecs,
const hio_uch_t* s
);
HIO_EXPORT hio_oow_t hio_uecs_ncat (
hio_uecs_t* uecs,
const hio_uch_t* s,
hio_oow_t len
);
HIO_EXPORT hio_oow_t hio_uecs_nrcat (
hio_uecs_t* uecs,
const hio_uch_t* s,
hio_oow_t len
);
HIO_EXPORT hio_oow_t hio_uecs_ccat (
hio_uecs_t* uecs,
hio_uch_t c
);
HIO_EXPORT hio_oow_t hio_uecs_nccat (
hio_uecs_t* uecs,
hio_uch_t c,
hio_oow_t len
);
HIO_EXPORT hio_oow_t hio_uecs_del (
hio_uecs_t* uecs,
hio_oow_t index,
hio_oow_t size
);
HIO_EXPORT hio_oow_t hio_uecs_amend (
hio_uecs_t* uecs,
hio_oow_t index,
hio_oow_t size,
const hio_uch_t* repl
);
HIO_EXPORT hio_oow_t hio_uecs_vfcat (
hio_uecs_t* str,
const hio_uch_t* fmt,
va_list ap
);
HIO_EXPORT hio_oow_t hio_uecs_fcat (
hio_uecs_t* str,
const hio_uch_t* fmt,
...
);
HIO_EXPORT hio_oow_t hio_uecs_vfmt (
hio_uecs_t* str,
const hio_uch_t* fmt,
va_list ap
);
HIO_EXPORT hio_oow_t hio_uecs_fmt (
hio_uecs_t* str,
const hio_uch_t* fmt,
...
);
#if defined(HIO_OOCH_IS_UCH)
# define hio_ooecs_open hio_uecs_open
# define hio_ooecs_close hio_uecs_close
# define hio_ooecs_init hio_uecs_init
# define hio_ooecs_fini hio_uecs_fini
# define hio_ooecs_getxtn hio_uecs_getxtn
# define hio_ooecs_yield hio_uecs_yield
# define hio_ooecs_yieldptr hio_uecs_yieldptr
# define hio_ooecs_getsizer hio_uecs_getsizer
# define hio_ooecs_setsizer hio_uecs_setsizer
# define hio_ooecs_getcapa hio_uecs_getcapa
# define hio_ooecs_setcapa hio_uecs_setcapa
# define hio_ooecs_getlen hio_uecs_getlen
# define hio_ooecs_setlen hio_uecs_setlen
# define hio_ooecs_clear hio_uecs_clear
# define hio_ooecs_swap hio_uecs_swap
# define hio_ooecs_cpy hio_uecs_cpy
# define hio_ooecs_ncpy hio_uecs_ncpy
# define hio_ooecs_cat hio_uecs_cat
# define hio_ooecs_ncat hio_uecs_ncat
# define hio_ooecs_nrcat hio_uecs_nrcat
# define hio_ooecs_ccat hio_uecs_ccat
# define hio_ooecs_nccat hio_uecs_nccat
# define hio_ooecs_del hio_uecs_del
# define hio_ooecs_amend hio_uecs_amend
# define hio_ooecs_vfcat hio_uecs_vfcat
# define hio_ooecs_fcat hio_uecs_fcat
# define hio_ooecs_vfmt hio_uecs_vfmt
# define hio_ooecs_fmt hio_uecs_fmt
#else
# define hio_ooecs_open hio_becs_open
# define hio_ooecs_close hio_becs_close
# define hio_ooecs_init hio_becs_init
# define hio_ooecs_fini hio_becs_fini
# define hio_ooecs_getxtn hio_becs_getxtn
# define hio_ooecs_yield hio_becs_yield
# define hio_ooecs_yieldptr hio_becs_yieldptr
# define hio_ooecs_getsizer hio_becs_getsizer
# define hio_ooecs_setsizer hio_becs_setsizer
# define hio_ooecs_getcapa hio_becs_getcapa
# define hio_ooecs_setcapa hio_becs_setcapa
# define hio_ooecs_getlen hio_becs_getlen
# define hio_ooecs_setlen hio_becs_setlen
# define hio_ooecs_clear hio_becs_clear
# define hio_ooecs_swap hio_becs_swap
# define hio_ooecs_cpy hio_becs_cpy
# define hio_ooecs_ncpy hio_becs_ncpy
# define hio_ooecs_cat hio_becs_cat
# define hio_ooecs_ncat hio_becs_ncat
# define hio_ooecs_nrcat hio_becs_nrcat
# define hio_ooecs_ccat hio_becs_ccat
# define hio_ooecs_nccat hio_becs_nccat
# define hio_ooecs_del hio_becs_del
# define hio_ooecs_amend hio_becs_amend
# define hio_ooecs_vfcat hio_becs_vfcat
# define hio_ooecs_fcat hio_becs_fcat
# define hio_ooecs_vfmt hio_becs_vfmt
# define hio_ooecs_fmt hio_becs_fmt
#endif
HIO_EXPORT hio_oow_t hio_becs_ncatuchars (
hio_becs_t* str,
const hio_uch_t* s,
hio_oow_t len,
hio_cmgr_t* cmgr
);
HIO_EXPORT hio_oow_t hio_uecs_ncatbchars (
hio_uecs_t* str,
const hio_bch_t* s,
hio_oow_t len,
hio_cmgr_t* cmgr,
int all
);
#if defined(__cplusplus)
}
#endif
#endif

391
hio/lib/hio-fmt.h Normal file
View File

@ -0,0 +1,391 @@
/*
* $Id$
*
Copyright (c) 2016-2020 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 WARRANTIES
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 _HIO_FMT_H_
#define _HIO_FMT_H_
#include <hio-cmn.h>
#include <stdarg.h>
/** \file
* This file defines various formatting functions.
*/
/* =========================================================================
* FORMATTED OUTPUT
* ========================================================================= */
typedef struct hio_fmtout_t hio_fmtout_t;
typedef int (*hio_fmtout_putbchars_t) (
hio_fmtout_t* fmtout,
const hio_bch_t* ptr,
hio_oow_t len
);
typedef int (*hio_fmtout_putuchars_t) (
hio_fmtout_t* fmtout,
const hio_uch_t* ptr,
hio_oow_t len
);
enum hio_fmtout_fmt_type_t
{
HIO_FMTOUT_FMT_TYPE_BCH = 0,
HIO_FMTOUT_FMT_TYPE_UCH
};
typedef enum hio_fmtout_fmt_type_t hio_fmtout_fmt_type_t;
struct hio_fmtout_t
{
hio_oow_t count; /* out */
hio_mmgr_t* mmgr; /* in */
hio_fmtout_putbchars_t putbchars; /* in */
hio_fmtout_putuchars_t putuchars; /* in */
hio_bitmask_t mask; /* in */
void* ctx; /* in */
/* internally set a input */
hio_fmtout_fmt_type_t fmt_type;
const void* fmt_str;
};
/* =========================================================================
* INTMAX FORMATTING
* ========================================================================= */
/**
* The hio_fmt_intmax_flag_t type defines enumerators to change the
* behavior of hio_fmt_intmax() and hio_fmt_uintmax().
*/
enum hio_fmt_intmax_flag_t
{
/* Use lower 6 bits to represent base between 2 and 36 inclusive.
* Upper bits are used for these flag options */
/** Don't truncate if the buffer is not large enough */
HIO_FMT_INTMAX_NOTRUNC = (0x40 << 0),
#define HIO_FMT_INTMAX_NOTRUNC HIO_FMT_INTMAX_NOTRUNC
#define HIO_FMT_UINTMAX_NOTRUNC HIO_FMT_INTMAX_NOTRUNC
#define HIO_FMT_INTMAX_TO_BCSTR_NOTRUNC HIO_FMT_INTMAX_NOTRUNC
#define HIO_FMT_UINTMAX_TO_BCSTR_NOTRUNC HIO_FMT_INTMAX_NOTRUNC
#define HIO_FMT_INTMAX_TO_UCSTR_NOTRUNC HIO_FMT_INTMAX_NOTRUNC
#define HIO_FMT_UINTMAX_TO_UCSTR_NOTRUNC HIO_FMT_INTMAX_NOTRUNC
#define HIO_FMT_INTMAX_TO_OOCSTR_NOTRUNC HIO_FMT_INTMAX_NOTRUNC
#define HIO_FMT_UINTMAX_TO_OOCSTR_NOTRUNC HIO_FMT_INTMAX_NOTRUNC
/** Don't append a terminating null */
HIO_FMT_INTMAX_NONULL = (0x40 << 1),
#define HIO_FMT_INTMAX_NONULL HIO_FMT_INTMAX_NONULL
#define HIO_FMT_UINTMAX_NONULL HIO_FMT_INTMAX_NONULL
#define HIO_FMT_INTMAX_TO_BCSTR_NONULL HIO_FMT_INTMAX_NONULL
#define HIO_FMT_UINTMAX_TO_BCSTR_NONULL HIO_FMT_INTMAX_NONULL
#define HIO_FMT_INTMAX_TO_UCSTR_NONULL HIO_FMT_INTMAX_NONULL
#define HIO_FMT_UINTMAX_TO_UCSTR_NONULL HIO_FMT_INTMAX_NONULL
#define HIO_FMT_INTMAX_TO_OOCSTR_NONULL HIO_FMT_INTMAX_NONULL
#define HIO_FMT_UINTMAX_TO_OOCSTR_NONULL HIO_FMT_INTMAX_NONULL
/** Produce no digit for a value of zero */
HIO_FMT_INTMAX_NOZERO = (0x40 << 2),
#define HIO_FMT_INTMAX_NOZERO HIO_FMT_INTMAX_NOZERO
#define HIO_FMT_UINTMAX_NOZERO HIO_FMT_INTMAX_NOZERO
#define HIO_FMT_INTMAX_TO_BCSTR_NOZERO HIO_FMT_INTMAX_NOZERO
#define HIO_FMT_UINTMAX_TO_BCSTR_NOZERO HIO_FMT_INTMAX_NOZERO
#define HIO_FMT_INTMAX_TO_UCSTR_NOZERO HIO_FMT_INTMAX_NOZERO
#define HIO_FMT_UINTMAX_TO_UCSTR_NOZERO HIO_FMT_INTMAX_NOZERO
#define HIO_FMT_INTMAX_TO_OOCSTR_NOZERO HIO_FMT_INTMAX_NOZERO
#define HIO_FMT_UINTMAX_TO_OOCSTR_NOZERO HIO_FMT_INTMAX_NOZERO
/** Produce a leading zero for a non-zero value */
HIO_FMT_INTMAX_ZEROLEAD = (0x40 << 3),
#define HIO_FMT_INTMAX_ZEROLEAD HIO_FMT_INTMAX_ZEROLEAD
#define HIO_FMT_UINTMAX_ZEROLEAD HIO_FMT_INTMAX_ZEROLEAD
#define HIO_FMT_INTMAX_TO_BCSTR_ZEROLEAD HIO_FMT_INTMAX_ZEROLEAD
#define HIO_FMT_UINTMAX_TO_BCSTR_ZEROLEAD HIO_FMT_INTMAX_ZEROLEAD
#define HIO_FMT_INTMAX_TO_UCSTR_ZEROLEAD HIO_FMT_INTMAX_ZEROLEAD
#define HIO_FMT_UINTMAX_TO_UCSTR_ZEROLEAD HIO_FMT_INTMAX_ZEROLEAD
#define HIO_FMT_INTMAX_TO_OOCSTR_ZEROLEAD HIO_FMT_INTMAX_ZEROLEAD
#define HIO_FMT_UINTMAX_TO_OOCSTR_ZEROLEAD HIO_FMT_INTMAX_ZEROLEAD
/** Use uppercase letters for alphabetic digits */
HIO_FMT_INTMAX_UPPERCASE = (0x40 << 4),
#define HIO_FMT_INTMAX_UPPERCASE HIO_FMT_INTMAX_UPPERCASE
#define HIO_FMT_UINTMAX_UPPERCASE HIO_FMT_INTMAX_UPPERCASE
#define HIO_FMT_INTMAX_TO_BCSTR_UPPERCASE HIO_FMT_INTMAX_UPPERCASE
#define HIO_FMT_UINTMAX_TO_BCSTR_UPPERCASE HIO_FMT_INTMAX_UPPERCASE
#define HIO_FMT_INTMAX_TO_UCSTR_UPPERCASE HIO_FMT_INTMAX_UPPERCASE
#define HIO_FMT_UINTMAX_TO_UCSTR_UPPERCASE HIO_FMT_INTMAX_UPPERCASE
#define HIO_FMT_INTMAX_TO_OOCSTR_UPPERCASE HIO_FMT_INTMAX_UPPERCASE
#define HIO_FMT_UINTMAX_TO_OOCSTR_UPPERCASE HIO_FMT_INTMAX_UPPERCASE
/** Insert a plus sign for a positive integer including 0 */
HIO_FMT_INTMAX_PLUSSIGN = (0x40 << 5),
#define HIO_FMT_INTMAX_PLUSSIGN HIO_FMT_INTMAX_PLUSSIGN
#define HIO_FMT_UINTMAX_PLUSSIGN HIO_FMT_INTMAX_PLUSSIGN
#define HIO_FMT_INTMAX_TO_BCSTR_PLUSSIGN HIO_FMT_INTMAX_PLUSSIGN
#define HIO_FMT_UINTMAX_TO_BCSTR_PLUSSIGN HIO_FMT_INTMAX_PLUSSIGN
#define HIO_FMT_INTMAX_TO_UCSTR_PLUSSIGN HIO_FMT_INTMAX_PLUSSIGN
#define HIO_FMT_UINTMAX_TO_UCSTR_PLUSSIGN HIO_FMT_INTMAX_PLUSSIGN
#define HIO_FMT_INTMAX_TO_OOCSTR_PLUSSIGN HIO_FMT_INTMAX_PLUSSIGN
#define HIO_FMT_UINTMAX_TO_OOCSTR_PLUSSIGN HIO_FMT_INTMAX_PLUSSIGN
/** Insert a space for a positive integer including 0 */
HIO_FMT_INTMAX_EMPTYSIGN = (0x40 << 6),
#define HIO_FMT_INTMAX_EMPTYSIGN HIO_FMT_INTMAX_EMPTYSIGN
#define HIO_FMT_UINTMAX_EMPTYSIGN HIO_FMT_INTMAX_EMPTYSIGN
#define HIO_FMT_INTMAX_TO_BCSTR_EMPTYSIGN HIO_FMT_INTMAX_EMPTYSIGN
#define HIO_FMT_UINTMAX_TO_BCSTR_EMPTYSIGN HIO_FMT_INTMAX_EMPTYSIGN
#define HIO_FMT_INTMAX_TO_UCSTR_EMPTYSIGN HIO_FMT_INTMAX_EMPTYSIGN
#define HIO_FMT_UINTMAX_TO_UCSTR_EMPTYSIGN HIO_FMT_INTMAX_EMPTYSIGN
/** Fill the right part of the string */
HIO_FMT_INTMAX_FILLRIGHT = (0x40 << 7),
#define HIO_FMT_INTMAX_FILLRIGHT HIO_FMT_INTMAX_FILLRIGHT
#define HIO_FMT_UINTMAX_FILLRIGHT HIO_FMT_INTMAX_FILLRIGHT
#define HIO_FMT_INTMAX_TO_BCSTR_FILLRIGHT HIO_FMT_INTMAX_FILLRIGHT
#define HIO_FMT_UINTMAX_TO_BCSTR_FILLRIGHT HIO_FMT_INTMAX_FILLRIGHT
#define HIO_FMT_INTMAX_TO_UCSTR_FILLRIGHT HIO_FMT_INTMAX_FILLRIGHT
#define HIO_FMT_UINTMAX_TO_UCSTR_FILLRIGHT HIO_FMT_INTMAX_FILLRIGHT
#define HIO_FMT_INTMAX_TO_OOCSTR_FILLRIGHT HIO_FMT_INTMAX_FILLRIGHT
#define HIO_FMT_UINTMAX_TO_OOCSTR_FILLRIGHT HIO_FMT_INTMAX_FILLRIGHT
/** Fill between the sign chacter and the digit part */
HIO_FMT_INTMAX_FILLCENTER = (0x40 << 8)
#define HIO_FMT_INTMAX_FILLCENTER HIO_FMT_INTMAX_FILLCENTER
#define HIO_FMT_UINTMAX_FILLCENTER HIO_FMT_INTMAX_FILLCENTER
#define HIO_FMT_INTMAX_TO_BCSTR_FILLCENTER HIO_FMT_INTMAX_FILLCENTER
#define HIO_FMT_UINTMAX_TO_BCSTR_FILLCENTER HIO_FMT_INTMAX_FILLCENTER
#define HIO_FMT_INTMAX_TO_UCSTR_FILLCENTER HIO_FMT_INTMAX_FILLCENTER
#define HIO_FMT_UINTMAX_TO_UCSTR_FILLCENTER HIO_FMT_INTMAX_FILLCENTER
#define HIO_FMT_INTMAX_TO_OOCSTR_FILLCENTER HIO_FMT_INTMAX_FILLCENTER
#define HIO_FMT_UINTMAX_TO_OOCSTR_FILLCENTER HIO_FMT_INTMAX_FILLCENTER
};
#if defined(__cplusplus)
extern "C" {
#endif
/* =========================================================================
* FORMATTED OUTPUT
* ========================================================================= */
HIO_EXPORT int hio_bfmt_outv (
hio_fmtout_t* fmtout,
const hio_bch_t* fmt,
va_list ap
);
HIO_EXPORT int hio_ufmt_outv (
hio_fmtout_t* fmtout,
const hio_uch_t* fmt,
va_list ap
);
HIO_EXPORT int hio_bfmt_out (
hio_fmtout_t* fmtout,
const hio_bch_t* fmt,
...
);
HIO_EXPORT int hio_ufmt_out (
hio_fmtout_t* fmtout,
const hio_uch_t* fmt,
...
);
/* =========================================================================
* INTMAX FORMATTING
* ========================================================================= */
/**
* The hio_fmt_intmax_to_bcstr() function formats an integer \a value to a
* multibyte string according to the given base and writes it to a buffer
* pointed to by \a buf. It writes to the buffer at most \a size characters
* including the terminating null. The base must be between 2 and 36 inclusive
* and can be ORed with zero or more #hio_fmt_intmax_to_bcstr_flag_t enumerators.
* This ORed value is passed to the function via the \a base_and_flags
* parameter. If the formatted string is shorter than \a bufsize, the redundant
* slots are filled with the fill character \a fillchar if it is not a null
* character. The filling behavior is determined by the flags shown below:
*
* - If #HIO_FMT_INTMAX_TO_BCSTR_FILLRIGHT is set in \a base_and_flags, slots
* after the formatting string are filled.
* - If #HIO_FMT_INTMAX_TO_BCSTR_FILLCENTER is set in \a base_and_flags, slots
* before the formatting string are filled. However, if it contains the
* sign character, the slots between the sign character and the digit part
* are filled.
* - If neither #HIO_FMT_INTMAX_TO_BCSTR_FILLRIGHT nor #HIO_FMT_INTMAX_TO_BCSTR_FILLCENTER
* , slots before the formatting string are filled.
*
* The \a precision parameter specified the minimum number of digits to
* produce from the \a value. If \a value produces fewer digits than
* \a precision, the actual digits are padded with '0' to meet the precision
* requirement. You can pass a negative number if you don't wish to specify
* precision.
*
* The terminating null is not added if #HIO_FMT_INTMAX_TO_BCSTR_NONULL is set;
* The #HIO_FMT_INTMAX_TO_BCSTR_UPPERCASE flag indicates that the function should
* use the uppercase letter for a alphabetic digit;
* You can set #HIO_FMT_INTMAX_TO_BCSTR_NOTRUNC if you require lossless formatting.
* The #HIO_FMT_INTMAX_TO_BCSTR_PLUSSIGN flag and #HIO_FMT_INTMAX_TO_BCSTR_EMPTYSIGN
* ensures that the plus sign and a space is added for a positive integer
* including 0 respectively.
* The #HIO_FMT_INTMAX_TO_BCSTR_ZEROLEAD flag ensures that the numeric string
* begins with '0' before applying the prefix.
* You can set the #HIO_FMT_INTMAX_TO_BCSTR_NOZERO flag if you want the value of
* 0 to produce nothing. If both #HIO_FMT_INTMAX_TO_BCSTR_NOZERO and
* #HIO_FMT_INTMAX_TO_BCSTR_ZEROLEAD are specified, '0' is still produced.
*
* If \a prefix is not #HIO_NULL, it is inserted before the digits.
*
* \return
* - -1 if the base is not between 2 and 36 inclusive.
* - negated number of characters required for lossless formatting
* - if \a bufsize is 0.
* - if #HIO_FMT_INTMAX_TO_BCSTR_NOTRUNC is set and \a bufsize is less than
* the minimum required for lossless formatting.
* - number of characters written to the buffer excluding a terminating
* null in all other cases.
*/
HIO_EXPORT int hio_fmt_intmax_to_bcstr (
hio_bch_t* buf, /**< buffer pointer */
int bufsize, /**< buffer size */
hio_intmax_t value, /**< integer to format */
int base_and_flags, /**< base ORed with flags */
int precision, /**< precision */
hio_bch_t fillchar, /**< fill character */
const hio_bch_t* prefix /**< prefix */
);
/**
* The hio_fmt_intmax_to_ucstr() function formats an integer \a value to a
* wide-character string according to the given base and writes it to a buffer
* pointed to by \a buf. It writes to the buffer at most \a size characters
* including the terminating null. The base must be between 2 and 36 inclusive
* and can be ORed with zero or more #hio_fmt_intmax_to_ucstr_flag_t enumerators.
* This ORed value is passed to the function via the \a base_and_flags
* parameter. If the formatted string is shorter than \a bufsize, the redundant
* slots are filled with the fill character \a fillchar if it is not a null
* character. The filling behavior is determined by the flags shown below:
*
* - If #HIO_FMT_INTMAX_TO_UCSTR_FILLRIGHT is set in \a base_and_flags, slots
* after the formatting string are filled.
* - If #HIO_FMT_INTMAX_TO_UCSTR_FILLCENTER is set in \a base_and_flags, slots
* before the formatting string are filled. However, if it contains the
* sign character, the slots between the sign character and the digit part
* are filled.
* - If neither #HIO_FMT_INTMAX_TO_UCSTR_FILLRIGHT nor #HIO_FMT_INTMAX_TO_UCSTR_FILLCENTER
* , slots before the formatting string are filled.
*
* The \a precision parameter specified the minimum number of digits to
* produce from the \ value. If \a value produces fewer digits than
* \a precision, the actual digits are padded with '0' to meet the precision
* requirement. You can pass a negative number if don't wish to specify
* precision.
*
* The terminating null is not added if #HIO_FMT_INTMAX_TO_UCSTR_NONULL is set;
* The #HIO_FMT_INTMAX_TO_UCSTR_UPPERCASE flag indicates that the function should
* use the uppercase letter for a alphabetic digit;
* You can set #HIO_FMT_INTMAX_TO_UCSTR_NOTRUNC if you require lossless formatting.
* The #HIO_FMT_INTMAX_TO_UCSTR_PLUSSIGN flag and #HIO_FMT_INTMAX_TO_UCSTR_EMPTYSIGN
* ensures that the plus sign and a space is added for a positive integer
* including 0 respectively.
* The #HIO_FMT_INTMAX_TO_UCSTR_ZEROLEAD flag ensures that the numeric string
* begins with 0 before applying the prefix.
* You can set the #HIO_FMT_INTMAX_TO_UCSTR_NOZERO flag if you want the value of
* 0 to produce nothing. If both #HIO_FMT_INTMAX_TO_UCSTR_NOZERO and
* #HIO_FMT_INTMAX_TO_UCSTR_ZEROLEAD are specified, '0' is still produced.
*
* If \a prefix is not #HIO_NULL, it is inserted before the digits.
*
* \return
* - -1 if the base is not between 2 and 36 inclusive.
* - negated number of characters required for lossless formatting
* - if \a bufsize is 0.
* - if #HIO_FMT_INTMAX_TO_UCSTR_NOTRUNC is set and \a bufsize is less than
* the minimum required for lossless formatting.
* - number of characters written to the buffer excluding a terminating
* null in all other cases.
*/
HIO_EXPORT int hio_fmt_intmax_to_ucstr (
hio_uch_t* buf, /**< buffer pointer */
int bufsize, /**< buffer size */
hio_intmax_t value, /**< integer to format */
int base_and_flags, /**< base ORed with flags */
int precision, /**< precision */
hio_uch_t fillchar, /**< fill character */
const hio_uch_t* prefix /**< prefix */
);
/**
* The hio_fmt_uintmax_to_bcstr() function formats an unsigned integer \a value
* to a multibyte string buffer. It behaves the same as hio_fmt_intmax_to_bcstr()
* except that it handles an unsigned integer.
*/
HIO_EXPORT int hio_fmt_uintmax_to_bcstr (
hio_bch_t* buf, /**< buffer pointer */
int bufsize, /**< buffer size */
hio_uintmax_t value, /**< integer to format */
int base_and_flags, /**< base ORed with flags */
int precision, /**< precision */
hio_bch_t fillchar, /**< fill character */
const hio_bch_t* prefix /**< prefix */
);
/**
* The hio_fmt_uintmax_to_ucstr() function formats an unsigned integer \a value
* to a unicode string buffer. It behaves the same as hio_fmt_intmax_to_ucstr()
* except that it handles an unsigned integer.
*/
HIO_EXPORT int hio_fmt_uintmax_to_ucstr (
hio_uch_t* buf, /**< buffer pointer */
int bufsize, /**< buffer size */
hio_uintmax_t value, /**< integer to format */
int base_and_flags, /**< base ORed with flags */
int precision, /**< precision */
hio_uch_t fillchar, /**< fill character */
const hio_uch_t* prefix /**< prefix */
);
#if defined(HIO_OOCH_IS_BCH)
# define hio_fmt_intmax_to_oocstr hio_fmt_intmax_to_bcstr
# define hio_fmt_uintmax_to_oocstr hio_fmt_uintmax_to_bcstr
#else
# define hio_fmt_intmax_to_oocstr hio_fmt_intmax_to_ucstr
# define hio_fmt_uintmax_to_oocstr hio_fmt_uintmax_to_ucstr
#endif
/* TODO: hio_fmt_fltmax_to_bcstr()... hio_fmt_fltmax_to_ucstr() */
#if defined(__cplusplus)
}
#endif
#endif

682
hio/lib/hio-htb.h Normal file
View File

@ -0,0 +1,682 @@
/*
* $Id$
*
Copyright (c) 2016-2020 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 WARRANTIES
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 _HIO_HTB_H_
#define _HIO_HTB_H_
#include <hio.h>
/**@file
* This file provides a hash table encapsulated in the #hio_htb_t type that
* maintains buckets for key/value pairs with the same key hash chained under
* the same bucket. Its interface is very close to #hio_rbt_t.
*
* This sample code adds a series of keys and values and print them
* in the randome order.
* @code
* #include <hio-htb.h>
*
* static hio_htb_walk_t walk (hio_htb_t* htb, hio_htb_pair_t* pair, void* ctx)
* {
* hio_printf (HIO_T("key = %d, value = %d\n"),
* *(int*)HIO_HTB_KPTR(pair), *(int*)HIO_HTB_VPTR(pair));
* return HIO_HTB_WALK_FORWARD;
* }
*
* int main ()
* {
* hio_htb_t* s1;
* int i;
*
* hio_open_stdsios ();
* s1 = hio_htb_open (HIO_MMGR_GETDFL(), 0, 30, 75, 1, 1); // error handling skipped
* hio_htb_setstyle (s1, hio_get_htb_style(HIO_HTB_STYLE_INLINE_COPIERS));
*
* for (i = 0; i < 20; i++)
* {
* int x = i * 20;
* hio_htb_insert (s1, &i, HIO_SIZEOF(i), &x, HIO_SIZEOF(x)); // eror handling skipped
* }
*
* hio_htb_walk (s1, walk, HIO_NULL);
*
* hio_htb_close (s1);
* hio_close_stdsios ();
* return 0;
* }
* @endcode
*/
typedef struct hio_htb_t hio_htb_t;
typedef struct hio_htb_pair_t hio_htb_pair_t;
/**
* The hio_htb_walk_t type defines values that the callback function can
* return to control hio_htb_walk().
*/
enum hio_htb_walk_t
{
HIO_HTB_WALK_STOP = 0,
HIO_HTB_WALK_FORWARD = 1
};
typedef enum hio_htb_walk_t hio_htb_walk_t;
/**
* The hio_htb_id_t type defines IDs to indicate a key or a value in various
* functions.
*/
enum hio_htb_id_t
{
HIO_HTB_KEY = 0,
HIO_HTB_VAL = 1
};
typedef enum hio_htb_id_t hio_htb_id_t;
/**
* The hio_htb_copier_t type defines a pair contruction callback.
* A special copier #HIO_HTB_COPIER_INLINE is provided. This copier enables
* you to copy the data inline to the internal node. No freeer is invoked
* when the node is freeed.
*/
typedef void* (*hio_htb_copier_t) (
hio_htb_t* htb /* hash table */,
void* dptr /* pointer to a key or a value */,
hio_oow_t dlen /* length of a key or a value */
);
/**
* The hio_htb_freeer_t defines a key/value destruction callback
* The freeer is called when a node containing the element is destroyed.
*/
typedef void (*hio_htb_freeer_t) (
hio_htb_t* htb, /**< hash table */
void* dptr, /**< pointer to a key or a value */
hio_oow_t dlen /**< length of a key or a value */
);
/**
* The hio_htb_comper_t type defines a key comparator that is called when
* the htb needs to compare keys. A hash table is created with a default
* comparator which performs bitwise comparison of two keys.
* The comparator should return 0 if the keys are the same and a non-zero
* integer otherwise.
*/
typedef int (*hio_htb_comper_t) (
const hio_htb_t* htb, /**< hash table */
const void* kptr1, /**< key pointer */
hio_oow_t klen1, /**< key length */
const void* kptr2, /**< key pointer */
hio_oow_t klen2 /**< key length */
);
/**
* The hio_htb_keeper_t type defines a value keeper that is called when
* a value is retained in the context that it should be destroyed because
* it is identical to a new value. Two values are identical if their
* pointers and lengths are equal.
*/
typedef void (*hio_htb_keeper_t) (
hio_htb_t* htb, /**< hash table */
void* vptr, /**< value pointer */
hio_oow_t vlen /**< value length */
);
/**
* The hio_htb_sizer_t type defines a bucket size claculator that is called
* when hash table should resize the bucket. The current bucket size + 1 is
* passed as the hint.
*/
typedef hio_oow_t (*hio_htb_sizer_t) (
hio_htb_t* htb, /**< htb */
hio_oow_t hint /**< sizing hint */
);
/**
* The hio_htb_hasher_t type defines a key hash function
*/
typedef hio_oow_t (*hio_htb_hasher_t) (
const hio_htb_t* htb, /**< hash table */
const void* kptr, /**< key pointer */
hio_oow_t klen /**< key length in bytes */
);
/**
* The hio_htb_walker_t defines a pair visitor.
*/
typedef hio_htb_walk_t (*hio_htb_walker_t) (
hio_htb_t* htb, /**< htb */
hio_htb_pair_t* pair, /**< pointer to a key/value pair */
void* ctx /**< pointer to user-defined data */
);
/**
* The hio_htb_cbserter_t type defines a callback function for hio_htb_cbsert().
* The hio_htb_cbserter() function calls it to allocate a new pair for the
* key pointed to by @a kptr of the length @a klen and the callback context
* @a ctx. The second parameter @a pair is passed the pointer to the existing
* pair for the key or #HIO_NULL in case of no existing key. The callback
* must return a pointer to a new or a reallocated pair. When reallocating the
* existing pair, this callback must destroy the existing pair and return the
* newly reallocated pair. It must return #HIO_NULL for failure.
*/
typedef hio_htb_pair_t* (*hio_htb_cbserter_t) (
hio_htb_t* htb, /**< hash table */
hio_htb_pair_t* pair, /**< pair pointer */
void* kptr, /**< key pointer */
hio_oow_t klen, /**< key length */
void* ctx /**< callback context */
);
/**
* The hio_htb_pair_t type defines hash table pair. A pair is composed of a key
* and a value. It maintains pointers to the beginning of a key and a value
* plus their length. The length is scaled down with the scale factor
* specified in an owning hash table.
*/
struct hio_htb_pair_t
{
hio_ptl_t key;
hio_ptl_t val;
/* management information below */
hio_htb_pair_t* next;
};
typedef struct hio_htb_style_t hio_htb_style_t;
struct hio_htb_style_t
{
hio_htb_copier_t copier[2];
hio_htb_freeer_t freeer[2];
hio_htb_comper_t comper; /**< key comparator */
hio_htb_keeper_t keeper; /**< value keeper */
hio_htb_sizer_t sizer; /**< bucket capacity recalculator */
hio_htb_hasher_t hasher; /**< key hasher */
};
/**
* The hio_htb_style_kind_t type defines the type of predefined
* callback set for pair manipulation.
*/
enum hio_htb_style_kind_t
{
/** store the key and the value pointer */
HIO_HTB_STYLE_DEFAULT,
/** copy both key and value into the pair */
HIO_HTB_STYLE_INLINE_COPIERS,
/** copy the key into the pair but store the value pointer */
HIO_HTB_STYLE_INLINE_KEY_COPIER,
/** copy the value into the pair but store the key pointer */
HIO_HTB_STYLE_INLINE_VALUE_COPIER
};
typedef enum hio_htb_style_kind_t hio_htb_style_kind_t;
/**
* The hio_htb_t type defines a hash table.
*/
struct hio_htb_t
{
hio_t* hio;
const hio_htb_style_t* style;
hio_uint8_t scale[2]; /**< length scale */
hio_uint8_t factor; /**< load factor in percentage */
hio_oow_t size;
hio_oow_t capa;
hio_oow_t threshold;
hio_htb_pair_t** bucket;
};
struct hio_htb_itr_t
{
hio_htb_pair_t* pair;
hio_oow_t buckno;
};
typedef struct hio_htb_itr_t hio_htb_itr_t;
/**
* The HIO_HTB_COPIER_SIMPLE macros defines a copier that remembers the
* pointer and length of data in a pair.
**/
#define HIO_HTB_COPIER_SIMPLE ((hio_htb_copier_t)1)
/**
* The HIO_HTB_COPIER_INLINE macros defines a copier that copies data into
* a pair.
**/
#define HIO_HTB_COPIER_INLINE ((hio_htb_copier_t)2)
#define HIO_HTB_COPIER_DEFAULT (HIO_HTB_COPIER_SIMPLE)
#define HIO_HTB_FREEER_DEFAULT (HIO_NULL)
#define HIO_HTB_COMPER_DEFAULT (hio_htb_dflcomp)
#define HIO_HTB_KEEPER_DEFAULT (HIO_NULL)
#define HIO_HTB_SIZER_DEFAULT (HIO_NULL)
#define HIO_HTB_HASHER_DEFAULT (hio_htb_dflhash)
/**
* The HIO_HTB_SIZE() macro returns the number of pairs in a hash table.
*/
#define HIO_HTB_SIZE(m) (*(const hio_oow_t*)&(m)->size)
/**
* The HIO_HTB_CAPA() macro returns the maximum number of pairs that can be
* stored in a hash table without further reorganization.
*/
#define HIO_HTB_CAPA(m) (*(const hio_oow_t*)&(m)->capa)
#define HIO_HTB_FACTOR(m) (*(const int*)&(m)->factor)
#define HIO_HTB_KSCALE(m) (*(const int*)&(m)->scale[HIO_HTB_KEY])
#define HIO_HTB_VSCALE(m) (*(const int*)&(m)->scale[HIO_HTB_VAL])
#define HIO_HTB_KPTL(p) (&(p)->key)
#define HIO_HTB_VPTL(p) (&(p)->val)
#define HIO_HTB_KPTR(p) ((p)->key.ptr)
#define HIO_HTB_KLEN(p) ((p)->key.len)
#define HIO_HTB_VPTR(p) ((p)->val.ptr)
#define HIO_HTB_VLEN(p) ((p)->val.len)
#define HIO_HTB_NEXT(p) ((p)->next)
#if defined(__cplusplus)
extern "C" {
#endif
/**
* The hio_get_htb_style() functions returns a predefined callback set for
* pair manipulation.
*/
HIO_EXPORT const hio_htb_style_t* hio_get_htb_style (
hio_htb_style_kind_t kind
);
/**
* The hio_htb_open() function creates a hash table with a dynamic array
* bucket and a list of values chained. The initial capacity should be larger
* than 0. The load factor should be between 0 and 100 inclusive and the load
* factor of 0 disables bucket resizing. If you need extra space associated
* with hash table, you may pass a non-zero value for @a xtnsize.
* The HIO_HTB_XTN() macro and the hio_htb_getxtn() function return the
* pointer to the beginning of the extension.
* The @a kscale and @a vscale parameters specify the unit of the key and
* value size.
* @return #hio_htb_t pointer on success, #HIO_NULL on failure.
*/
HIO_EXPORT hio_htb_t* hio_htb_open (
hio_t* hio,
hio_oow_t xtnsize, /**< extension size in bytes */
hio_oow_t capa, /**< initial capacity */
int factor, /**< load factor */
int kscale, /**< key scale - 1 to 255 */
int vscale /**< value scale - 1 to 255 */
);
/**
* The hio_htb_close() function destroys a hash table.
*/
HIO_EXPORT void hio_htb_close (
hio_htb_t* htb /**< hash table */
);
/**
* The hio_htb_init() function initializes a hash table
*/
HIO_EXPORT int hio_htb_init (
hio_htb_t* htb, /**< hash table */
hio_t* hio,
hio_oow_t capa, /**< initial capacity */
int factor, /**< load factor */
int kscale, /**< key scale */
int vscale /**< value scale */
);
/**
* The hio_htb_fini() funtion finalizes a hash table
*/
HIO_EXPORT void hio_htb_fini (
hio_htb_t* htb
);
#if defined(HIO_HAVE_INLINE)
static HIO_INLINE void* hio_htb_getxtn (hio_htb_t* htb) { return (void*)(htb + 1); }
#else
#define hio_htb_getxtn(htb) ((void*)((hio_htb_t*)(htb) + 1))
#endif
/**
* The hio_htb_getstyle() function gets manipulation callback function set.
*/
HIO_EXPORT const hio_htb_style_t* hio_htb_getstyle (
const hio_htb_t* htb /**< hash table */
);
/**
* The hio_htb_setstyle() function sets internal manipulation callback
* functions for data construction, destruction, resizing, hashing, etc.
* The callback structure pointed to by \a style must outlive the hash
* table pointed to by \a htb as the hash table doesn't copy the contents
* of the structure.
*/
HIO_EXPORT void hio_htb_setstyle (
hio_htb_t* htb, /**< hash table */
const hio_htb_style_t* style /**< callback function set */
);
/**
* The hio_htb_getsize() function gets the number of pairs in hash table.
*/
HIO_EXPORT hio_oow_t hio_htb_getsize (
const hio_htb_t* htb
);
/**
* The hio_htb_getcapa() function gets the number of slots allocated
* in a hash bucket.
*/
HIO_EXPORT hio_oow_t hio_htb_getcapa (
const hio_htb_t* htb /**< hash table */
);
/**
* The hio_htb_search() function searches a hash table to find a pair with a
* matching key. It returns the pointer to the pair found. If it fails
* to find one, it returns HIO_NULL.
* @return pointer to the pair with a maching key,
* or #HIO_NULL if no match is found.
*/
HIO_EXPORT hio_htb_pair_t* hio_htb_search (
const hio_htb_t* htb, /**< hash table */
const void* kptr, /**< key pointer */
hio_oow_t klen /**< key length */
);
/**
* The hio_htb_upsert() function searches a hash table for the pair with a
* matching key. If one is found, it updates the pair. Otherwise, it inserts
* a new pair with the key and value given. It returns the pointer to the
* pair updated or inserted.
* @return pointer to the updated or inserted pair on success,
* #HIO_NULL on failure.
*/
HIO_EXPORT hio_htb_pair_t* hio_htb_upsert (
hio_htb_t* htb, /**< hash table */
void* kptr, /**< key pointer */
hio_oow_t klen, /**< key length */
void* vptr, /**< value pointer */
hio_oow_t vlen /**< value length */
);
/**
* The hio_htb_ensert() function inserts a new pair with the key and the value
* given. If there exists a pair with the key given, the function returns
* the pair containing the key.
* @return pointer to a pair on success, #HIO_NULL on failure.
*/
HIO_EXPORT hio_htb_pair_t* hio_htb_ensert (
hio_htb_t* htb, /**< hash table */
void* kptr, /**< key pointer */
hio_oow_t klen, /**< key length */
void* vptr, /**< value pointer */
hio_oow_t vlen /**< value length */
);
/**
* The hio_htb_insert() function inserts a new pair with the key and the value
* given. If there exists a pair with the key given, the function returns
* #HIO_NULL without channging the value.
* @return pointer to the pair created on success, #HIO_NULL on failure.
*/
HIO_EXPORT hio_htb_pair_t* hio_htb_insert (
hio_htb_t* htb, /**< hash table */
void* kptr, /**< key pointer */
hio_oow_t klen, /**< key length */
void* vptr, /**< value pointer */
hio_oow_t vlen /**< value length */
);
/**
* The hio_htb_update() function updates the value of an existing pair
* with a matching key.
* @return pointer to the pair on success, #HIO_NULL on no matching pair
*/
HIO_EXPORT hio_htb_pair_t* hio_htb_update (
hio_htb_t* htb, /**< hash table */
void* kptr, /**< key pointer */
hio_oow_t klen, /**< key length */
void* vptr, /**< value pointer */
hio_oow_t vlen /**< value length */
);
/**
* The hio_htb_cbsert() function inserts a key/value pair by delegating pair
* allocation to a callback function. Depending on the callback function,
* it may behave like hio_htb_insert(), hio_htb_upsert(), hio_htb_update(),
* hio_htb_ensert(), or totally differently. The sample code below inserts
* a new pair if the key is not found and appends the new value to the
* existing value delimited by a comma if the key is found.
*
* @code
* #include <hio-htb.h>
*
* hio_htb_walk_t print_map_pair (hio_htb_t* map, hio_htb_pair_t* pair, void* ctx)
* {
* hio_printf (HIO_T("%.*s[%d] => %.*s[%d]\n"),
* HIO_HTB_KLEN(pair), HIO_HTB_KPTR(pair), (int)HIO_HTB_KLEN(pair),
* HIO_HTB_VLEN(pair), HIO_HTB_VPTR(pair), (int)HIO_HTB_VLEN(pair));
* return HIO_HTB_WALK_FORWARD;
* }
*
* hio_htb_pair_t* cbserter (
* hio_htb_t* htb, hio_htb_pair_t* pair,
* void* kptr, hio_oow_t klen, void* ctx)
* {
* hio_cstr_t* v = (hio_cstr_t*)ctx;
* if (pair == HIO_NULL)
* {
* // no existing key for the key
* return hio_htb_allocpair (htb, kptr, klen, v->ptr, v->len);
* }
* else
* {
* // a pair with the key exists.
* // in this sample, i will append the new value to the old value
* // separated by a comma
* hio_htb_pair_t* new_pair;
* hio_ooch_t comma = HIO_T(',');
* hio_uint8_t* vptr;
*
* // allocate a new pair, but without filling the actual value.
* // note vptr is given HIO_NULL for that purpose
* new_pair = hio_htb_allocpair (
* htb, kptr, klen, HIO_NULL, HIO_HTB_VLEN(pair) + 1 + v->len);
* if (new_pair == HIO_NULL) return HIO_NULL;
*
* // fill in the value space
* vptr = HIO_HTB_VPTR(new_pair);
* hio_memcpy (vptr, HIO_HTB_VPTR(pair), HIO_HTB_VLEN(pair)*HIO_SIZEOF(hio_ooch_t));
* vptr += HIO_HTB_VLEN(pair)*HIO_SIZEOF(hio_ooch_t);
* hio_memcpy (vptr, &comma, HIO_SIZEOF(hio_ooch_t));
* vptr += HIO_SIZEOF(hio_ooch_t);
* hio_memcpy (vptr, v->ptr, v->len*HIO_SIZEOF(hio_ooch_t));
*
* // this callback requires the old pair to be destroyed
* hio_htb_freepair (htb, pair);
*
* // return the new pair
* return new_pair;
* }
* }
*
* int main ()
* {
* hio_htb_t* s1;
* int i;
* hio_ooch_t* keys[] = { HIO_T("one"), HIO_T("two"), HIO_T("three") };
* hio_ooch_t* vals[] = { HIO_T("1"), HIO_T("2"), HIO_T("3"), HIO_T("4"), HIO_T("5") };
*
* hio_open_stdsios ();
* s1 = hio_htb_open (
* HIO_MMGR_GETDFL(), 0, 10, 70,
* HIO_SIZEOF(hio_ooch_t), HIO_SIZEOF(hio_ooch_t)
* ); // note error check is skipped
* hio_htb_setstyle (s1, hio_get_htb_style(HIO_HTB_STYLE_INLINE_COPIERS));
*
* for (i = 0; i < HIO_COUNTOF(vals); i++)
* {
* hio_cstr_t ctx;
* ctx.ptr = vals[i]; ctx.len = hio_count_oocstr(vals[i]);
* hio_htb_cbsert (s1,
* keys[i%HIO_COUNTOF(keys)], hio_count_oocstr(keys[i%HIO_COUNTOF(keys)]),
* cbserter, &ctx
* ); // note error check is skipped
* }
* hio_htb_walk (s1, print_map_pair, HIO_NULL);
*
* hio_htb_close (s1);
* hio_close_stdsios ();
* return 0;
* }
* @endcode
*/
HIO_EXPORT hio_htb_pair_t* hio_htb_cbsert (
hio_htb_t* htb, /**< hash table */
void* kptr, /**< key pointer */
hio_oow_t klen, /**< key length */
hio_htb_cbserter_t cbserter, /**< callback function */
void* ctx /**< callback context */
);
/**
* The hio_htb_delete() function deletes a pair with a matching key
* @return 0 on success, -1 on failure
*/
HIO_EXPORT int hio_htb_delete (
hio_htb_t* htb, /**< hash table */
const void* kptr, /**< key pointer */
hio_oow_t klen /**< key length */
);
/**
* The hio_htb_clear() function empties a hash table
*/
HIO_EXPORT void hio_htb_clear (
hio_htb_t* htb /**< hash table */
);
/**
* The hio_htb_walk() function traverses a hash table.
*/
HIO_EXPORT void hio_htb_walk (
hio_htb_t* htb, /**< hash table */
hio_htb_walker_t walker, /**< callback function for each pair */
void* ctx /**< pointer to user-specific data */
);
HIO_EXPORT void hio_init_htb_itr (
hio_htb_itr_t* itr
);
/**
* The hio_htb_getfirstpair() function returns the pointer to the first pair
* in a hash table.
*/
HIO_EXPORT hio_htb_pair_t* hio_htb_getfirstpair (
hio_htb_t* htb, /**< hash table */
hio_htb_itr_t* itr /**< iterator*/
);
/**
* The hio_htb_getnextpair() function returns the pointer to the next pair
* to the current pair @a pair in a hash table.
*/
HIO_EXPORT hio_htb_pair_t* hio_htb_getnextpair (
hio_htb_t* htb, /**< hash table */
hio_htb_itr_t* itr /**< iterator*/
);
/**
* The hio_htb_allocpair() function allocates a pair for a key and a value
* given. But it does not chain the pair allocated into the hash table @a htb.
* Use this function at your own risk.
*
* Take note of he following special behavior when the copier is
* #HIO_HTB_COPIER_INLINE.
* - If @a kptr is #HIO_NULL, the key space of the size @a klen is reserved but
* not propagated with any data.
* - If @a vptr is #HIO_NULL, the value space of the size @a vlen is reserved
* but not propagated with any data.
*/
HIO_EXPORT hio_htb_pair_t* hio_htb_allocpair (
hio_htb_t* htb,
void* kptr,
hio_oow_t klen,
void* vptr,
hio_oow_t vlen
);
/**
* The hio_htb_freepair() function destroys a pair. But it does not detach
* the pair destroyed from the hash table @a htb. Use this function at your
* own risk.
*/
HIO_EXPORT void hio_htb_freepair (
hio_htb_t* htb,
hio_htb_pair_t* pair
);
/**
* The hio_htb_dflhash() function is a default hash function.
*/
HIO_EXPORT hio_oow_t hio_htb_dflhash (
const hio_htb_t* htb,
const void* kptr,
hio_oow_t klen
);
/**
* The hio_htb_dflcomp() function is default comparator.
*/
HIO_EXPORT int hio_htb_dflcomp (
const hio_htb_t* htb,
const void* kptr1,
hio_oow_t klen1,
const void* kptr2,
hio_oow_t klen2
);
#if defined(__cplusplus)
}
#endif
#endif

214
hio/lib/hio-htrd.h Normal file
View File

@ -0,0 +1,214 @@
/*
Copyright (c) 2016-2020 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 WARRANTIES
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 _HIO_HTRD_H_
#define _HIO_HTRD_H_
#include <hio-http.h>
#include <hio-htre.h>
typedef struct hio_htrd_t hio_htrd_t;
enum hio_htrd_errnum_t
{
HIO_HTRD_ENOERR,
HIO_HTRD_EOTHER,
HIO_HTRD_ENOIMPL,
HIO_HTRD_ESYSERR,
HIO_HTRD_EINTERN,
HIO_HTRD_ENOMEM,
HIO_HTRD_EBADRE,
HIO_HTRD_EBADHDR,
HIO_HTRD_ESUSPENDED
};
typedef enum hio_htrd_errnum_t hio_htrd_errnum_t;
/**
* The hio_htrd_option_t type defines various options to
* change the behavior of the hio_htrd_t reader.
*/
enum hio_htrd_option_t
{
HIO_HTRD_SKIP_EMPTY_LINES = ((hio_bitmask_t)1 << 0), /**< skip leading empty lines before the initial line */
HIO_HTRD_SKIP_INITIAL_LINE = ((hio_bitmask_t)1 << 1), /**< skip processing an initial line */
HIO_HTRD_CANONQPATH = ((hio_bitmask_t)1 << 2), /**< canonicalize the query path */
HIO_HTRD_REQUEST = ((hio_bitmask_t)1 << 3), /**< parse input as a request */
HIO_HTRD_RESPONSE = ((hio_bitmask_t)1 << 4), /**< parse input as a response */
HIO_HTRD_TRAILERS = ((hio_bitmask_t)1 << 5), /**< store trailers in a separate table */
HIO_HTRD_STRICT = ((hio_bitmask_t)1 << 6) /**< be more picky */
};
typedef enum hio_htrd_option_t hio_htrd_option_t;
typedef struct hio_htrd_recbs_t hio_htrd_recbs_t;
struct hio_htrd_recbs_t
{
int (*peek) (hio_htrd_t* htrd, hio_htre_t* re);
int (*poke) (hio_htrd_t* htrd, hio_htre_t* re);
int (*push_content) (hio_htrd_t* htrd, hio_htre_t* re, const hio_bch_t* data, hio_oow_t len);
};
struct hio_htrd_t
{
hio_t* hio;
hio_htrd_errnum_t errnum;
hio_bitmask_t option;
int flags;
hio_htrd_recbs_t recbs;
struct
{
struct
{
int flags;
int crlf; /* crlf status */
hio_oow_t plen; /* raw request length excluding crlf */
hio_oow_t need; /* number of octets needed for contents */
struct
{
hio_oow_t len;
hio_oow_t count;
int phase;
} chunk;
} s; /* state */
/* buffers needed for processing a request */
struct
{
hio_becs_t raw; /* buffer to hold raw octets */
hio_becs_t tra; /* buffer for handling trailers */
} b;
} fed;
hio_htre_t re;
int clean;
};
#if defined(__cplusplus)
extern "C" {
#endif
/**
* The hio_htrd_open() function creates a htrd processor.
*/
HIO_EXPORT hio_htrd_t* hio_htrd_open (
hio_t* hio, /**< memory manager */
hio_oow_t xtnsize /**< extension size in bytes */
);
/**
* The hio_htrd_close() function destroys a htrd processor.
*/
HIO_EXPORT void hio_htrd_close (
hio_htrd_t* htrd
);
HIO_EXPORT int hio_htrd_init (
hio_htrd_t* htrd,
hio_t* hio
);
HIO_EXPORT void hio_htrd_fini (
hio_htrd_t* htrd
);
#if defined(HIO_HAVE_INLINE)
static HIO_INLINE void* hio_htrd_getxtn (hio_htrd_t* htrd) { return (void*)(htrd + 1); }
#else
#define hio_htrd_getxtn(htrd) ((void*)((hio_htrd_t*)(htrd) + 1))
#endif
HIO_EXPORT hio_htrd_errnum_t hio_htrd_geterrnum (
hio_htrd_t* htrd
);
HIO_EXPORT void hio_htrd_clear (
hio_htrd_t* htrd
);
HIO_EXPORT hio_bitmask_t hio_htrd_getoption (
hio_htrd_t* htrd
);
HIO_EXPORT void hio_htrd_setoption (
hio_htrd_t* htrd,
hio_bitmask_t mask
);
HIO_EXPORT const hio_htrd_recbs_t* hio_htrd_getrecbs (
hio_htrd_t* htrd
);
HIO_EXPORT void hio_htrd_setrecbs (
hio_htrd_t* htrd,
const hio_htrd_recbs_t* recbs
);
/**
* The hio_htrd_feed() function accepts htrd request octets and invokes a
* callback function if it has processed a proper htrd request.
*/
HIO_EXPORT int hio_htrd_feed (
hio_htrd_t* htrd, /**< htrd */
const hio_bch_t* req, /**< request octets */
hio_oow_t len, /**< number of octets */
hio_oow_t* rem
);
/**
* The hio_htrd_halt() function indicates the end of feeeding
* if the current response should be processed until the
* connection is closed.
*/
HIO_EXPORT int hio_htrd_halt (
hio_htrd_t* htrd
);
HIO_EXPORT void hio_htrd_suspend (
hio_htrd_t* htrd
);
HIO_EXPORT void hio_htrd_resume (
hio_htrd_t* htrd
);
HIO_EXPORT void hio_htrd_dummify (
hio_htrd_t* htrd
);
HIO_EXPORT void hio_htrd_undummify (
hio_htrd_t* htrd
);
#if defined(__cplusplus)
}
#endif
#endif

324
hio/lib/hio-htre.h Normal file
View File

@ -0,0 +1,324 @@
/*
* $Id$
*
Copyright (c) 2016-2020 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 WARRANTIES
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 _HIO_HTRE_H_
#define _HIO_HTRE_H_
#include <hio-htb.h>
#include <hio-ecs.h>
/**
* The hio_http_version_t type defines http version.
*/
struct hio_http_version_t
{
short major; /**< major version */
short minor; /**< minor version */
};
typedef struct hio_http_version_t hio_http_version_t;
/**
* The hio_http_method_t type defines http methods .
*/
enum hio_http_method_t
{
HIO_HTTP_OTHER,
/* rfc 2616 */
HIO_HTTP_HEAD,
HIO_HTTP_GET,
HIO_HTTP_POST,
HIO_HTTP_PUT,
HIO_HTTP_DELETE,
HIO_HTTP_PATCH,
HIO_HTTP_OPTIONS,
HIO_HTTP_TRACE,
HIO_HTTP_CONNECT
#if 0
/* rfc 2518 */
HIO_HTTP_PROPFIND,
HIO_HTTP_PROPPATCH,
HIO_HTTP_MKCOL,
HIO_HTTP_COPY,
HIO_HTTP_MOVE,
HIO_HTTP_LOCK,
HIO_HTTP_UNLOCK,
/* rfc 3253 */
HIO_HTTP_VERSION_CONTROL,
HIO_HTTP_REPORT,
HIO_HTTP_CHECKOUT,
HIO_HTTP_CHECKIN,
HIO_HTTP_UNCHECKOUT,
HIO_HTTP_MKWORKSPACE,
HIO_HTTP_UPDATE,
HIO_HTTP_LABEL,
HIO_HTTP_MERGE,
HIO_HTTP_BASELINE_CONTROL,
HIO_HTTP_MKACTIVITY,
/* microsoft */
HIO_HTTP_BPROPFIND,
HIO_HTTP_BPROPPATCH,
HIO_HTTP_BCOPY,
HIO_HTTP_BDELETE,
HIO_HTTP_BMOVE,
HIO_HTTP_NOTIFY,
HIO_HTTP_POLL,
HIO_HTTP_SUBSCRIBE,
HIO_HTTP_UNSUBSCRIBE,
#endif
};
typedef enum hio_http_method_t hio_http_method_t;
/*
* You should not manipulate an object of the #hio_htre_t
* type directly since it's complex. Use #hio_htrd_t to
* create an object of the hio_htre_t type.
*/
/* header and contents of request/response */
typedef struct hio_htre_t hio_htre_t;
typedef struct hio_htre_hdrval_t hio_htre_hdrval_t;
enum hio_htre_state_t
{
HIO_HTRE_DISCARDED = (1 << 0), /** content has been discarded */
HIO_HTRE_COMPLETED = (1 << 1) /** complete content has been seen */
};
typedef enum hio_htre_state_t hio_htre_state_t;
typedef int (*hio_htre_concb_t) (
hio_htre_t* re,
const hio_bch_t* ptr,
hio_oow_t len,
void* ctx
);
struct hio_htre_hdrval_t
{
const hio_bch_t* ptr;
hio_oow_t len;
hio_htre_hdrval_t* next;
};
struct hio_htre_t
{
hio_t* hio;
enum
{
HIO_HTRE_Q,
HIO_HTRE_S
} type;
/* version */
hio_http_version_t version;
const hio_bch_t* verstr; /* version string include HTTP/ */
union
{
struct
{
struct
{
hio_http_method_t type;
const hio_bch_t* name;
} method;
hio_bcs_t path;
hio_bcs_t param;
hio_bcs_t anchor;
} q;
struct
{
struct
{
int val;
hio_bch_t* str;
} code;
hio_bch_t* mesg;
} s;
} u;
#define HIO_HTRE_ATTR_CHUNKED (1 << 0)
#define HIO_HTRE_ATTR_LENGTH (1 << 1)
#define HIO_HTRE_ATTR_KEEPALIVE (1 << 2)
#define HIO_HTRE_ATTR_EXPECT (1 << 3)
#define HIO_HTRE_ATTR_EXPECT100 (1 << 4)
#define HIO_HTRE_ATTR_PROXIED (1 << 5)
#define HIO_HTRE_QPATH_PERDEC (1 << 6) /* the qpath has been percent-decoded */
int flags;
/* original query path for a request.
* meaningful if HIO_HTRE_QPATH_PERDEC is set in the flags */
struct
{
hio_bch_t* buf; /* buffer pointer */
hio_oow_t capa; /* buffer capacity */
hio_bch_t* ptr;
hio_oow_t len;
} orgqpath;
/* special attributes derived from the header */
struct
{
hio_oow_t content_length;
const hio_bch_t* status; /* for cgi */
} attr;
/* header table */
hio_htb_t hdrtab;
hio_htb_t trailers;
/* content octets */
hio_becs_t content;
/* content callback */
hio_htre_concb_t concb;
void* concb_ctx;
/* bitwise-ORed of hio_htre_state_t */
int state;
};
#define hio_htre_getversion(re) (&((re)->version))
#define hio_htre_getmajorversion(re) ((re)->version.major)
#define hio_htre_getminorversion(re) ((re)->version.minor)
#define hio_htre_getverstr(re) ((re)->verstr)
#define hio_htre_getqmethodtype(re) ((re)->u.q.method.type)
#define hio_htre_getqmethodname(re) ((re)->u.q.method.name)
#define hio_htre_getqpath(re) ((re)->u.q.path.ptr)
#define hio_htre_getqparam(re) ((re)->u.q.param.ptr)
#define hio_htre_getqanchor(re) ((re)->u.q.anchor.ptr)
#define hio_htre_getorgqpath(re) ((re)->orgqpath.ptr)
#define hio_htre_getscodeval(re) ((re)->u.s.code.val)
#define hio_htre_getscodestr(re) ((re)->u.s.code.str)
#define hio_htre_getsmesg(re) ((re)->u.s.mesg)
#define hio_htre_getcontent(re) (&(re)->content)
#define hio_htre_getcontentbcs(re) HIO_BECS_BCS(&(re)->content)
#define hio_htre_getcontentptr(re) HIO_BECS_PTR(&(re)->content)
#define hio_htre_getcontentlen(re) HIO_BECS_LEN(&(re)->content)
typedef int (*hio_htre_header_walker_t) (
hio_htre_t* re,
const hio_bch_t* key,
const hio_htre_hdrval_t* val,
void* ctx
);
#if defined(__cplusplus)
extern "C" {
#endif
HIO_EXPORT int hio_htre_init (
hio_htre_t* re,
hio_t* hio
);
HIO_EXPORT void hio_htre_fini (
hio_htre_t* re
);
HIO_EXPORT void hio_htre_clear (
hio_htre_t* re
);
HIO_EXPORT const hio_htre_hdrval_t* hio_htre_getheaderval (
const hio_htre_t* re,
const hio_bch_t* key
);
HIO_EXPORT const hio_htre_hdrval_t* hio_htre_gettrailerval (
const hio_htre_t* re,
const hio_bch_t* key
);
HIO_EXPORT int hio_htre_walkheaders (
hio_htre_t* re,
hio_htre_header_walker_t walker,
void* ctx
);
HIO_EXPORT int hio_htre_walktrailers (
hio_htre_t* re,
hio_htre_header_walker_t walker,
void* ctx
);
/**
* The hio_htre_addcontent() function adds a content semgnet pointed to by
* @a ptr of @a len bytes to the content buffer. If @a re is already completed
* or discarded, this function returns 0 without adding the segment to the
* content buffer.
* @return 1 on success, -1 on failure, 0 if adding is skipped.
*/
HIO_EXPORT int hio_htre_addcontent (
hio_htre_t* re,
const hio_bch_t* ptr,
hio_oow_t len
);
HIO_EXPORT void hio_htre_completecontent (
hio_htre_t* re
);
HIO_EXPORT void hio_htre_discardcontent (
hio_htre_t* re
);
HIO_EXPORT void hio_htre_unsetconcb (
hio_htre_t* re
);
HIO_EXPORT void hio_htre_setconcb (
hio_htre_t* re,
hio_htre_concb_t concb,
void* ctx
);
HIO_EXPORT int hio_htre_perdecqpath (
hio_htre_t* req
);
HIO_EXPORT int hio_htre_getreqcontentlen (
hio_htre_t* req,
hio_oow_t* len
);
#if defined(__cplusplus)
}
#endif
#endif

346
hio/lib/hio-http.h Normal file
View File

@ -0,0 +1,346 @@
/*
Copyright (c) 2016-2020 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 WARRANTIES
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 _HIO_HTTP_H_
#define _HIO_HTTP_H_
#include <hio-ecs.h>
#include <hio-sck.h>
#include <hio-htre.h>
#include <hio-thr.h>
/** \file
* This file provides basic data types and functions for the http protocol.
*/
enum hio_http_range_type_t
{
HIO_HTTP_RANGE_PROPER,
HIO_HTTP_RANGE_PREFIX,
HIO_HTTP_RANGE_SUFFIX
};
typedef enum hio_http_range_type_t hio_http_range_type_t;
/**
* The hio_http_range_t type defines a structure that can represent
* a value for the \b Range: http header.
*
* If type is #HIO_HTTP_RANGE_PREFIX, 'to' is meaningless and 'from' indicates
* the number of bytes from the start.
* - 500- => from the 501st bytes all the way to the back.
*
* If type is #HIO_HTTP_RANGE_SUFFIX, 'from' is meaningless and 'to' indicates
* the number of bytes from the back.
* - -500 => last 500 bytes
*
* If type is #HIO_HTTP_RANGE_PROPER, 'from' and 'to' represents a proper range
* where the value of 0 indicates the first byte. This doesn't require any
* adjustment.
* - 0-999 => first 1000 bytes
* - 99- => from the 100th bytes to the end.
*/
struct hio_http_range_t
{
hio_http_range_type_t type; /**< type indicator */
hio_foff_t from; /**< starting offset */
hio_foff_t to; /**< ending offset */
};
typedef struct hio_http_range_t hio_http_range_t;
enum hio_perenc_http_opt_t
{
HIO_PERENC_HTTP_KEEP_SLASH = (1 << 0)
};
typedef enum hio_perenc_http_opt_t hio_perenc_bcstr_opt_t;
/* -------------------------------------------------------------- */
typedef struct hio_svc_htts_t hio_svc_htts_t;
typedef struct hio_svc_httc_t hio_svc_httc_t;
/* -------------------------------------------------------------- */
typedef struct hio_svc_htts_rsrc_t hio_svc_htts_rsrc_t;
typedef void (*hio_svc_htts_rsrc_on_kill_t) (
hio_svc_htts_rsrc_t* rsrc
);
#define HIO_SVC_HTTS_RSRC_HEADER \
hio_svc_htts_t* htts; \
hio_oow_t rsrc_size; \
hio_oow_t rsrc_refcnt; \
hio_svc_htts_rsrc_on_kill_t rsrc_on_kill
struct hio_svc_htts_rsrc_t
{
HIO_SVC_HTTS_RSRC_HEADER;
};
#define HIO_SVC_HTTS_RSRC_ATTACH(rsrc, var) do { (var) = (rsrc); ++(rsrc)->rsrc_refcnt; } while(0)
#define HIO_SVC_HTTS_RSRC_DETACH(rsrc_var) do { if (--(rsrc_var)->rsrc_refcnt == 0) { hio_svc_htts_rsrc_t* __rsrc_tmp = (rsrc_var); (rsrc_var) = HIO_NULL; hio_svc_htts_rsrc_kill(__rsrc_tmp); } else { (rsrc_var) = HIO_NULL; } } while(0)
/* -------------------------------------------------------------- */
typedef int (*hio_svc_htts_proc_req_t) (
hio_svc_htts_t* htts,
hio_dev_sck_t* sck,
hio_htre_t* req
);
/* -------------------------------------------------------------- */
struct hio_svc_htts_thr_func_info_t
{
hio_t* hio;
hio_http_method_t req_method;
hio_http_version_t req_version;
hio_bch_t* req_path;
hio_bch_t* req_param;
int req_x_http_method_override; /* -1 or hio_http_method_t */
/* TODO: header table */
hio_skad_t client_addr;
hio_skad_t server_addr;
};
typedef struct hio_svc_htts_thr_func_info_t hio_svc_htts_thr_func_info_t;
typedef void (*hio_svc_htts_thr_func_t) (
hio_t* hio,
hio_dev_thr_iopair_t* iop,
hio_svc_htts_thr_func_info_t* info,
void* ctx
);
/* -------------------------------------------------------------- */
#if defined(__cplusplus)
extern "C" {
#endif
HIO_EXPORT int hio_comp_http_versions (
const hio_http_version_t* v1,
const hio_http_version_t* v2
);
HIO_EXPORT int hio_comp_http_version_numbers (
const hio_http_version_t* v1,
int v2_major,
int v2_minor
);
HIO_EXPORT const hio_bch_t* hio_http_status_to_bcstr (
int code
);
HIO_EXPORT const hio_bch_t* hio_http_method_to_bcstr (
hio_http_method_t type
);
HIO_EXPORT hio_http_method_t hio_bcstr_to_http_method (
const hio_bch_t* name
);
HIO_EXPORT hio_http_method_t hio_bchars_to_http_method (
const hio_bch_t* nameptr,
hio_oow_t namelen
);
HIO_EXPORT int hio_parse_http_range_bcstr (
const hio_bch_t* str,
hio_http_range_t* range
);
HIO_EXPORT int hio_parse_http_time_bcstr (
const hio_bch_t* str,
hio_ntime_t* nt
);
HIO_EXPORT hio_bch_t* hio_fmt_http_time_to_bcstr (
const hio_ntime_t* nt,
hio_bch_t* buf,
hio_oow_t bufsz
);
/**
* The hio_is_perenced_http_bcstr() function determines if the given string
* contains a valid percent-encoded sequence.
*/
HIO_EXPORT int hio_is_perenced_http_bcstr (
const hio_bch_t* str
);
/**
* The hio_perdec_http_bcstr() function performs percent-decoding over a string.
* The caller must ensure that the output buffer \a buf is large enough.
* If \a ndecs is not #HIO_NULL, it is set to the number of characters
* decoded. 0 means no characters in the input string required decoding
* \return the length of the output string.
*/
HIO_EXPORT hio_oow_t hio_perdec_http_bcstr (
const hio_bch_t* str,
hio_bch_t* buf,
hio_oow_t* ndecs
);
/**
* The hio_perdec_http_bcstr() function performs percent-decoding over a length-bound string.
* It doesn't insert the terminating null.
*/
HIO_EXPORT hio_oow_t hio_perdec_http_bcs (
const hio_bcs_t* str,
hio_bch_t* buf,
hio_oow_t* ndecs
);
/**
* The hio_perenc_http_bcstr() function performs percent-encoding over a string.
* The caller must ensure that the output buffer \a buf is large enough.
* If \a nencs is not #HIO_NULL, it is set to the number of characters
* encoded. 0 means no characters in the input string required encoding.
* \return the length of the output string.
*/
HIO_EXPORT hio_oow_t hio_perenc_http_bcstr (
int opt, /**< 0 or bitwise-OR'ed of #hio_perenc_http_bcstr_opt_t */
const hio_bch_t* str,
hio_bch_t* buf,
hio_oow_t* nencs
);
#if 0
/* TODO: rename this function according to the naming convension */
HIO_EXPORT hio_bch_t* hio_perenc_http_bcstrdup (
int opt, /**< 0 or bitwise-OR'ed of #hio_perenc_http_bcstr_opt_t */
const hio_bch_t* str,
hio_mmgr_t* mmgr
);
#endif
HIO_EXPORT int hio_scan_http_qparam (
hio_bch_t* qparam,
int (*qparamcb) (hio_bcs_t* key, hio_bcs_t* val, void* ctx),
void* ctx
);
/* ------------------------------------------------------------------------- */
/* HTTP SERVER SERVICE */
/* ------------------------------------------------------------------------- */
HIO_EXPORT hio_svc_htts_t* hio_svc_htts_start (
hio_t* hio,
hio_dev_sck_bind_t* sck_bind,
hio_svc_htts_proc_req_t proc_req
);
HIO_EXPORT void hio_svc_htts_stop (
hio_svc_htts_t* htts
);
#if defined(HIO_HAVE_INLINE)
static HIO_INLINE hio_t* hio_svc_htts_gethio(hio_svc_htts_t* svc) { return hio_svc_gethio((hio_svc_t*)svc); }
#else
# define hio_svc_htts_gethio(svc) hio_svc_gethio(svc)
#endif
HIO_EXPORT int hio_svc_htts_writetosidechan (
hio_svc_htts_t* htts,
const void* dptr,
hio_oow_t dlen
);
HIO_EXPORT int hio_svc_htts_setservernamewithbcstr (
hio_svc_htts_t* htts,
const hio_bch_t* server_name
);
HIO_EXPORT int hio_svc_htts_getsockaddr (
hio_svc_htts_t* htts,
hio_skad_t* skad
);
HIO_EXPORT int hio_svc_htts_docgi (
hio_svc_htts_t* htts,
hio_dev_sck_t* csck,
hio_htre_t* req,
const hio_bch_t* docroot,
const hio_bch_t* script
);
HIO_EXPORT int hio_svc_htts_dofile (
hio_svc_htts_t* htts,
hio_dev_sck_t* csck,
hio_htre_t* req,
const hio_bch_t* docroot,
const hio_bch_t* filepath,
const hio_bch_t* mime_type
);
HIO_EXPORT int hio_svc_htts_dothr (
hio_svc_htts_t* htts,
hio_dev_sck_t* csck,
hio_htre_t* req,
hio_svc_htts_thr_func_t func,
void* ctx
);
HIO_EXPORT int hio_svc_htts_dotxt (
hio_svc_htts_t* htts,
hio_dev_sck_t* csck,
hio_htre_t* req,
int status_code,
const hio_bch_t* content_type,
const hio_bch_t* content_text
);
HIO_EXPORT hio_svc_htts_rsrc_t* hio_svc_htts_rsrc_make (
hio_svc_htts_t* htts,
hio_oow_t rsrc_size,
hio_svc_htts_rsrc_on_kill_t on_kill
);
HIO_EXPORT void hio_svc_htts_rsrc_kill (
hio_svc_htts_rsrc_t* rsrc
);
HIO_EXPORT void hio_svc_htts_fmtgmtime (
hio_svc_htts_t* htts,
const hio_ntime_t* nt,
hio_bch_t* buf,
hio_oow_t len
);
HIO_EXPORT hio_bch_t* hio_svc_htts_dupmergepaths (
hio_svc_htts_t* htts,
const hio_bch_t* base,
const hio_bch_t* path
);
#if defined(__cplusplus)
}
#endif
#endif

396
hio/lib/hio-json.h Normal file
View File

@ -0,0 +1,396 @@
/*
* $Id$
*
Copyright (c) 2016-2020 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 WARRANTIES
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 _HIO_JSON_H_
#define _HIO_JSON_H_
#include <hio.h>
/**
* The hio_json_t type defines a simple json parser.
*/
typedef struct hio_json_t hio_json_t;
/* ========================================================================= */
enum hio_json_state_t
{
HIO_JSON_STATE_START,
HIO_JSON_STATE_IN_ARRAY,
HIO_JSON_STATE_IN_OBJECT,
HIO_JSON_STATE_IN_WORD_VALUE,
HIO_JSON_STATE_IN_NUMERIC_VALUE,
HIO_JSON_STATE_IN_STRING_VALUE
};
typedef enum hio_json_state_t hio_json_state_t;
/* ========================================================================= */
enum hio_json_inst_t
{
HIO_JSON_INST_START_ARRAY,
HIO_JSON_INST_END_ARRAY,
HIO_JSON_INST_START_OBJECT,
HIO_JSON_INST_END_OBJECT,
HIO_JSON_INST_KEY,
HIO_JSON_INST_STRING,
HIO_JSON_INST_NUMBER,
HIO_JSON_INST_NIL,
HIO_JSON_INST_TRUE,
HIO_JSON_INST_FALSE,
};
typedef enum hio_json_inst_t hio_json_inst_t;
typedef int (*hio_json_instcb_t) (
hio_json_t* json,
hio_json_inst_t inst,
hio_oow_t level,
hio_oow_t index,
hio_json_state_t container_state,
const hio_oocs_t* str,
void* ctx
);
typedef struct hio_json_state_node_t hio_json_state_node_t;
struct hio_json_state_node_t
{
hio_json_state_t state;
hio_oow_t level;
hio_oow_t index;
int in_comment;
union
{
struct
{
int got_value;
} ia; /* in array */
struct
{
/* 0: ready to get key (at the beginning or got comma),
* 1: got key, 2: got colon, 3: got value */
int state;
} io; /* in object */
struct
{
int escaped;
int digit_count;
/* acc is always of unicode type to handle \u and \U.
* in the bch mode, it will get converted to a utf8 stream. */
hio_uch_t acc;
} sv;
struct
{
int escaped;
int digit_count;
/* for a character, no way to support the unicode character
* in the bch mode */
hio_ooch_t acc;
} cv;
struct
{
int progress;
} nv;
} u;
hio_json_state_node_t* next;
};
enum hio_json_option_t
{
/* allow an unquoted word as an object key */
HIO_JSON_PERMIT_WORD_KEY = ((hio_bitmask_t)1 << 0),
/* a comma as a separator is not mandatory */
HIO_JSON_OPTIONAL_COMMA = ((hio_bitmask_t)1 << 1),
/* support the line comment. the text beginning with # is a comment to the end of the line */
HIO_JSON_LINE_COMMENT = ((hio_bitmask_t)1 << 2)
};
typedef enum hio_json_option_t hio_json_option_t;
struct hio_json_t
{
hio_t* hio;
hio_json_instcb_t instcb;
void* rctx;
hio_bitmask_t option;
hio_json_state_node_t state_top;
hio_json_state_node_t* state_stack;
hio_oocs_t tok;
hio_oow_t tok_capa;
hio_oow_t tok_line;
hio_oow_t tok_col;
hio_oow_t c_line;
hio_oow_t c_col;
};
/* ========================================================================= */
typedef struct hio_jsonwr_t hio_jsonwr_t;
typedef int (*hio_jsonwr_writecb_t) (
hio_jsonwr_t* jsonwr,
const hio_bch_t* dptr,
hio_oow_t dlen,
void* ctx
);
typedef struct hio_jsonwr_state_node_t hio_jsonwr_state_node_t;
struct hio_jsonwr_state_node_t
{
hio_json_state_t state;
hio_oow_t level;
hio_oow_t index;
int obj_awaiting_val;
hio_jsonwr_state_node_t* next;
};
enum hio_jsonwr_flag_t
{
HIO_JSONWR_FLAG_PRETTY = (1 << 0)
};
typedef enum hio_jsonwr_flag_t hio_jsonwr_flag_t;
struct hio_jsonwr_t
{
hio_t* hio;
hio_jsonwr_writecb_t writecb;
hio_jsonwr_state_node_t state_top;
hio_jsonwr_state_node_t* state_stack;
int flags;
void* wctx;
hio_bch_t wbuf[8192];
hio_oow_t wbuf_len;
};
/* ========================================================================= */
#if defined(__cplusplus)
extern "C" {
#endif
HIO_EXPORT hio_json_t* hio_json_open (
hio_t* hio,
hio_oow_t xtnsize
);
HIO_EXPORT void hio_json_close (
hio_json_t* json
);
HIO_EXPORT int hio_json_init (
hio_json_t* json,
hio_t* hio
);
HIO_EXPORT void hio_json_fini (
hio_json_t* json
);
#if defined(HIO_HAVE_INLINE)
static HIO_INLINE hio_t* hio_json_gethio (hio_json_t* json) { return json->hio; }
#else
# define hio_json_gethio(json) (((hio_json_t*)(json))->hio)
#endif
#if defined(HIO_HAVE_INLINE)
static HIO_INLINE void* hio_json_getxtn (hio_json_t* json) { return (void*)(json + 1); }
#else
#define hio_json_getxtn(json) ((void*)((hio_json_t*)(json) + 1))
#endif
HIO_EXPORT hio_bitmask_t hio_json_getoption (
hio_json_t* json
);
HIO_EXPORT void hio_json_setoption (
hio_json_t* json,
hio_bitmask_t mask
);
HIO_EXPORT void hio_json_setinstcb (
hio_json_t* json,
hio_json_instcb_t instcb,
void* ctx
);
HIO_EXPORT hio_json_state_t hio_json_getstate (
hio_json_t* json
);
HIO_EXPORT void hio_json_resetstates (
hio_json_t* json
);
HIO_EXPORT void hio_json_resetfeedloc (
hio_json_t* json
);
/**
* The hio_json_feed() function processes the raw data.
*
* If stop_if_ever_complted is 0, it returns 0 on success. If the value pointed to by
* rem is greater 0 after the call, processing is not complete and more feeding is
* required. Incomplete feeding may be caused by incomplete byte sequences or incomplete
* json object.
*
* If stop_if_ever_completed is non-zero, it returns 0 upon incomplet byte sequence or
* incomplete json object. It returns 1 if it sees the first complete json object. It stores
* the size of remaning raw data in the memory pointed to by rem.
*
* The function returns -1 upon failure.
*/
HIO_EXPORT int hio_json_feed (
hio_json_t* json,
const void* ptr,
hio_oow_t len,
hio_oow_t* rem,
int stop_if_ever_completed
);
/* ========================================================================= */
HIO_EXPORT hio_jsonwr_t* hio_jsonwr_open (
hio_t* hio,
hio_oow_t xtnsize,
int flags
);
HIO_EXPORT void hio_jsonwr_close (
hio_jsonwr_t* jsonwr
);
HIO_EXPORT int hio_jsonwr_init (
hio_jsonwr_t* jsonwr,
hio_t* hio,
int flags
);
HIO_EXPORT void hio_jsonwr_fini (
hio_jsonwr_t* jsonwr
);
#if defined(HIO_HAVE_INLINE)
static HIO_INLINE hio_t* hio_jsonwr_gethio (hio_jsonwr_t* jsonwr) { return jsonwr->hio; }
#else
# define hio_jsonwr_gethio(jsonwr) (((hio_jsonwr_t*)(jsonwr))->hio)
#endif
#if defined(HIO_HAVE_INLINE)
static HIO_INLINE void* hio_jsonwr_getxtn (hio_jsonwr_t* jsonwr) { return (void*)(jsonwr + 1); }
#else
#define hio_jsonwr_getxtn(jsonwr) ((void*)((hio_jsonwr_t*)(jsonwr) + 1))
#endif
HIO_EXPORT void hio_jsonwr_setwritecb (
hio_jsonwr_t* jsonwr,
hio_jsonwr_writecb_t writecb,
void* ctx
);
HIO_EXPORT int hio_jsonwr_write (
hio_jsonwr_t* jsonwr,
hio_json_inst_t inst,
int is_uchars,
const void* dptr,
hio_oow_t dlen
);
#define hio_jsonwr_startarray(jsonwr) hio_jsonwr_write(jsonwr, HIO_JSON_INST_START_ARRAY, 0, HIO_NULL, 0)
#define hio_jsonwr_endarray(jsonwr) hio_jsonwr_write(jsonwr, HIO_JSON_INST_END_ARRAY, 0, HIO_NULL, 0)
#define hio_jsonwr_startobject(jsonwr) hio_jsonwr_write(jsonwr, HIO_JSON_INST_START_OBJECT, 0, HIO_NULL, 0)
#define hio_jsonwr_endobject(jsonwr) hio_jsonwr_write(jsonwr, HIO_JSON_INST_END_OBJECT, 0, HIO_NULL, 0)
#define hio_jsonwr_writenil(jsonwr) hio_jsonwr_write(jsonwr, HIO_JSON_INST_NIL, 0, HIO_NULL, 0)
#define hio_jsonwr_writetrue(jsonwr) hio_jsonwr_write(jsonwr, HIO_JSON_INST_TRUE, 0, HIO_NULL, 0)
#define hio_jsonwr_writefalse(jsonwr) hio_jsonwr_write(jsonwr, HIO_JSON_INST_FALSE, 0, HIO_NULL, 0)
#define hio_jsonwr_writekeywithuchars(jsonwr,dptr,dlen) hio_jsonwr_write(jsonwr, HIO_JSON_INST_KEY, 1, dptr, dlen)
#define hio_jsonwr_writekeywithbchars(jsonwr,dptr,dlen) hio_jsonwr_write(jsonwr, HIO_JSON_INST_KEY, 0, dptr, dlen)
#define hio_jsonwr_writekeywithucstr(jsonwr,dptr) hio_jsonwr_write(jsonwr, HIO_JSON_INST_KEY, 1, dptr, hio_count_ucstr(dptr))
#define hio_jsonwr_writekeywithbcstr(jsonwr,dptr) hio_jsonwr_write(jsonwr, HIO_JSON_INST_KEY, 0, dptr, hio_count_bcstr(dptr))
#define hio_jsonwr_writenumberwithuchars(jsonwr,dptr,dlen) hio_jsonwr_write(jsonwr, HIO_JSON_INST_NUMBER, 1, dptr, dlen)
#define hio_jsonwr_writenumberwithbchars(jsonwr,dptr,dlen) hio_jsonwr_write(jsonwr, HIO_JSON_INST_NUMBER, 0, dptr, dlen)
#define hio_jsonwr_writenumberwithucstr(jsonwr,dptr) hio_jsonwr_write(jsonwr, HIO_JSON_INST_NUMBER, 1, dptr, hio_count_ucstr(dptr))
#define hio_jsonwr_writenumberwithbcstr(jsonwr,dptr) hio_jsonwr_write(jsonwr, HIO_JSON_INST_NUMBER, 0, dptr, hio_count_bcstr(dptr))
#define hio_jsonwr_writestringwithuchars(jsonwr,dptr,dlen) hio_jsonwr_write(jsonwr, HIO_JSON_INST_STRING, 1, dptr, dlen)
#define hio_jsonwr_writestringwithbchars(jsonwr,dptr,dlen) hio_jsonwr_write(jsonwr, HIO_JSON_INST_STRING, 0, dptr, dlen)
#define hio_jsonwr_writestringwithucstr(jsonwr,dptr) hio_jsonwr_write(jsonwr, HIO_JSON_INST_STRING, 1, dptr, hio_count_ucstr(dptr))
#define hio_jsonwr_writestringwithbcstr(jsonwr,dptr) hio_jsonwr_write(jsonwr, HIO_JSON_INST_STRING, 0, dptr, hio_count_bcstr(dptr))
HIO_EXPORT int hio_jsonwr_writeintmax (
hio_jsonwr_t* jsonwr,
hio_intmax_t v
);
HIO_EXPORT int hio_jsonwr_writeuintmax (
hio_jsonwr_t* jsonwr,
hio_uintmax_t v
);
HIO_EXPORT int hio_jsonwr_writerawuchars (
hio_jsonwr_t* jsonwr,
const hio_uch_t* dptr,
hio_oow_t dlen
);
HIO_EXPORT int hio_jsonwr_writerawucstr (
hio_jsonwr_t* jsonwr,
const hio_uch_t* dptr
);
HIO_EXPORT int hio_jsonwr_writerawbchars (
hio_jsonwr_t* jsonwr,
const hio_bch_t* dptr,
hio_oow_t dlen
);
HIO_EXPORT int hio_jsonwr_writerawbcstr (
hio_jsonwr_t* jsonwr,
const hio_bch_t* dptr
);
#if defined(__cplusplus)
}
#endif
#endif

288
hio/lib/hio-mar.h Normal file
View File

@ -0,0 +1,288 @@
/*
* $Id$
*
Copyright (c) 2016-2020 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 PIPEVIDED 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, PIPECUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PIPEFITS; 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 _HIO_MAR_H_
#define _HIO_MAR_H_
#include <hio.h>
typedef struct hio_dev_mar_t hio_dev_mar_t;
enum hio_dev_mar_progress_t
{
HIO_DEV_MAR_INITIAL,
HIO_DEV_MAR_CONNECTING,
HIO_DEV_MAR_CONNECTED,
HIO_DEV_MAR_QUERY_STARTING,
HIO_DEV_MAR_QUERY_STARTED,
HIO_DEV_MAR_ROW_FETCHING,
HIO_DEV_MAR_ROW_FETCHED
};
typedef enum hio_dev_mar_progress_t hio_dev_mar_progress_t;
#define HIO_DEV_MAR_SET_PROGRESS(dev,value) ((dev)->progress = (value))
#define HIO_DEV_MAR_GET_PROGRESS(dev) ((dev)->progress)
typedef int (*hio_dev_mar_on_read_t) (
hio_dev_mar_t* dev,
const void* data,
hio_iolen_t len
);
typedef int (*hio_dev_mar_on_write_t) (
hio_dev_mar_t* dev,
hio_iolen_t wrlen,
void* wrctx
);
typedef void (*hio_dev_mar_on_connect_t) (
hio_dev_mar_t* dev
);
typedef void (*hio_dev_mar_on_disconnect_t) (
hio_dev_mar_t* dev
);
typedef void (*hio_dev_mar_on_query_started_t) (
hio_dev_mar_t* dev,
int mar_ret,
const hio_bch_t* mar_errmsg
);
typedef void (*hio_dev_mar_on_row_fetched_t) (
hio_dev_mar_t* dev,
void* row_data
);
struct hio_dev_mar_t
{
HIO_DEV_HEADER;
void* hnd;
void* res;
hio_dev_mar_progress_t progress;
unsigned int connected: 1;
unsigned int connected_deferred: 1;
unsigned int query_started_deferred: 1;
/*unsigned int query_started: 1;*/
unsigned int row_fetched_deferred: 1;
unsigned int broken: 1;
hio_syshnd_t broken_syshnd;
int row_wstatus;
void* row;
hio_dev_mar_on_read_t on_read;
hio_dev_mar_on_write_t on_write;
hio_dev_mar_on_connect_t on_connect;
hio_dev_mar_on_disconnect_t on_disconnect;
hio_dev_mar_on_query_started_t on_query_started;
hio_dev_mar_on_row_fetched_t on_row_fetched;
};
enum hio_dev_mar_make_flag_t
{
HIO_DEV_MAR_USE_TMOUT = (1 << 0)
};
typedef enum hio_dev_mar_make_flag_t hio_dev_mar_make_flag_t;
typedef struct hio_dev_mar_tmout_t hio_dev_mar_tmout_t;
struct hio_dev_mar_tmout_t
{
hio_ntime_t c;
hio_ntime_t r;
hio_ntime_t w;
};
typedef struct hio_dev_mar_make_t hio_dev_mar_make_t;
struct hio_dev_mar_make_t
{
int flags;
hio_dev_mar_tmout_t tmout;
hio_dev_mar_on_write_t on_write; /* mandatory */
hio_dev_mar_on_read_t on_read; /* mandatory */
hio_dev_mar_on_connect_t on_connect; /* optional */
hio_dev_mar_on_disconnect_t on_disconnect; /* optional */
hio_dev_mar_on_query_started_t on_query_started;
hio_dev_mar_on_row_fetched_t on_row_fetched;
};
typedef struct hio_dev_mar_connect_t hio_dev_mar_connect_t;
struct hio_dev_mar_connect_t
{
const hio_bch_t* host;
const hio_bch_t* username;
const hio_bch_t* password;
const hio_bch_t* dbname;
hio_uint16_t port;
};
enum hio_dev_mar_ioctl_cmd_t
{
HIO_DEV_MAR_CONNECT,
HIO_DEV_MAR_QUERY_WITH_BCS,
HIO_DEV_MAR_FETCH_ROW
};
typedef enum hio_dev_mar_ioctl_cmd_t hio_dev_mar_ioctl_cmd_t;
/* -------------------------------------------------------------- */
typedef struct hio_svc_marc_t hio_svc_marc_t;
typedef hio_dev_mar_connect_t hio_svc_marc_connect_t;
typedef hio_dev_mar_tmout_t hio_svc_marc_tmout_t;
enum hio_svc_marc_qtype_t
{
HIO_SVC_MARC_QTYPE_SELECT, /* SELECT, SHOW, ... */
HIO_SVC_MARC_QTYPE_ACTION /* UPDATE, INSERT, DELETE, ALTER ... */
};
typedef enum hio_svc_marc_qtype_t hio_svc_marc_qtype_t;
enum hio_svc_marc_rcode_t
{
HIO_SVC_MARC_RCODE_ROW, /* has row *- data is MYSQL_ROW */
HIO_SVC_MARC_RCODE_DONE, /* completed or no more row - data is NULL */
HIO_SVC_MARC_RCODE_ERROR /* query error - data is hio_sv_marc_dev_error_t* */
};
typedef enum hio_svc_marc_rcode_t hio_svc_marc_rcode_t;
struct hio_svc_marc_dev_error_t
{
int mar_errcode;
const hio_bch_t* mar_errmsg;
};
typedef struct hio_svc_marc_dev_error_t hio_svc_marc_dev_error_t;
typedef void (*hio_svc_marc_on_result_t) (
hio_svc_marc_t* marc,
hio_oow_t sid,
hio_svc_marc_rcode_t rcode,
void* data,
void* qctx
);
/* -------------------------------------------------------------- */
#ifdef __cplusplus
extern "C" {
#endif
HIO_EXPORT hio_dev_mar_t* hio_dev_mar_make (
hio_t* hio,
hio_oow_t xtnsize,
const hio_dev_mar_make_t* data
);
#if defined(HIO_HAVE_INLINE)
static HIO_INLINE hio_t* hio_dev_mar_gethio (hio_dev_mar_t* mar) { return hio_dev_gethio((hio_dev_t*)mar); }
#else
# define hio_dev_mar_gethio(mar) hio_dev_gethio(mar)
#endif
#if defined(HIO_HAVE_INLINE)
static HIO_INLINE void* hio_dev_mar_getxtn (hio_dev_mar_t* mar) { return (void*)(mar + 1); }
#else
# define hio_dev_mar_getxtn(mar) ((void*)(((hio_dev_mar_t*)mar) + 1))
#endif
HIO_EXPORT int hio_dev_mar_connect (
hio_dev_mar_t* mar,
hio_dev_mar_connect_t* ci
);
HIO_EXPORT int hio_dev_mar_querywithbchars (
hio_dev_mar_t* mar,
const hio_bch_t* qstr,
hio_oow_t qlen
);
HIO_EXPORT int hio_dev_mar_fetchrows (
hio_dev_mar_t* mar
);
#if defined(HIO_HAVE_INLINE)
static HIO_INLINE void hio_dev_mar_kill (hio_dev_mar_t* mar) { hio_dev_kill ((hio_dev_t*)mar); }
static HIO_INLINE void hio_dev_mar_halt (hio_dev_mar_t* mar) { hio_dev_halt ((hio_dev_t*)mar); }
#else
# define hio_dev_mar_kill(mar) hio_dev_kill((hio_dev_t*)mar)
# define hio_dev_mar_halt(mar) hio_dev_halt((hio_dev_t*)mar)
#endif
HIO_EXPORT hio_oow_t hio_dev_mar_escapebchars (
hio_dev_mar_t* dev,
const hio_bch_t* qstr,
hio_oow_t qlen,
hio_bch_t* buf
);
/* ------------------------------------------------------------------------- */
/* MARDB CLIENT SERVICE */
/* ------------------------------------------------------------------------- */
HIO_EXPORT hio_svc_marc_t* hio_svc_marc_start (
hio_t* hio,
const hio_svc_marc_connect_t* ci,
const hio_svc_marc_tmout_t* tmout
);
HIO_EXPORT void hio_svc_marc_stop (
hio_svc_marc_t* marc
);
#if defined(HIO_HAVE_INLINE)
static HIO_INLINE hio_t* hio_svc_marc_gethio(hio_svc_marc_t* svc) { return hio_svc_gethio((hio_svc_t*)svc); }
#else
# define hio_svc_marc_gethio(svc) hio_svc_gethio(svc)
#endif
HIO_EXPORT int hio_svc_marc_querywithbchars (
hio_svc_marc_t* marc,
hio_oow_t sid,
hio_svc_marc_qtype_t qtype,
const hio_bch_t* qptr,
hio_oow_t qlen,
hio_svc_marc_on_result_t on_result,
void* qctx
);
HIO_EXPORT hio_oow_t hio_svc_marc_escapebchars (
hio_svc_marc_t* marc,
const hio_bch_t* qstr,
hio_oow_t qlen,
hio_bch_t* buf
);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -24,52 +24,52 @@
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _MIO_NWIF_H_
#define _MIO_NWIF_H_
#ifndef _HIO_NWIF_H_
#define _HIO_NWIF_H_
#include <mio.h>
#include <mio-skad.h>
#include <hio.h>
#include <hio-skad.h>
typedef struct mio_ifcfg_t mio_ifcfg_t;
typedef struct hio_ifcfg_t hio_ifcfg_t;
enum mio_ifcfg_flag_t
enum hio_ifcfg_flag_t
{
MIO_IFCFG_UP = (1 << 0),
MIO_IFCFG_RUNNING = (1 << 1),
MIO_IFCFG_BCAST = (1 << 2),
MIO_IFCFG_PTOP = (1 << 3), /* peer to peer */
MIO_IFCFG_LINKUP = (1 << 4),
MIO_IFCFG_LINKDOWN = (1 << 5)
HIO_IFCFG_UP = (1 << 0),
HIO_IFCFG_RUNNING = (1 << 1),
HIO_IFCFG_BCAST = (1 << 2),
HIO_IFCFG_PTOP = (1 << 3), /* peer to peer */
HIO_IFCFG_LINKUP = (1 << 4),
HIO_IFCFG_LINKDOWN = (1 << 5)
};
enum mio_ifcfg_type_t
enum hio_ifcfg_type_t
{
MIO_IFCFG_IN4 = MIO_AF_INET,
MIO_IFCFG_IN6 = MIO_AF_INET6
HIO_IFCFG_IN4 = HIO_AF_INET,
HIO_IFCFG_IN6 = HIO_AF_INET6
};
typedef enum mio_ifcfg_type_t mio_ifcfg_type_t;
struct mio_ifcfg_t
typedef enum hio_ifcfg_type_t hio_ifcfg_type_t;
struct hio_ifcfg_t
{
mio_ifcfg_type_t type; /* in */
mio_ooch_t name[64]; /* in/out */
hio_ifcfg_type_t type; /* in */
hio_ooch_t name[64]; /* in/out */
unsigned int index; /* in/out */
/* ---------------- */
int flags; /* out */
int mtu; /* out */
mio_skad_t addr; /* out */
mio_skad_t mask; /* out */
mio_skad_t ptop; /* out */
mio_skad_t bcast; /* out */
hio_skad_t addr; /* out */
hio_skad_t mask; /* out */
hio_skad_t ptop; /* out */
hio_skad_t bcast; /* out */
/* ---------------- */
/* TODO: add hwaddr?? */
/* i support ethernet only currently */
mio_uint8_t ethw[6]; /* out */
hio_uint8_t ethw[6]; /* out */
};
@ -77,59 +77,59 @@ struct mio_ifcfg_t
extern "C" {
#endif
MIO_EXPORT int mio_bcstrtoifindex (
mio_t* mio,
const mio_bch_t* ptr,
HIO_EXPORT int hio_bcstrtoifindex (
hio_t* hio,
const hio_bch_t* ptr,
unsigned int* index
);
MIO_EXPORT int mio_bcharstoifindex (
mio_t* mio,
const mio_bch_t* ptr,
mio_oow_t len,
HIO_EXPORT int hio_bcharstoifindex (
hio_t* hio,
const hio_bch_t* ptr,
hio_oow_t len,
unsigned int* index
);
MIO_EXPORT int mio_ucstrtoifindex (
mio_t* mio,
const mio_uch_t* ptr,
HIO_EXPORT int hio_ucstrtoifindex (
hio_t* hio,
const hio_uch_t* ptr,
unsigned int* index
);
MIO_EXPORT int mio_ucharstoifindex (
mio_t* mio,
const mio_uch_t* ptr,
mio_oow_t len,
HIO_EXPORT int hio_ucharstoifindex (
hio_t* hio,
const hio_uch_t* ptr,
hio_oow_t len,
unsigned int* index
);
MIO_EXPORT int mio_ifindextobcstr (
mio_t* mio,
HIO_EXPORT int hio_ifindextobcstr (
hio_t* hio,
unsigned int index,
mio_bch_t* buf,
mio_oow_t len
hio_bch_t* buf,
hio_oow_t len
);
MIO_EXPORT int mio_ifindextoucstr (
mio_t* mio,
HIO_EXPORT int hio_ifindextoucstr (
hio_t* hio,
unsigned int index,
mio_uch_t* buf,
mio_oow_t len
hio_uch_t* buf,
hio_oow_t len
);
#if defined(MIO_OOCH_IS_UCH)
# define mio_oocstrtoifindex mio_ucstrtoifindex
# define mio_oocharstoifindex mio_ucharstoifindex
# define mio_ifindextooocstr mio_ifindextoucstr
#if defined(HIO_OOCH_IS_UCH)
# define hio_oocstrtoifindex hio_ucstrtoifindex
# define hio_oocharstoifindex hio_ucharstoifindex
# define hio_ifindextooocstr hio_ifindextoucstr
#else
# define mio_oocstrtoifindex mio_bcstrtoifindex
# define mio_oocharstoifindex mio_bcharstoifindex
# define mio_ifindextooocstr mio_ifindextobcstr
# define hio_oocstrtoifindex hio_bcstrtoifindex
# define hio_oocharstoifindex hio_bcharstoifindex
# define hio_ifindextooocstr hio_ifindextobcstr
#endif
MIO_EXPORT int mio_getifcfg (
mio_t* mio,
mio_ifcfg_t* cfg
HIO_EXPORT int hio_getifcfg (
hio_t* hio,
hio_ifcfg_t* cfg
);
#if defined(__cplusplus)

View File

@ -24,72 +24,72 @@
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _MIO_OPT_H_
#define _MIO_OPT_H_
#ifndef _HIO_OPT_H_
#define _HIO_OPT_H_
#include "mio-cmn.h"
#include "hio-cmn.h"
/** \file
* This file defines functions and data structures to process
* command-line arguments.
*/
typedef struct mio_uopt_t mio_uopt_t;
typedef struct mio_uopt_lng_t mio_uopt_lng_t;
typedef struct hio_uopt_t hio_uopt_t;
typedef struct hio_uopt_lng_t hio_uopt_lng_t;
struct mio_uopt_lng_t
struct hio_uopt_lng_t
{
const mio_uch_t* str;
mio_uci_t val;
const hio_uch_t* str;
hio_uci_t val;
};
struct mio_uopt_t
struct hio_uopt_t
{
/* input */
const mio_uch_t* str; /* option string */
mio_uopt_lng_t* lng; /* long options */
const hio_uch_t* str; /* option string */
hio_uopt_lng_t* lng; /* long options */
/* output */
mio_uci_t opt; /* character checked for validity */
mio_uch_t* arg; /* argument associated with an option */
hio_uci_t opt; /* character checked for validity */
hio_uch_t* arg; /* argument associated with an option */
/* output */
const mio_uch_t* lngopt;
const hio_uch_t* lngopt;
/* input + output */
int ind; /* index into parent argv vector */
/* input + output - internal*/
mio_uch_t* cur;
hio_uch_t* cur;
};
typedef struct mio_bopt_t mio_bopt_t;
typedef struct mio_bopt_lng_t mio_bopt_lng_t;
typedef struct hio_bopt_t hio_bopt_t;
typedef struct hio_bopt_lng_t hio_bopt_lng_t;
struct mio_bopt_lng_t
struct hio_bopt_lng_t
{
const mio_bch_t* str;
mio_bci_t val;
const hio_bch_t* str;
hio_bci_t val;
};
struct mio_bopt_t
struct hio_bopt_t
{
/* input */
const mio_bch_t* str; /* option string */
mio_bopt_lng_t* lng; /* long options */
const hio_bch_t* str; /* option string */
hio_bopt_lng_t* lng; /* long options */
/* output */
mio_bci_t opt; /* character checked for validity */
mio_bch_t* arg; /* argument associated with an option */
hio_bci_t opt; /* character checked for validity */
hio_bch_t* arg; /* argument associated with an option */
/* output */
const mio_bch_t* lngopt;
const hio_bch_t* lngopt;
/* input + output */
int ind; /* index into parent argv vector */
/* input + output - internal*/
mio_bch_t* cur;
hio_bch_t* cur;
};
#if defined(__cplusplus)
@ -97,7 +97,7 @@ extern "C" {
#endif
/**
* The mio_getopt() function processes the \a argc command-line arguments
* The hio_getopt() function processes the \a argc command-line arguments
* pointed to by \a argv as configured in \a opt. It can process two
* different option styles: a single character starting with '-', and a
* long name starting with '--'.
@ -109,29 +109,29 @@ extern "C" {
* - \b ? indicates a bad option stored in the \a opt->opt field.
* - \b : indicates a bad parameter for an option stored in the \a opt->opt field.
*
* @return an option character on success, MIO_CHAR_EOF on no more options.
* @return an option character on success, HIO_CHAR_EOF on no more options.
*/
MIO_EXPORT mio_uci_t mio_getuopt (
HIO_EXPORT hio_uci_t hio_getuopt (
int argc, /* argument count */
mio_uch_t* const* argv, /* argument array */
mio_uopt_t* opt /* option configuration */
hio_uch_t* const* argv, /* argument array */
hio_uopt_t* opt /* option configuration */
);
MIO_EXPORT mio_bci_t mio_getbopt (
HIO_EXPORT hio_bci_t hio_getbopt (
int argc, /* argument count */
mio_bch_t* const* argv, /* argument array */
mio_bopt_t* opt /* option configuration */
hio_bch_t* const* argv, /* argument array */
hio_bopt_t* opt /* option configuration */
);
#if defined(MIO_OOCH_IS_UCH)
# define mio_opt_t mio_uopt_t
# define mio_opt_lng_t mio_uopt_lng_t
# define mio_getopt(argc,argv,opt) mio_getuopt(argc,argv,opt)
#if defined(HIO_OOCH_IS_UCH)
# define hio_opt_t hio_uopt_t
# define hio_opt_lng_t hio_uopt_lng_t
# define hio_getopt(argc,argv,opt) hio_getuopt(argc,argv,opt)
#else
# define mio_opt_t mio_bopt_t
# define mio_opt_lng_t mio_bopt_lng_t
# define mio_getopt(argc,argv,opt) mio_getbopt(argc,argv,opt)
# define hio_opt_t hio_bopt_t
# define hio_opt_lng_t hio_bopt_lng_t
# define hio_getopt(argc,argv,opt) hio_getbopt(argc,argv,opt)
#endif
#if defined(__cplusplus)

View File

@ -24,68 +24,68 @@
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _MIO_PATH_H_
#define _MIO_PATH_H_
#ifndef _HIO_PATH_H_
#define _HIO_PATH_H_
#include <mio.h>
#include <mio-utl.h>
#include <hio.h>
#include <hio-utl.h>
enum mio_canon_path_flag_t
enum hio_canon_path_flag_t
{
/** if the final output is . logically, return an empty path */
MIO_CANON_PATH_EMPTY_SINGLE_DOT = (1 << 0),
HIO_CANON_PATH_EMPTY_SINGLE_DOT = (1 << 0),
/** keep the .. segment in the path name */
MIO_CANON_PATH_KEEP_DOUBLE_DOTS = (1 << 1),
HIO_CANON_PATH_KEEP_DOUBLE_DOTS = (1 << 1),
/** drop a trailing separator even if the source contains one */
MIO_CANON_PATH_DROP_TRAILING_SEP = (1 << 2)
HIO_CANON_PATH_DROP_TRAILING_SEP = (1 << 2)
};
typedef enum mio_canon_path_flag_t mio_canon_path_flag_t;
typedef enum hio_canon_path_flag_t hio_canon_path_flag_t;
#define MIO_CANON_OOCSTR_PATH_EMPTY_SINGLE_DOT MIO_CANON_PATH_EMPTY_SINGLE_DOT
#define MIO_CANON_OOCSTR_PATH_KEEP_DOUBLE_DOTS MIO_CANON_PATH_KEEP_DOUBLE_DOTS
#define MIO_CANON_OOCSTR_PATH_DROP_TRAILING_SEP MIO_CANON_PATH_DROP_TRAILING_SEP
#define HIO_CANON_OOCSTR_PATH_EMPTY_SINGLE_DOT HIO_CANON_PATH_EMPTY_SINGLE_DOT
#define HIO_CANON_OOCSTR_PATH_KEEP_DOUBLE_DOTS HIO_CANON_PATH_KEEP_DOUBLE_DOTS
#define HIO_CANON_OOCSTR_PATH_DROP_TRAILING_SEP HIO_CANON_PATH_DROP_TRAILING_SEP
#define MIO_CANON_UCSTR_PATH_EMPTY_SINGLE_DOT MIO_CANON_PATH_EMPTY_SINGLE_DOT
#define MIO_CANON_UCSTR_PATH_KEEP_DOUBLE_DOTS MIO_CANON_PATH_KEEP_DOUBLE_DOTS
#define MIO_CANON_UCSTR_PATH_DROP_TRAILING_SEP MIO_CANON_PATH_DROP_TRAILING_SEP
#define HIO_CANON_UCSTR_PATH_EMPTY_SINGLE_DOT HIO_CANON_PATH_EMPTY_SINGLE_DOT
#define HIO_CANON_UCSTR_PATH_KEEP_DOUBLE_DOTS HIO_CANON_PATH_KEEP_DOUBLE_DOTS
#define HIO_CANON_UCSTR_PATH_DROP_TRAILING_SEP HIO_CANON_PATH_DROP_TRAILING_SEP
#define MIO_CANON_BCSTR_PATH_EMPTY_SINGLE_DOT MIO_CANON_PATH_EMPTY_SINGLE_DOT
#define MIO_CANON_BCSTR_PATH_KEEP_DOUBLE_DOTS MIO_CANON_PATH_KEEP_DOUBLE_DOTS
#define MIO_CANON_BCSTR_PATH_DROP_TRAILING_SEP MIO_CANON_PATH_DROP_TRAILING_SEP
#define HIO_CANON_BCSTR_PATH_EMPTY_SINGLE_DOT HIO_CANON_PATH_EMPTY_SINGLE_DOT
#define HIO_CANON_BCSTR_PATH_KEEP_DOUBLE_DOTS HIO_CANON_PATH_KEEP_DOUBLE_DOTS
#define HIO_CANON_BCSTR_PATH_DROP_TRAILING_SEP HIO_CANON_PATH_DROP_TRAILING_SEP
#if defined(_WIN32) || defined(__OS2__) || defined(__DOS__)
# define MIO_IS_PATH_SEP(c) ((c) == '/' || (c) == '\\')
# define HIO_IS_PATH_SEP(c) ((c) == '/' || (c) == '\\')
#else
# define MIO_IS_PATH_SEP(c) ((c) == '/')
# define HIO_IS_PATH_SEP(c) ((c) == '/')
#endif
#define MIO_IS_PATH_DRIVE(s) \
#define HIO_IS_PATH_DRIVE(s) \
(((s[0] >= 'A' && s[0] <= 'Z') || \
(s[0] >= 'a' && s[0] <= 'z')) && \
s[1] == ':')
#define MIO_IS_PATH_SEP_OR_NIL(c) (MIO_IS_PATH_SEP(c) || (c) == '\0')
#define HIO_IS_PATH_SEP_OR_NIL(c) (HIO_IS_PATH_SEP(c) || (c) == '\0')
#if defined(__cplusplus)
extern "C" {
#endif
MIO_EXPORT mio_oow_t mio_canon_ucstr_path (
const mio_uch_t* path,
mio_uch_t* canon,
HIO_EXPORT hio_oow_t hio_canon_ucstr_path (
const hio_uch_t* path,
hio_uch_t* canon,
int flags
);
MIO_EXPORT mio_oow_t mio_canon_bcstr_path (
const mio_bch_t* path,
mio_bch_t* canon,
HIO_EXPORT hio_oow_t hio_canon_bcstr_path (
const hio_bch_t* path,
hio_bch_t* canon,
int flags
);

160
hio/lib/hio-pipe.h Normal file
View File

@ -0,0 +1,160 @@
/*
* $Id$
*
Copyright (c) 2016-2020 Chung, Hyung-Hwan. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted pipevided 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 repipeduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials pipevided with the distribution.
THIS SOFTWARE IS PIPEVIDED 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, PIPECUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PIPEFITS; 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 _HIO_PIPE_H_
#define _HIO_PIPE_H_
#include <hio.h>
enum hio_dev_pipe_sid_t
{
HIO_DEV_PIPE_MASTER = -1, /* no io occurs on this. used only in on_close() */
HIO_DEV_PIPE_IN = 0, /* input */
HIO_DEV_PIPE_OUT = 1 /* output */
};
typedef enum hio_dev_pipe_sid_t hio_dev_pipe_sid_t;
typedef struct hio_dev_pipe_t hio_dev_pipe_t;
typedef struct hio_dev_pipe_slave_t hio_dev_pipe_slave_t;
typedef int (*hio_dev_pipe_on_read_t) (
hio_dev_pipe_t* dev,
const void* data,
hio_iolen_t len
);
typedef int (*hio_dev_pipe_on_write_t) (
hio_dev_pipe_t* dev,
hio_iolen_t wrlen,
void* wrctx
);
typedef void (*hio_dev_pipe_on_close_t) (
hio_dev_pipe_t* dev,
hio_dev_pipe_sid_t sid
);
struct hio_dev_pipe_t
{
HIO_DEV_HEADER;
hio_dev_pipe_slave_t* slave[2];
int slave_count;
hio_dev_pipe_on_read_t on_read;
hio_dev_pipe_on_write_t on_write;
hio_dev_pipe_on_close_t on_close;
};
struct hio_dev_pipe_slave_t
{
HIO_DEV_HEADER;
hio_dev_pipe_sid_t id;
hio_syshnd_t pfd;
hio_dev_pipe_t* master; /* parent device */
};
typedef struct hio_dev_pipe_make_t hio_dev_pipe_make_t;
struct hio_dev_pipe_make_t
{
hio_dev_pipe_on_write_t on_write; /* mandatory */
hio_dev_pipe_on_read_t on_read; /* mandatory */
hio_dev_pipe_on_close_t on_close; /* optional */
};
enum hio_dev_pipe_ioctl_cmd_t
{
HIO_DEV_PIPE_CLOSE
};
typedef enum hio_dev_pipe_ioctl_cmd_t hio_dev_pipe_ioctl_cmd_t;
#ifdef __cplusplus
extern "C" {
#endif
HIO_EXPORT hio_dev_pipe_t* hio_dev_pipe_make (
hio_t* hio,
hio_oow_t xtnsize,
const hio_dev_pipe_make_t* data
);
#if defined(HIO_HAVE_INLINE)
static HIO_INLINE hio_t* hio_dev_pipe_gethio (hio_dev_pipe_t* pipe) { return hio_dev_gethio((hio_dev_t*)pipe); }
#else
# define hio_dev_pipe_gethio(pipe) hio_dev_gethio(pipe)
#endif
#if defined(HIO_HAVE_INLINE)
static HIO_INLINE void* hio_dev_pipe_getxtn (hio_dev_pipe_t* pipe) { return (void*)(pipe + 1); }
#else
# define hio_dev_pipe_getxtn(pipe) ((void*)(((hio_dev_pipe_t*)pipe) + 1))
#endif
HIO_EXPORT void hio_dev_pipe_kill (
hio_dev_pipe_t* pipe
);
HIO_EXPORT void hio_dev_pipe_halt (
hio_dev_pipe_t* pipe
);
HIO_EXPORT int hio_dev_pipe_read (
hio_dev_pipe_t* pipe,
int enabled
);
HIO_EXPORT int hio_dev_pipe_timedread (
hio_dev_pipe_t* pipe,
int enabled,
const hio_ntime_t* tmout
);
HIO_EXPORT int hio_dev_pipe_write (
hio_dev_pipe_t* pipe,
const void* data,
hio_iolen_t len,
void* wrctx
);
HIO_EXPORT int hio_dev_pipe_timedwrite (
hio_dev_pipe_t* pipe,
const void* data,
hio_iolen_t len,
const hio_ntime_t* tmout,
void* wrctx
);
HIO_EXPORT int hio_dev_pipe_close (
hio_dev_pipe_t* pipe,
hio_dev_pipe_sid_t sid
);
#ifdef __cplusplus
}
#endif
#endif

212
hio/lib/hio-pro.h Normal file
View File

@ -0,0 +1,212 @@
/*
* $Id$
*
Copyright (c) 2016-2020 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 _HIO_PRO_H_
#define _HIO_PRO_H_
#include <hio.h>
enum hio_dev_pro_sid_t
{
HIO_DEV_PRO_MASTER = -1, /* no io occurs on this. used only in on_close() */
HIO_DEV_PRO_IN = 0, /* input of the child process */
HIO_DEV_PRO_OUT = 1, /* output of the child process */
HIO_DEV_PRO_ERR = 2 /* error output of the child process */
};
typedef enum hio_dev_pro_sid_t hio_dev_pro_sid_t;
typedef struct hio_dev_pro_t hio_dev_pro_t;
typedef struct hio_dev_pro_slave_t hio_dev_pro_slave_t;
typedef int (*hio_dev_pro_on_read_t) (
hio_dev_pro_t* dev,
hio_dev_pro_sid_t sid,
const void* data,
hio_iolen_t len
);
typedef int (*hio_dev_pro_on_write_t) (
hio_dev_pro_t* dev,
hio_iolen_t wrlen,
void* wrctx
);
typedef void (*hio_dev_pro_on_close_t) (
hio_dev_pro_t* dev,
hio_dev_pro_sid_t sid
);
typedef int (*hio_dev_pro_on_fork_t) (
hio_dev_pro_t* dev,
void* fork_ctx
);
struct hio_dev_pro_t
{
HIO_DEV_HEADER;
int flags;
hio_intptr_t child_pid;
hio_dev_pro_slave_t* slave[3];
int slave_count;
hio_dev_pro_on_read_t on_read;
hio_dev_pro_on_write_t on_write;
hio_dev_pro_on_close_t on_close;
hio_bch_t* mcmd;
};
struct hio_dev_pro_slave_t
{
HIO_DEV_HEADER;
hio_dev_pro_sid_t id;
hio_syshnd_t pfd;
hio_dev_pro_t* master; /* parent device */
};
enum hio_dev_pro_make_flag_t
{
HIO_DEV_PRO_WRITEIN = (1 << 0),
HIO_DEV_PRO_READOUT = (1 << 1),
HIO_DEV_PRO_READERR = (1 << 2),
HIO_DEV_PRO_ERRTOOUT = (1 << 3),
HIO_DEV_PRO_OUTTOERR = (1 << 4),
HIO_DEV_PRO_INTONUL = (1 << 5),
HIO_DEV_PRO_OUTTONUL = (1 << 6),
HIO_DEV_PRO_ERRTONUL = (1 << 7),
HIO_DEV_PRO_DROPIN = (1 << 8),
HIO_DEV_PRO_DROPOUT = (1 << 9),
HIO_DEV_PRO_DROPERR = (1 << 10),
HIO_DEV_PRO_SHELL = (1 << 13),
/* perform no waitpid() on a child process upon device destruction.
* you should set this flag if your application has automatic child
* process reaping enabled. for instance, SIGCHLD is set to SIG_IGN
* on POSIX.1-2001 compliant systems */
HIO_DEV_PRO_FORGET_CHILD = (1 << 14),
HIO_DEV_PRO_FORGET_DIEHARD_CHILD = (1 << 15)
};
typedef enum hio_dev_pro_make_flag_t hio_dev_pro_make_flag_t;
typedef struct hio_dev_pro_make_t hio_dev_pro_make_t;
struct hio_dev_pro_make_t
{
int flags; /**< bitwise-ORed of hio_dev_pro_make_flag_t enumerators */
const void* cmd;
hio_dev_pro_on_write_t on_write; /* mandatory */
hio_dev_pro_on_read_t on_read; /* mandatory */
hio_dev_pro_on_close_t on_close; /* optional */
hio_dev_pro_on_fork_t on_fork; /* optional */
void* fork_ctx;
};
enum hio_dev_pro_ioctl_cmd_t
{
HIO_DEV_PRO_CLOSE,
HIO_DEV_PRO_KILL_CHILD
};
typedef enum hio_dev_pro_ioctl_cmd_t hio_dev_pro_ioctl_cmd_t;
#ifdef __cplusplus
extern "C" {
#endif
HIO_EXPORT hio_dev_pro_t* hio_dev_pro_make (
hio_t* hio,
hio_oow_t xtnsize,
const hio_dev_pro_make_t* data
);
#if defined(HIO_HAVE_INLINE)
static HIO_INLINE hio_t* hio_dev_pro_gethio (hio_dev_pro_t* pro) { return hio_dev_gethio((hio_dev_t*)pro); }
#else
# define hio_dev_pro_gethio(pro) hio_dev_gethio(pro)
#endif
#if defined(HIO_HAVE_INLINE)
static HIO_INLINE void* hio_dev_pro_getxtn (hio_dev_pro_t* pro) { return (void*)(pro + 1); }
#else
# define hio_dev_pro_getxtn(pro) ((void*)(((hio_dev_pro_t*)pro) + 1))
#endif
HIO_EXPORT void hio_dev_pro_kill (
hio_dev_pro_t* pro
);
HIO_EXPORT void hio_dev_pro_halt (
hio_dev_pro_t* pro
);
HIO_EXPORT int hio_dev_pro_read (
hio_dev_pro_t* pro,
hio_dev_pro_sid_t sid, /**< either #HIO_DEV_PRO_OUT or #HIO_DEV_PRO_ERR */
int enabled
);
HIO_EXPORT int hio_dev_pro_timedread (
hio_dev_pro_t* pro,
hio_dev_pro_sid_t sid, /**< either #HIO_DEV_PRO_OUT or #HIO_DEV_PRO_ERR */
int enabled,
const hio_ntime_t* tmout
);
HIO_EXPORT int hio_dev_pro_write (
hio_dev_pro_t* pro,
const void* data,
hio_iolen_t len,
void* wrctx
);
HIO_EXPORT int hio_dev_pro_timedwrite (
hio_dev_pro_t* pro,
const void* data,
hio_iolen_t len,
const hio_ntime_t* tmout,
void* wrctx
);
HIO_EXPORT int hio_dev_pro_close (
hio_dev_pro_t* pro,
hio_dev_pro_sid_t sid
);
HIO_EXPORT int hio_dev_pro_killchild (
hio_dev_pro_t* pro
);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -24,14 +24,14 @@
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _MIO_PRV_H_
#define _MIO_PRV_H_
#ifndef _HIO_PRV_H_
#define _HIO_PRV_H_
#include <mio.h>
#include <mio-utl.h>
#include <hio.h>
#include <hio-utl.h>
/* enable floating-point support in basic formatting functions */
#define MIO_ENABLE_FLTFMT
#define HIO_ENABLE_FLTFMT
#if defined(__has_builtin)
@ -40,24 +40,24 @@
# endif
# if __has_builtin(__builtin_memset)
# define MIO_MEMSET(dst,src,size) __builtin_memset(dst,src,size)
# define HIO_MEMSET(dst,src,size) __builtin_memset(dst,src,size)
# else
# define MIO_MEMSET(dst,src,size) memset(dst,src,size)
# define HIO_MEMSET(dst,src,size) memset(dst,src,size)
# endif
# if __has_builtin(__builtin_memcpy)
# define MIO_MEMCPY(dst,src,size) __builtin_memcpy(dst,src,size)
# define HIO_MEMCPY(dst,src,size) __builtin_memcpy(dst,src,size)
# else
# define MIO_MEMCPY(dst,src,size) memcpy(dst,src,size)
# define HIO_MEMCPY(dst,src,size) memcpy(dst,src,size)
# endif
# if __has_builtin(__builtin_memmove)
# define MIO_MEMMOVE(dst,src,size) __builtin_memmove(dst,src,size)
# define HIO_MEMMOVE(dst,src,size) __builtin_memmove(dst,src,size)
# else
# define MIO_MEMMOVE(dst,src,size) memmove(dst,src,size)
# define HIO_MEMMOVE(dst,src,size) memmove(dst,src,size)
# endif
# if __has_builtin(__builtin_memcmp)
# define MIO_MEMCMP(dst,src,size) __builtin_memcmp(dst,src,size)
# define HIO_MEMCMP(dst,src,size) __builtin_memcmp(dst,src,size)
# else
# define MIO_MEMCMP(dst,src,size) memcmp(dst,src,size)
# define HIO_MEMCMP(dst,src,size) memcmp(dst,src,size)
# endif
#else
@ -67,24 +67,24 @@
# endif
# if defined(HAVE___BUILTIN_MEMSET)
# define MIO_MEMSET(dst,src,size) __builtin_memset(dst,src,size)
# define HIO_MEMSET(dst,src,size) __builtin_memset(dst,src,size)
# else
# define MIO_MEMSET(dst,src,size) memset(dst,src,size)
# define HIO_MEMSET(dst,src,size) memset(dst,src,size)
# endif
# if defined(HAVE___BUILTIN_MEMCPY)
# define MIO_MEMCPY(dst,src,size) __builtin_memcpy(dst,src,size)
# define HIO_MEMCPY(dst,src,size) __builtin_memcpy(dst,src,size)
# else
# define MIO_MEMCPY(dst,src,size) memcpy(dst,src,size)
# define HIO_MEMCPY(dst,src,size) memcpy(dst,src,size)
# endif
# if defined(HAVE___BUILTIN_MEMMOVE)
# define MIO_MEMMOVE(dst,src,size) __builtin_memmove(dst,src,size)
# define HIO_MEMMOVE(dst,src,size) __builtin_memmove(dst,src,size)
# else
# define MIO_MEMMOVE(dst,src,size) memmove(dst,src,size)
# define HIO_MEMMOVE(dst,src,size) memmove(dst,src,size)
# endif
# if defined(HAVE___BUILTIN_MEMCMP)
# define MIO_MEMCMP(dst,src,size) __builtin_memcmp(dst,src,size)
# define HIO_MEMCMP(dst,src,size) __builtin_memcmp(dst,src,size)
# else
# define MIO_MEMCMP(dst,src,size) memcmp(dst,src,size)
# define HIO_MEMCMP(dst,src,size) memcmp(dst,src,size)
# endif
#endif
@ -92,130 +92,130 @@
/* =========================================================================
* MIO ASSERTION
* ========================================================================= */
#if defined(MIO_BUILD_RELEASE)
# define MIO_ASSERT(mio,expr) ((void)0)
#if defined(HIO_BUILD_RELEASE)
# define HIO_ASSERT(hio,expr) ((void)0)
#else
# define MIO_ASSERT(mio,expr) ((void)((expr) || (mio_sys_assertfail(mio, #expr, __FILE__, __LINE__), 0)))
# define HIO_ASSERT(hio,expr) ((void)((expr) || (hio_sys_assertfail(hio, #expr, __FILE__, __LINE__), 0)))
#endif
/* i don't want an error raised inside the callback to override
* the existing error number and message. */
#define MIO_SYS_WRITE_LOG(mio,mask,ptr,len) do { \
int __shuterr = (mio)->_shuterr; \
(mio)->_shuterr = 1; \
mio_sys_writelog (mio, mask, ptr, len); \
(mio)->_shuterr = __shuterr; \
#define HIO_SYS_WRITE_LOG(hio,mask,ptr,len) do { \
int __shuterr = (hio)->_shuterr; \
(hio)->_shuterr = 1; \
hio_sys_writelog (hio, mask, ptr, len); \
(hio)->_shuterr = __shuterr; \
} while(0)
#ifdef __cplusplus
extern "C" {
#endif
int mio_makesyshndasync (
mio_t* mio,
mio_syshnd_t hnd
int hio_makesyshndasync (
hio_t* hio,
hio_syshnd_t hnd
);
int mio_makesyshndcloexec (
mio_t* mio,
mio_syshnd_t hnd
int hio_makesyshndcloexec (
hio_t* hio,
hio_syshnd_t hnd
);
void mio_cleartmrjobs (
mio_t* mio
void hio_cleartmrjobs (
hio_t* hio
);
void mio_firetmrjobs (
mio_t* mio,
const mio_ntime_t* tmbase,
mio_oow_t* firecnt
void hio_firetmrjobs (
hio_t* hio,
const hio_ntime_t* tmbase,
hio_oow_t* firecnt
);
/**
* The mio_gettmrtmout() function gets the remaining time until the first
* The hio_gettmrtmout() function gets the remaining time until the first
* scheduled job is to be triggered. It stores in \a tmout the difference between
* the given time \a tm and the scheduled time and returns 1. If there is no
* job scheduled, it returns 0.
*/
int mio_gettmrtmout (
mio_t* mio,
const mio_ntime_t* tm,
mio_ntime_t* tmout
int hio_gettmrtmout (
hio_t* hio,
const hio_ntime_t* tm,
hio_ntime_t* tmout
);
/* ========================================================================== */
/* system intefaces */
/* ========================================================================== */
int mio_sys_init (
mio_t* mio
int hio_sys_init (
hio_t* hio
);
void mio_sys_fini (
mio_t* mio
void hio_sys_fini (
hio_t* hio
);
void mio_sys_assertfail (
mio_t* mio,
const mio_bch_t* expr,
const mio_bch_t* file,
mio_oow_t line
void hio_sys_assertfail (
hio_t* hio,
const hio_bch_t* expr,
const hio_bch_t* file,
hio_oow_t line
);
mio_errnum_t mio_sys_syserrstrb (
mio_t* mio,
hio_errnum_t hio_sys_syserrstrb (
hio_t* hio,
int syserr_type,
int syserr_code,
mio_bch_t* buf,
mio_oow_t len
hio_bch_t* buf,
hio_oow_t len
);
void mio_sys_resetlog (
mio_t* mio
void hio_sys_resetlog (
hio_t* hio
);
void mio_sys_locklog (
mio_t* mio
void hio_sys_locklog (
hio_t* hio
);
void mio_sys_unlocklog (
mio_t* mio
void hio_sys_unlocklog (
hio_t* hio
);
void mio_sys_writelog (
mio_t* mio,
mio_bitmask_t mask,
const mio_ooch_t* msg,
mio_oow_t len
void hio_sys_writelog (
hio_t* hio,
hio_bitmask_t mask,
const hio_ooch_t* msg,
hio_oow_t len
);
void mio_sys_intrmux (
mio_t* mio
void hio_sys_intrmux (
hio_t* hio
);
int mio_sys_ctrlmux (
mio_t* mio,
mio_sys_mux_cmd_t cmd,
mio_dev_t* dev,
int hio_sys_ctrlmux (
hio_t* hio,
hio_sys_mux_cmd_t cmd,
hio_dev_t* dev,
int dev_cap
);
int mio_sys_waitmux (
mio_t* mio,
const mio_ntime_t* tmout,
mio_sys_mux_evtcb_t event_handler
int hio_sys_waitmux (
hio_t* hio,
const hio_ntime_t* tmout,
hio_sys_mux_evtcb_t event_handler
);
void mio_sys_gettime (
mio_t* mio,
mio_ntime_t* now
void hio_sys_gettime (
hio_t* hio,
hio_ntime_t* now
);
void mio_sys_getrealtime (
mio_t* mio,
mio_ntime_t* now
void hio_sys_getrealtime (
hio_t* hio,
hio_ntime_t* now
);
#ifdef __cplusplus

618
hio/lib/hio-sck.h Normal file
View File

@ -0,0 +1,618 @@
/*
* $Id$
*
Copyright (c) 2016-2020 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 _HIO_SCK_H_
#define _HIO_SCK_H_
#include <hio.h>
#include <hio-skad.h>
/* ========================================================================= */
/* TOOD: move these to a separate file */
#define HIO_ETHHDR_PROTO_IP4 0x0800
#define HIO_ETHHDR_PROTO_ARP 0x0806
#define HIO_ETHHDR_PROTO_8021Q 0x8100 /* 802.1Q VLAN */
#define HIO_ETHHDR_PROTO_IP6 0x86DD
#define HIO_ARPHDR_OPCODE_REQUEST 1
#define HIO_ARPHDR_OPCODE_REPLY 2
#define HIO_ARPHDR_HTYPE_ETH 0x0001
#define HIO_ARPHDR_PTYPE_IP4 0x0800
#include <hio-pac1.h>
struct HIO_PACKED hio_ethhdr_t
{
hio_uint8_t dest[HIO_ETHAD_LEN];
hio_uint8_t source[HIO_ETHAD_LEN];
hio_uint16_t proto;
};
typedef struct hio_ethhdr_t hio_ethhdr_t;
struct HIO_PACKED hio_arphdr_t
{
hio_uint16_t htype; /* hardware type (ethernet: 0x0001) */
hio_uint16_t ptype; /* protocol type (ipv4: 0x0800) */
hio_uint8_t hlen; /* hardware address length (ethernet: 6) */
hio_uint8_t plen; /* protocol address length (ipv4 :4) */
hio_uint16_t opcode; /* operation code */
};
typedef struct hio_arphdr_t hio_arphdr_t;
/* arp payload for ipv4 over ethernet */
struct HIO_PACKED hio_etharp_t
{
hio_uint8_t sha[HIO_ETHAD_LEN]; /* source hardware address */
hio_uint8_t spa[HIO_IP4AD_LEN]; /* source protocol address */
hio_uint8_t tha[HIO_ETHAD_LEN]; /* target hardware address */
hio_uint8_t tpa[HIO_IP4AD_LEN]; /* target protocol address */
};
typedef struct hio_etharp_t hio_etharp_t;
struct HIO_PACKED hio_etharp_pkt_t
{
hio_ethhdr_t ethhdr;
hio_arphdr_t arphdr;
hio_etharp_t arppld;
};
typedef struct hio_etharp_pkt_t hio_etharp_pkt_t;
struct hio_iphdr_t
{
#if defined(HIO_ENDIAN_LITTLE)
hio_uint8_t ihl:4;
hio_uint8_t version:4;
#elif defined(HIO_ENDIAN_BIG)
hio_uint8_t version:4;
hio_uint8_t ihl:4;
#else
# UNSUPPORTED ENDIAN
#endif
hio_int8_t tos;
hio_int16_t tot_len;
hio_int16_t id;
hio_int16_t frag_off;
hio_int8_t ttl;
hio_int8_t protocol;
hio_int16_t check;
hio_int32_t saddr;
hio_int32_t daddr;
/*The options start here. */
};
typedef struct hio_iphdr_t hio_iphdr_t;
struct HIO_PACKED hio_icmphdr_t
{
hio_uint8_t type; /* message type */
hio_uint8_t code; /* subcode */
hio_uint16_t checksum;
union
{
struct
{
hio_uint16_t id;
hio_uint16_t seq;
} echo;
hio_uint32_t gateway;
struct
{
hio_uint16_t frag_unused;
hio_uint16_t mtu;
} frag; /* path mut discovery */
} u;
};
typedef struct hio_icmphdr_t hio_icmphdr_t;
#include <hio-upac.h>
/* ICMP types */
#define HIO_ICMP_ECHO_REPLY 0
#define HIO_ICMP_UNREACH 3 /* destination unreachable */
#define HIO_ICMP_SOURCE_QUENCE 4
#define HIO_ICMP_REDIRECT 5
#define HIO_ICMP_ECHO_REQUEST 8
#define HIO_ICMP_TIME_EXCEEDED 11
#define HIO_ICMP_PARAM_PROBLEM 12
#define HIO_ICMP_TIMESTAMP_REQUEST 13
#define HIO_ICMP_TIMESTAMP_REPLY 14
#define HIO_ICMP_INFO_REQUEST 15
#define HIO_ICMP_INFO_REPLY 16
#define HIO_ICMP_ADDR_MASK_REQUEST 17
#define HIO_ICMP_ADDR_MASK_REPLY 18
/* Subcode for HIO_ICMP_UNREACH */
#define HIO_ICMP_UNREACH_NET 0
#define HIO_ICMP_UNREACH_HOST 1
#define HIO_ICMP_UNREACH_PROTOCOL 2
#define HIO_ICMP_UNREACH_PORT 3
#define HIO_ICMP_UNREACH_FRAG_NEEDED 4
/* Subcode for HIO_ICMP_REDIRECT */
#define HIO_ICMP_REDIRECT_NET 0
#define HIO_ICMP_REDIRECT_HOST 1
#define HIO_ICMP_REDIRECT_NETTOS 2
#define HIO_ICMP_REDIRECT_HOSTTOS 3
/* Subcode for HIO_ICMP_TIME_EXCEEDED */
#define HIO_ICMP_TIME_EXCEEDED_TTL 0
#define HIO_ICMP_TIME_EXCEEDED_FRAGTIME 1
/* ========================================================================= */
#if (HIO_SIZEOF_SOCKLEN_T == HIO_SIZEOF_INT)
#if defined(HIO_SOCKLEN_T_IS_SIGNED)
typedef int hio_scklen_t;
#else
typedef unsigned int hio_scklen_t;
#endif
#elif (HIO_SIZEOF_SOCKLEN_T == HIO_SIZEOF_LONG)
#if defined(HIO_SOCKLEN_T_IS_SIGNED)
typedef long hio_scklen_t;
#else
typedef unsigned long hio_scklen_t;
#endif
#else
typedef int hio_scklen_t;
#endif
/* ========================================================================= */
enum hio_dev_sck_ioctl_cmd_t
{
HIO_DEV_SCK_BIND,
HIO_DEV_SCK_CONNECT,
HIO_DEV_SCK_LISTEN
};
typedef enum hio_dev_sck_ioctl_cmd_t hio_dev_sck_ioctl_cmd_t;
#define HIO_DEV_SCK_SET_PROGRESS(dev,bit) do { \
(dev)->state &= ~HIO_DEV_SCK_ALL_PROGRESS_BITS; \
(dev)->state |= (bit); \
} while(0)
#define HIO_DEV_SCK_GET_PROGRESS(dev) ((dev)->state & HIO_DEV_SCK_ALL_PROGRESS_BITS)
enum hio_dev_sck_state_t
{
/* the following items(progress bits) are mutually exclusive */
HIO_DEV_SCK_CONNECTING = (1 << 0),
HIO_DEV_SCK_CONNECTING_SSL = (1 << 1),
HIO_DEV_SCK_CONNECTED = (1 << 2),
HIO_DEV_SCK_LISTENING = (1 << 3),
HIO_DEV_SCK_ACCEPTING_SSL = (1 << 4),
HIO_DEV_SCK_ACCEPTED = (1 << 5),
/* the following items can be bitwise-ORed with an exclusive item above */
HIO_DEV_SCK_LENIENT = (1 << 14),
HIO_DEV_SCK_INTERCEPTED = (1 << 15),
/* convenience bit masks */
HIO_DEV_SCK_ALL_PROGRESS_BITS = (HIO_DEV_SCK_CONNECTING |
HIO_DEV_SCK_CONNECTING_SSL |
HIO_DEV_SCK_CONNECTED |
HIO_DEV_SCK_LISTENING |
HIO_DEV_SCK_ACCEPTING_SSL |
HIO_DEV_SCK_ACCEPTED)
};
typedef enum hio_dev_sck_state_t hio_dev_sck_state_t;
typedef struct hio_dev_sck_t hio_dev_sck_t;
typedef int (*hio_dev_sck_on_read_t) (
hio_dev_sck_t* dev,
const void* data,
hio_iolen_t dlen,
const hio_skad_t* srcaddr
);
typedef int (*hio_dev_sck_on_write_t) (
hio_dev_sck_t* dev,
hio_iolen_t wrlen,
void* wrctx,
const hio_skad_t* dstaddr
);
typedef void (*hio_dev_sck_on_disconnect_t) (
hio_dev_sck_t* dev
);
typedef void (*hio_dev_sck_on_connect_t) (
hio_dev_sck_t* dev
);
typedef void (*hio_dev_sck_on_raw_accept_t) (
hio_dev_sck_t* dev,
hio_syshnd_t syshnd,
hio_skad_t* peeradr
);
enum hio_dev_sck_type_t
{
HIO_DEV_SCK_QX,
HIO_DEV_SCK_TCP4,
HIO_DEV_SCK_TCP6,
HIO_DEV_SCK_UDP4,
HIO_DEV_SCK_UDP6,
/* ICMP at the IPv4 layer */
HIO_DEV_SCK_ICMP4,
/* ICMP at the IPv6 layer */
HIO_DEV_SCK_ICMP6,
/* ARP at the ethernet layer */
HIO_DEV_SCK_ARP,
HIO_DEV_SCK_ARP_DGRAM,
/* raw L2-level packet */
HIO_DEV_SCK_PACKET,
/* bpf socket */
HIO_DEV_SCK_BPF
};
typedef enum hio_dev_sck_type_t hio_dev_sck_type_t;
enum hio_dev_sck_make_option_t
{
/* for now, accept failure doesn't affect the listing socket if this is set */
HIO_DEV_SCK_MAKE_LENIENT = (1 << 0)
};
typedef enum hio_dev_sck_make_option_t hio_dev_sck_make_option_t;
typedef struct hio_dev_sck_make_t hio_dev_sck_make_t;
struct hio_dev_sck_make_t
{
hio_dev_sck_type_t type;
int options;
hio_syshnd_t syshnd;
hio_dev_sck_on_write_t on_write;
hio_dev_sck_on_read_t on_read;
hio_dev_sck_on_connect_t on_connect;
hio_dev_sck_on_disconnect_t on_disconnect;
hio_dev_sck_on_raw_accept_t on_raw_accept; /* optional */
};
enum hio_dev_sck_bind_option_t
{
HIO_DEV_SCK_BIND_BROADCAST = (1 << 0),
HIO_DEV_SCK_BIND_REUSEADDR = (1 << 1),
HIO_DEV_SCK_BIND_REUSEPORT = (1 << 2),
HIO_DEV_SCK_BIND_TRANSPARENT = (1 << 3),
/* TODO: more options --- SO_RCVBUF, SO_SNDBUF, SO_RCVTIMEO, SO_SNDTIMEO, SO_KEEPALIVE */
/* BINDTODEVICE??? */
HIO_DEV_SCK_BIND_IGNERR = (1 << 14), /* ignore non-critical error in binding */
HIO_DEV_SCK_BIND_SSL = (1 << 15)
};
typedef enum hio_dev_sck_bind_option_t hio_dev_sck_bind_option_t;
typedef struct hio_dev_sck_bind_t hio_dev_sck_bind_t;
struct hio_dev_sck_bind_t
{
int options; /** 0 or bitwise-OR'ed of hio_dev_sck_bind_option_t enumerators */
hio_skad_t localaddr;
/* TODO: add device name for BIND_TO_DEVICE */
const hio_bch_t* ssl_certfile;
const hio_bch_t* ssl_keyfile;
};
enum hio_dev_sck_connect_option_t
{
HIO_DEV_SCK_CONNECT_SSL = (1 << 15)
};
typedef enum hio_dev_sck_connect_option_t hio_dev_sck_connect_option_t;
typedef struct hio_dev_sck_connect_t hio_dev_sck_connect_t;
struct hio_dev_sck_connect_t
{
int options;
hio_skad_t remoteaddr;
hio_ntime_t connect_tmout;
};
#if 0
enum hio_dev_sck_listen_option_t
{
};
typedef enum hio_dev_sck_listen_option_t hio_dev_sck_listen_option_t;
#endif
typedef struct hio_dev_sck_listen_t hio_dev_sck_listen_t;
struct hio_dev_sck_listen_t
{
int options; /* no options as of now. set it to 0 */
int backlogs;
hio_ntime_t accept_tmout;
};
struct hio_dev_sck_t
{
HIO_DEV_HEADER;
hio_dev_sck_type_t type;
hio_syshnd_t hnd;
int state;
/* remote peer address for a stateful stream socket. valid if one of the
* followings is set in state:
* HIO_DEV_TCP_ACCEPTING_SSL
* HIO_DEV_TCP_ACCEPTED
* HIO_DEV_TCP_CONNECTED
* HIO_DEV_TCP_CONNECTING
* HIO_DEV_TCP_CONNECTING_SSL
*
* also used as a placeholder to store source address for
* a stateless socket */
hio_skad_t remoteaddr;
/* local socket address */
hio_skad_t localaddr;
/* original destination address */
hio_skad_t orgdstaddr;
hio_dev_sck_on_write_t on_write;
hio_dev_sck_on_read_t on_read;
/* called on a new tcp device for an accepted client or
* on a tcp device conntected to a remote server */
hio_dev_sck_on_connect_t on_connect;
hio_dev_sck_on_disconnect_t on_disconnect;
hio_dev_sck_on_raw_accept_t on_raw_accept;
/* timer job index for handling
* - connect() timeout for a connecting socket.
* - SSL_accept() timeout for a socket accepting SSL */
hio_tmridx_t tmrjob_index;
/* connect timeout, ssl-connect timeout, ssl-accept timeout.
* it denotes timeout duration under some circumstances
* or an absolute expiry time under some other circumstances. */
hio_ntime_t tmout;
void* ssl_ctx;
void* ssl;
hio_syshnd_t side_chan; /* side-channel for HIO_DEV_SCK_QX */
};
enum hio_dev_sck_shutdown_how_t
{
HIO_DEV_SCK_SHUTDOWN_READ = (1 << 0),
HIO_DEV_SCK_SHUTDOWN_WRITE = (1 << 1)
};
typedef enum hio_dev_sck_shutdown_how_t hio_dev_sck_shutdown_how_t;
enum hio_dev_sck_qxmsg_cmd_t
{
HIO_DEV_SCK_QXMSG_NEWCONN = 0
};
typedef enum hio_dev_sck_qxmsg_cmd_t hio_dev_sck_qxmsg_cmd_t;
struct hio_dev_sck_qxmsg_t
{
hio_dev_sck_qxmsg_cmd_t cmd;
hio_dev_sck_type_t scktype;
hio_syshnd_t syshnd;
hio_skad_t remoteaddr;
};
typedef struct hio_dev_sck_qxmsg_t hio_dev_sck_qxmsg_t;
#ifdef __cplusplus
extern "C" {
#endif
/* ========================================================================= */
HIO_EXPORT hio_dev_sck_t* hio_dev_sck_make (
hio_t* hio,
hio_oow_t xtnsize,
const hio_dev_sck_make_t* info
);
#if defined(HIO_HAVE_INLINE)
static HIO_INLINE hio_t* hio_dev_sck_gethio (hio_dev_sck_t* sck) { return hio_dev_gethio((hio_dev_t*)sck); }
static HIO_INLINE void* hio_dev_sck_getxtn (hio_dev_sck_t* sck) { return (void*)(sck + 1); }
static HIO_INLINE hio_dev_sck_type_t hio_dev_sck_gettype (hio_dev_sck_t* sck) { return sck->type; }
static HIO_INLINE hio_syshnd_t hio_dev_sck_getsyshnd (hio_dev_sck_t* sck) { return sck->hnd; }
#else
# define hio_dev_sck_gethio(sck) hio_dev_gethio(sck)
# define hio_dev_sck_getxtn(sck) ((void*)(((hio_dev_sck_t*)sck) + 1))
# define hio_dev_sck_gettype(sck) (((hio_dev_sck_t*)sck)->type)
# define hio_dev_sck_getsyshnd(sck) (((hio_dev_sck_t*)sck)->hnd)
#endif
HIO_EXPORT int hio_dev_sck_bind (
hio_dev_sck_t* dev,
hio_dev_sck_bind_t* info
);
HIO_EXPORT int hio_dev_sck_connect (
hio_dev_sck_t* dev,
hio_dev_sck_connect_t* info
);
HIO_EXPORT int hio_dev_sck_listen (
hio_dev_sck_t* dev,
hio_dev_sck_listen_t* info
);
HIO_EXPORT int hio_dev_sck_write (
hio_dev_sck_t* dev,
const void* data,
hio_iolen_t len,
void* wrctx,
const hio_skad_t* dstaddr
);
HIO_EXPORT int hio_dev_sck_writev (
hio_dev_sck_t* dev,
hio_iovec_t* iov,
hio_iolen_t iovcnt,
void* wrctx,
const hio_skad_t* dstaddr
);
HIO_EXPORT int hio_dev_sck_timedwrite (
hio_dev_sck_t* dev,
const void* data,
hio_iolen_t len,
const hio_ntime_t* tmout,
void* wrctx,
const hio_skad_t* dstaddr
);
HIO_EXPORT int hio_dev_sck_timedwritev (
hio_dev_sck_t* dev,
hio_iovec_t* iov,
hio_iolen_t iovcnt,
const hio_ntime_t* tmout,
void* wrctx,
const hio_skad_t* dstaddr
);
#if defined(HIO_HAVE_INLINE)
static HIO_INLINE void hio_dev_sck_kill (hio_dev_sck_t* sck)
{
hio_dev_kill ((hio_dev_t*)sck);
}
static HIO_INLINE void hio_dev_sck_halt (hio_dev_sck_t* sck)
{
hio_dev_halt ((hio_dev_t*)sck);
}
static HIO_INLINE int hio_dev_sck_read (hio_dev_sck_t* sck, int enabled)
{
return hio_dev_read((hio_dev_t*)sck, enabled);
}
static HIO_INLINE int hio_dev_sck_timedread (hio_dev_sck_t* sck, int enabled, hio_ntime_t* tmout)
{
return hio_dev_timedread((hio_dev_t*)sck, enabled, tmout);
}
static HIO_INLINE int hio_dev_sck_sendfile (hio_dev_sck_t* sck, hio_syshnd_t in_fd, hio_foff_t foff, hio_iolen_t len, void* wrctx)
{
return hio_dev_sendfile((hio_dev_t*)sck, in_fd, foff, len, wrctx);
}
static HIO_INLINE int hio_dev_sck_timedsendfile (hio_dev_sck_t* sck, hio_syshnd_t in_fd, hio_foff_t foff, hio_iolen_t len, hio_ntime_t* tmout, void* wrctx)
{
return hio_dev_timedsendfile((hio_dev_t*)sck, in_fd, foff, len, tmout, wrctx);
}
#else
#define hio_dev_sck_kill(sck) hio_dev_kill((hio_dev_t*)sck)
#define hio_dev_sck_halt(sck) hio_dev_halt((hio_dev_t*)sck)
#define hio_dev_sck_read(sck,enabled) hio_dev_read((hio_dev_t*)sck, enabled)
#define hio_dev_sck_timedread(sck,enabled,tmout) hio_dev_timedread((hio_dev_t*)sck, enabled, tmout)
#define hio_dev_sck_sendfile(sck,in_fd,foff,len,wrctx) hio_dev_sendfile((hio_dev_t*)sck, in_fd, foff, len, wrctx)
#define hio_dev_sck_timedsendfile(sck,in_fd,foff,len,tmout,wrctx) hio_dev_timedsendfile((hio_dev_t*)sck, in_fd, foff, len, tmout, wrctx)
#endif
HIO_EXPORT int hio_dev_sck_setsockopt (
hio_dev_sck_t* dev,
int level,
int optname,
void* optval,
hio_scklen_t optlen
);
HIO_EXPORT int hio_dev_sck_getsockopt (
hio_dev_sck_t* dev,
int level,
int optname,
void* optval,
hio_scklen_t* optlen
);
HIO_EXPORT int hio_dev_sck_getsockaddr (
hio_dev_sck_t* dev,
hio_skad_t* skad
);
HIO_EXPORT int hio_dev_sck_getpeeraddr (
hio_dev_sck_t* dev,
hio_skad_t* skad
);
HIO_EXPORT int hio_dev_sck_shutdown (
hio_dev_sck_t* dev,
int how /* bitwise-ORed of hio_dev_sck_shutdown_how_t enumerators */
);
HIO_EXPORT int hio_dev_sck_sendfileok (
hio_dev_sck_t* dev
);
HIO_EXPORT int hio_dev_sck_writetosidechan (
hio_dev_sck_t* htts,
const void* dptr,
hio_oow_t dlen
);
HIO_EXPORT hio_uint16_t hio_checksum_ip (
const void* hdr,
hio_oow_t len
);
#ifdef __cplusplus
}
#endif
#endif

236
hio/lib/hio-skad.h Normal file
View File

@ -0,0 +1,236 @@
/*
* $Id$
*
Copyright (c) 2016-2020 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 WARRANTIES
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 _HIO_SKAD_H_
#define _HIO_SKAD_H_
#include <hio.h>
#include <hio-utl.h>
#define HIO_SIZEOF_SKAD_T 1
#if (HIO_SIZEOF_STRUCT_SOCKADDR_IN > HIO_SIZEOF_SKAD_T)
# undef HIO_SIZEOF_SKAD_T
# define HIO_SIZEOF_SKAD_T HIO_SIZEOF_STRUCT_SOCKADDR_IN
#endif
#if (HIO_SIZEOF_STRUCT_SOCKADDR_IN6 > HIO_SIZEOF_SKAD_T)
# undef HIO_SIZEOF_SKAD_T
# define HIO_SIZEOF_SKAD_T HIO_SIZEOF_STRUCT_SOCKADDR_IN6
#endif
#if (HIO_SIZEOF_STRUCT_SOCKADDR_LL > HIO_SIZEOF_SKAD_T)
# undef HIO_SIZEOF_SKAD_T
# define HIO_SIZEOF_SKAD_T HIO_SIZEOF_STRUCT_SOCKADDR_LL
#endif
#if (HIO_SIZEOF_STRUCT_SOCKADDR_DL > HIO_SIZEOF_SKAD_T)
# undef HIO_SIZEOF_SKAD_T
# define HIO_SIZEOF_SKAD_T HIO_SIZEOF_STRUCT_SOCKADDR_DL
#endif
#if (HIO_SIZEOF_STRUCT_SOCKADDR_UN > HIO_SIZEOF_SKAD_T)
# undef HIO_SIZEOF_SKAD_T
# define HIO_SIZEOF_SKAD_T HIO_SIZEOF_STRUCT_SOCKADDR_UN
#endif
struct hio_skad_t
{
hio_uint8_t data[HIO_SIZEOF_SKAD_T];
};
typedef struct hio_skad_t hio_skad_t;
#define HIO_SKAD_TO_OOCSTR_ADDR (1 << 0)
#define HIO_SKAD_TO_OOCSTR_PORT (1 << 1)
#define HIO_SKAD_TO_UCSTR_ADDR HIO_SKAD_TO_OOCSTR_ADDR
#define HIO_SKAD_TO_UCSTR_PORT HIO_SKAD_TO_OOCSTR_PORT
#define HIO_SKAD_TO_BCSTR_ADDR HIO_SKAD_TO_OOCSTR_ADDR
#define HIO_SKAD_TO_BCSTR_PORT HIO_SKAD_TO_OOCSTR_PORT
#define HIO_IP4AD_STRLEN (15) /* not including the terminating '\0' */
#define HIO_IP6AD_STRLEN (45) /* not including the terminating '\0'. pure IPv6 address, not including the scope(e.g. %10, %eth0) */
/* size large enough to hold the ip address plus port number.
* [IPV6ADDR%SCOPE]:PORT -> 9 for [] % : and PORT
* Let's reserve 16 for SCOPE and not include the terminting '\0'
*/
#define HIO_SKAD_IP_STRLEN (HIO_IP6AD_STRLEN + 25)
/* -------------------------------------------------------------------- */
#define HIO_ETHAD_LEN (6)
#define HIO_IP4AD_LEN (4)
#define HIO_IP6AD_LEN (16)
#include <hio-pac1.h>
struct HIO_PACKED hio_ethad_t
{
hio_uint8_t v[HIO_ETHAD_LEN];
};
typedef struct hio_ethad_t hio_ethad_t;
struct HIO_PACKED hio_ip4ad_t
{
hio_uint8_t v[HIO_IP4AD_LEN];
};
typedef struct hio_ip4ad_t hio_ip4ad_t;
struct HIO_PACKED hio_ip6ad_t
{
hio_uint8_t v[HIO_IP6AD_LEN];
};
typedef struct hio_ip6ad_t hio_ip6ad_t;
#include <hio-upac.h>
#if defined(__cplusplus)
extern "C" {
#endif
HIO_EXPORT int hio_ucharstoskad (
hio_t* hio,
const hio_uch_t* str,
hio_oow_t len,
hio_skad_t* skad
);
HIO_EXPORT int hio_bcharstoskad (
hio_t* hio,
const hio_bch_t* str,
hio_oow_t len,
hio_skad_t* skad
);
#define hio_bcstrtoskad(hio,str,skad) hio_bcharstoskad(hio, str, hio_count_bcstr(str), skad)
#define hio_ucstrtoskad(hio,str,skad) hio_ucharstoskad(hio, str, hio_count_ucstr(str), skad)
HIO_EXPORT hio_oow_t hio_skadtoucstr (
hio_t* hio,
const hio_skad_t* skad,
hio_uch_t* buf,
hio_oow_t len,
int flags
);
HIO_EXPORT hio_oow_t hio_skadtobcstr (
hio_t* hio,
const hio_skad_t* skad,
hio_bch_t* buf,
hio_oow_t len,
int flags
);
#if defined(HIO_OOCH_IS_UCH)
# define hio_oocharstoskad hio_ucharstoskad
# define hio_skadtooocstr hio_skadtoucstr
#else
# define hio_oocharstoskad hio_bcharstoskad
# define hio_skadtooocstr hio_skadtobcstr
#endif
HIO_EXPORT void hio_skad_init_for_ip4 (
hio_skad_t* skad,
hio_uint16_t port,
hio_ip4ad_t* ip4ad
);
HIO_EXPORT void hio_skad_init_for_ip6 (
hio_skad_t* skad,
hio_uint16_t port,
hio_ip6ad_t* ip6ad,
int scope_id
);
HIO_EXPORT void hio_skad_init_for_ip_with_bytes (
hio_skad_t* skad,
hio_uint16_t port,
const hio_uint8_t* bytes,
hio_oow_t len
);
HIO_EXPORT void hio_skad_init_for_eth (
hio_skad_t* skad,
int ifindex,
hio_ethad_t* ethad
);
HIO_EXPORT int hio_skad_family (
const hio_skad_t* skad
);
HIO_EXPORT int hio_skad_size (
const hio_skad_t* skad
);
HIO_EXPORT int hio_skad_port (
const hio_skad_t* skad
);
HIO_EXPORT int hio_skad_ifindex (
const hio_skad_t* skad
);
HIO_EXPORT void hio_clear_skad (
hio_skad_t* skad
);
HIO_EXPORT int hio_equal_skads (
const hio_skad_t* addr1,
const hio_skad_t* addr2,
int strict
);
HIO_EXPORT hio_oow_t hio_ipad_bytes_to_ucstr (
const hio_uint8_t* iptr,
hio_oow_t ilen,
hio_uch_t* buf,
hio_oow_t blen
);
HIO_EXPORT hio_oow_t hio_ipad_bytes_to_bcstr (
const hio_uint8_t* iptr,
hio_oow_t ilen,
hio_bch_t* buf,
hio_oow_t blen
);
HIO_EXPORT int hio_uchars_to_ipad_bytes (
const hio_uch_t* str,
hio_oow_t slen,
hio_uint8_t* buf,
hio_oow_t blen
);
HIO_EXPORT int hio_bchars_to_ipad_bytes (
const hio_bch_t* str,
hio_oow_t slen,
hio_uint8_t* buf,
hio_oow_t blen
);
#if defined(__cplusplus)
}
#endif
#endif

184
hio/lib/hio-thr.h Normal file
View File

@ -0,0 +1,184 @@
/*
* $Id$
*
Copyright (c) 2016-2020 Chung, Hyung-Hwan. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted thrvided 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 rethrduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials thrvided 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 _HIO_THR_H_
#define _HIO_THR_H_
#include <hio.h>
enum hio_dev_thr_sid_t
{
HIO_DEV_THR_MASTER = -1, /* no io occurs on this. used only in on_close() */
HIO_DEV_THR_IN = 0, /* input to the thread */
HIO_DEV_THR_OUT = 1, /* output from the thread */
};
typedef enum hio_dev_thr_sid_t hio_dev_thr_sid_t;
typedef struct hio_dev_thr_t hio_dev_thr_t;
typedef struct hio_dev_thr_slave_t hio_dev_thr_slave_t;
typedef int (*hio_dev_thr_on_read_t) (
hio_dev_thr_t* dev,
const void* data,
hio_iolen_t len
);
typedef int (*hio_dev_thr_on_write_t) (
hio_dev_thr_t* dev,
hio_iolen_t wrlen,
void* wrctx
);
typedef void (*hio_dev_thr_on_close_t) (
hio_dev_thr_t* dev,
hio_dev_thr_sid_t sid
);
struct hio_dev_thr_iopair_t
{
hio_syshnd_t rfd;
hio_syshnd_t wfd;
};
typedef struct hio_dev_thr_iopair_t hio_dev_thr_iopair_t;
typedef void (*hio_dev_thr_func_t) (
hio_t* hio,
hio_dev_thr_iopair_t* iop,
void* ctx
);
typedef struct hio_dev_thr_info_t hio_dev_thr_info_t;
struct hio_dev_thr_t
{
HIO_DEV_HEADER;
hio_dev_thr_slave_t* slave[2];
int slave_count;
hio_dev_thr_info_t* thr_info;
hio_dev_thr_on_read_t on_read;
hio_dev_thr_on_write_t on_write;
hio_dev_thr_on_close_t on_close;
};
struct hio_dev_thr_slave_t
{
HIO_DEV_HEADER;
hio_dev_thr_sid_t id;
hio_syshnd_t pfd;
hio_dev_thr_t* master; /* parent device */
};
typedef struct hio_dev_thr_make_t hio_dev_thr_make_t;
struct hio_dev_thr_make_t
{
hio_dev_thr_func_t thr_func;
void* thr_ctx;
hio_dev_thr_on_write_t on_write; /* mandatory */
hio_dev_thr_on_read_t on_read; /* mandatory */
hio_dev_thr_on_close_t on_close; /* optional */
};
enum hio_dev_thr_ioctl_cmd_t
{
HIO_DEV_THR_CLOSE,
HIO_DEV_THR_KILL_CHILD
};
typedef enum hio_dev_thr_ioctl_cmd_t hio_dev_thr_ioctl_cmd_t;
#ifdef __cplusplus
extern "C" {
#endif
HIO_EXPORT hio_dev_thr_t* hio_dev_thr_make (
hio_t* hio,
hio_oow_t xtnsize,
const hio_dev_thr_make_t* data
);
#if defined(HIO_HAVE_INLINE)
static HIO_INLINE hio_t* hio_dev_thr_gethio (hio_dev_thr_t* thr) { return hio_dev_gethio((hio_dev_t*)thr); }
#else
# define hio_dev_thr_gethio(thr) hio_dev_gethio(thr)
#endif
#if defined(HIO_HAVE_INLINE)
static HIO_INLINE void* hio_dev_thr_getxtn (hio_dev_thr_t* thr) { return (void*)(thr + 1); }
#else
# define hio_dev_thr_getxtn(thr) ((void*)(((hio_dev_thr_t*)thr) + 1))
#endif
HIO_EXPORT void hio_dev_thr_kill (
hio_dev_thr_t* thr
);
HIO_EXPORT void hio_dev_thr_halt (
hio_dev_thr_t* thr
);
HIO_EXPORT int hio_dev_thr_read (
hio_dev_thr_t* thr,
int enabled
);
HIO_EXPORT int hio_dev_thr_timedread (
hio_dev_thr_t* thr,
int enabled,
const hio_ntime_t* tmout
);
HIO_EXPORT int hio_dev_thr_write (
hio_dev_thr_t* thr,
const void* data,
hio_iolen_t len,
void* wrctx
);
HIO_EXPORT int hio_dev_thr_timedwrite (
hio_dev_thr_t* thr,
const void* data,
hio_iolen_t len,
const hio_ntime_t* tmout,
void* wrctx
);
HIO_EXPORT int hio_dev_thr_close (
hio_dev_thr_t* thr,
hio_dev_thr_sid_t sid
);
void hio_dev_thr_haltslave (
hio_dev_thr_t* dev,
hio_dev_thr_sid_t sid
);
#ifdef __cplusplus
}
#endif
#endif

1051
hio/lib/hio-utl.h Normal file

File diff suppressed because it is too large Load Diff

2170
hio/lib/hio.c Normal file

File diff suppressed because it is too large Load Diff

1416
hio/lib/hio.h Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,382 +0,0 @@
/*
* $Id$
*
Copyright (c) 2016-2020 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 WARRANTIES
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 _MIO_CHR_H_
#define _MIO_CHR_H_
#include <mio-cmn.h>
enum mio_ooch_prop_t
{
MIO_OOCH_PROP_UPPER = (1 << 0),
#define MIO_UCH_PROP_UPPER MIO_OOCH_PROP_UPPER
#define MIO_BCH_PROP_UPPER MIO_OOCH_PROP_UPPER
MIO_OOCH_PROP_LOWER = (1 << 1),
#define MIO_UCH_PROP_LOWER MIO_OOCH_PROP_LOWER
#define MIO_BCH_PROP_LOWER MIO_OOCH_PROP_LOWER
MIO_OOCH_PROP_ALPHA = (1 << 2),
#define MIO_UCH_PROP_ALPHA MIO_OOCH_PROP_ALPHA
#define MIO_BCH_PROP_ALPHA MIO_OOCH_PROP_ALPHA
MIO_OOCH_PROP_DIGIT = (1 << 3),
#define MIO_UCH_PROP_DIGIT MIO_OOCH_PROP_DIGIT
#define MIO_BCH_PROP_DIGIT MIO_OOCH_PROP_DIGIT
MIO_OOCH_PROP_XDIGIT = (1 << 4),
#define MIO_UCH_PROP_XDIGIT MIO_OOCH_PROP_XDIGIT
#define MIO_BCH_PROP_XDIGIT MIO_OOCH_PROP_XDIGIT
MIO_OOCH_PROP_ALNUM = (1 << 5),
#define MIO_UCH_PROP_ALNUM MIO_OOCH_PROP_ALNUM
#define MIO_BCH_PROP_ALNUM MIO_OOCH_PROP_ALNUM
MIO_OOCH_PROP_SPACE = (1 << 6),
#define MIO_UCH_PROP_SPACE MIO_OOCH_PROP_SPACE
#define MIO_BCH_PROP_SPACE MIO_OOCH_PROP_SPACE
MIO_OOCH_PROP_PRINT = (1 << 8),
#define MIO_UCH_PROP_PRINT MIO_OOCH_PROP_PRINT
#define MIO_BCH_PROP_PRINT MIO_OOCH_PROP_PRINT
MIO_OOCH_PROP_GRAPH = (1 << 9),
#define MIO_UCH_PROP_GRAPH MIO_OOCH_PROP_GRAPH
#define MIO_BCH_PROP_GRAPH MIO_OOCH_PROP_GRAPH
MIO_OOCH_PROP_CNTRL = (1 << 10),
#define MIO_UCH_PROP_CNTRL MIO_OOCH_PROP_CNTRL
#define MIO_BCH_PROP_CNTRL MIO_OOCH_PROP_CNTRL
MIO_OOCH_PROP_PUNCT = (1 << 11),
#define MIO_UCH_PROP_PUNCT MIO_OOCH_PROP_PUNCT
#define MIO_BCH_PROP_PUNCT MIO_OOCH_PROP_PUNCT
MIO_OOCH_PROP_BLANK = (1 << 12)
#define MIO_UCH_PROP_BLANK MIO_OOCH_PROP_BLANK
#define MIO_BCH_PROP_BLANK MIO_OOCH_PROP_BLANK
};
typedef enum mio_ooch_prop_t mio_ooch_prop_t;
typedef enum mio_ooch_prop_t mio_uch_prop_t;
typedef enum mio_ooch_prop_t mio_bch_prop_t;
#define MIO_DIGIT_TO_NUM(c) (((c) >= '0' && (c) <= '9')? ((c) - '0'): -1)
#define MIO_XDIGIT_TO_NUM(c) \
(((c) >= '0' && (c) <= '9')? ((c) - '0'): \
((c) >= 'A' && (c) <= 'F')? ((c) - 'A' + 10): \
((c) >= 'a' && (c) <= 'f')? ((c) - 'a' + 10): -1)
#define MIO_ZDIGIT_TO_NUM(c,base) \
(((c) >= '0' && (c) <= '9')? ((c) - '0'): \
((c) >= 'A' && (c) <= 'Z')? ((c) - 'A' + 10): \
((c) >= 'a' && (c) <= 'Z')? ((c) - 'a' + 10): base)
#if defined(__cplusplus)
extern "C" {
#endif
MIO_EXPORT int mio_is_uch_type (mio_uch_t c, mio_uch_prop_t type);
MIO_EXPORT int mio_is_uch_upper (mio_uch_t c);
MIO_EXPORT int mio_is_uch_lower (mio_uch_t c);
MIO_EXPORT int mio_is_uch_alpha (mio_uch_t c);
MIO_EXPORT int mio_is_uch_digit (mio_uch_t c);
MIO_EXPORT int mio_is_uch_xdigit (mio_uch_t c);
MIO_EXPORT int mio_is_uch_alnum (mio_uch_t c);
MIO_EXPORT int mio_is_uch_space (mio_uch_t c);
MIO_EXPORT int mio_is_uch_print (mio_uch_t c);
MIO_EXPORT int mio_is_uch_graph (mio_uch_t c);
MIO_EXPORT int mio_is_uch_cntrl (mio_uch_t c);
MIO_EXPORT int mio_is_uch_punct (mio_uch_t c);
MIO_EXPORT int mio_is_uch_blank (mio_uch_t c);
MIO_EXPORT mio_uch_t mio_to_uch_upper (mio_uch_t c);
MIO_EXPORT mio_uch_t mio_to_uch_lower (mio_uch_t c);
/* ------------------------------------------------------------------------- */
MIO_EXPORT int mio_is_bch_type (mio_bch_t c, mio_bch_prop_t type);
#if defined(__has_builtin)
# if __has_builtin(__builtin_isupper)
# define mio_is_bch_upper __builtin_isupper
# endif
# if __has_builtin(__builtin_islower)
# define mio_is_bch_lower __builtin_islower
# endif
# if __has_builtin(__builtin_isalpha)
# define mio_is_bch_alpha __builtin_isalpha
# endif
# if __has_builtin(__builtin_isdigit)
# define mio_is_bch_digit __builtin_isdigit
# endif
# if __has_builtin(__builtin_isxdigit)
# define mio_is_bch_xdigit __builtin_isxdigit
# endif
# if __has_builtin(__builtin_isalnum)
# define mio_is_bch_alnum __builtin_isalnum
# endif
# if __has_builtin(__builtin_isspace)
# define mio_is_bch_space __builtin_isspace
# endif
# if __has_builtin(__builtin_isprint)
# define mio_is_bch_print __builtin_isprint
# endif
# if __has_builtin(__builtin_isgraph)
# define mio_is_bch_graph __builtin_isgraph
# endif
# if __has_builtin(__builtin_iscntrl)
# define mio_is_bch_cntrl __builtin_iscntrl
# endif
# if __has_builtin(__builtin_ispunct)
# define mio_is_bch_punct __builtin_ispunct
# endif
# if __has_builtin(__builtin_isblank)
# define mio_is_bch_blank __builtin_isblank
# endif
# if __has_builtin(__builtin_toupper)
# define mio_to_bch_upper __builtin_toupper
# endif
# if __has_builtin(__builtin_tolower)
# define mio_to_bch_lower __builtin_tolower
# endif
#elif (__GNUC__ >= 14)
# define mio_is_bch_upper __builtin_isupper
# define mio_is_bch_lower __builtin_islower
# define mio_is_bch_alpha __builtin_isalpha
# define mio_is_bch_digit __builtin_isdigit
# define mio_is_bch_xdigit __builtin_isxdigit
# define mio_is_bch_alnum __builtin_isalnum
# define mio_is_bch_space __builtin_isspace
# define mio_is_bch_print __builtin_isprint
# define mio_is_bch_graph __builtin_isgraph
# define mio_is_bch_cntrl __builtin_iscntrl
# define mio_is_bch_punct __builtin_ispunct
# define mio_is_bch_blank __builtin_isblank
# define mio_to_bch_upper __builtin_toupper
# define mio_to_bch_lower __builtin_tolower
#endif
/* the bch class functions support no locale.
* these implemenent latin-1 only */
#if !defined(mio_is_bch_upper) && defined(MIO_HAVE_INLINE)
static MIO_INLINE int mio_is_bch_upper (mio_bch_t c) { return (mio_bcu_t)c - 'A' < 26; }
#elif !defined(mio_is_bch_upper)
# define mio_is_bch_upper(c) ((mio_bcu_t)(c) - 'A' < 26)
#endif
#if !defined(mio_is_bch_lower) && defined(MIO_HAVE_INLINE)
static MIO_INLINE int mio_is_bch_lower (mio_bch_t c) { return (mio_bcu_t)c - 'a' < 26; }
#elif !defined(mio_is_bch_lower)
# define mio_is_bch_lower(c) ((mio_bcu_t)(c) - 'a' < 26)
#endif
#if !defined(mio_is_bch_alpha) && defined(MIO_HAVE_INLINE)
static MIO_INLINE int mio_is_bch_alpha (mio_bch_t c) { return ((mio_bcu_t)c | 32) - 'a' < 26; }
#elif !defined(mio_is_bch_alpha)
# define mio_is_bch_alpha(c) (((mio_bcu_t)(c) | 32) - 'a' < 26)
#endif
#if !defined(mio_is_bch_digit) && defined(MIO_HAVE_INLINE)
static MIO_INLINE int mio_is_bch_digit (mio_bch_t c) { return (mio_bcu_t)c - '0' < 10; }
#elif !defined(mio_is_bch_digit)
# define mio_is_bch_digit(c) ((mio_bcu_t)(c) - '0' < 10)
#endif
#if !defined(mio_is_bch_xdigit) && defined(MIO_HAVE_INLINE)
static MIO_INLINE int mio_is_bch_xdigit (mio_bch_t c) { return mio_is_bch_digit(c) || ((mio_bcu_t)c | 32) - 'a' < 6; }
#elif !defined(mio_is_bch_xdigit)
# define mio_is_bch_xdigit(c) (mio_is_bch_digit(c) || ((mio_bcu_t)(c) | 32) - 'a' < 6)
#endif
#if !defined(mio_is_bch_alnum) && defined(MIO_HAVE_INLINE)
static MIO_INLINE int mio_is_bch_alnum (mio_bch_t c) { return mio_is_bch_alpha(c) || mio_is_bch_digit(c); }
#elif !defined(mio_is_bch_alnum)
# define mio_is_bch_alnum(c) (mio_is_bch_alpha(c) || mio_is_bch_digit(c))
#endif
#if !defined(mio_is_bch_space) && defined(MIO_HAVE_INLINE)
static MIO_INLINE int mio_is_bch_space (mio_bch_t c) { return c == ' ' || (mio_bcu_t)c - '\t' < 5; }
#elif !defined(mio_is_bch_space)
# define mio_is_bch_space(c) ((c) == ' ' || (mio_bcu_t)(c) - '\t' < 5)
#endif
#if !defined(mio_is_bch_print) && defined(MIO_HAVE_INLINE)
static MIO_INLINE int mio_is_bch_print (mio_bch_t c) { return (mio_bcu_t)c - ' ' < 95; }
#elif !defined(mio_is_bch_print)
# define mio_is_bch_print(c) ((mio_bcu_t)(c) - ' ' < 95)
#endif
#if !defined(mio_is_bch_graph) && defined(MIO_HAVE_INLINE)
static MIO_INLINE int mio_is_bch_graph (mio_bch_t c) { return (mio_bcu_t)c - '!' < 94; }
#elif !defined(mio_is_bch_graph)
# define mio_is_bch_graph(c) ((mio_bcu_t)(c) - '!' < 94)
#endif
#if !defined(mio_is_bch_cntrl) && defined(MIO_HAVE_INLINE)
static MIO_INLINE int mio_is_bch_cntrl (mio_bch_t c) { return (mio_bcu_t)c < ' ' || (mio_bcu_t)c == 127; }
#elif !defined(mio_is_bch_cntrl)
# define mio_is_bch_cntrl(c) ((mio_bcu_t)(c) < ' ' || (mio_bcu_t)(c) == 127)
#endif
#if !defined(mio_is_bch_punct) && defined(MIO_HAVE_INLINE)
static MIO_INLINE int mio_is_bch_punct (mio_bch_t c) { return mio_is_bch_graph(c) && !mio_is_bch_alnum(c); }
#elif !defined(mio_is_bch_punct)
# define mio_is_bch_punct(c) (mio_is_bch_graph(c) && !mio_is_bch_alnum(c))
#endif
#if !defined(mio_is_bch_blank) && defined(MIO_HAVE_INLINE)
static MIO_INLINE int mio_is_bch_blank (mio_bch_t c) { return c == ' ' || c == '\t'; }
#elif !defined(mio_is_bch_blank)
# define mio_is_bch_blank(c) ((c) == ' ' || (c) == '\t')
#endif
#if !defined(mio_to_bch_upper)
MIO_EXPORT mio_bch_t mio_to_bch_upper (mio_bch_t c);
#endif
#if !defined(mio_to_bch_lower)
MIO_EXPORT mio_bch_t mio_to_bch_lower (mio_bch_t c);
#endif
#if defined(MIO_OOCH_IS_UCH)
# define mio_is_ooch_type mio_is_uch_type
# define mio_is_ooch_upper mio_is_uch_upper
# define mio_is_ooch_lower mio_is_uch_lower
# define mio_is_ooch_alpha mio_is_uch_alpha
# define mio_is_ooch_digit mio_is_uch_digit
# define mio_is_ooch_xdigit mio_is_uch_xdigit
# define mio_is_ooch_alnum mio_is_uch_alnum
# define mio_is_ooch_space mio_is_uch_space
# define mio_is_ooch_print mio_is_uch_print
# define mio_is_ooch_graph mio_is_uch_graph
# define mio_is_ooch_cntrl mio_is_uch_cntrl
# define mio_is_ooch_punct mio_is_uch_punct
# define mio_is_ooch_blank mio_is_uch_blank
# define mio_to_ooch_upper mio_to_uch_upper
# define mio_to_ooch_lower mio_to_uch_lower
#else
# define mio_is_ooch_type mio_is_bch_type
# define mio_is_ooch_upper mio_is_bch_upper
# define mio_is_ooch_lower mio_is_bch_lower
# define mio_is_ooch_alpha mio_is_bch_alpha
# define mio_is_ooch_digit mio_is_bch_digit
# define mio_is_ooch_xdigit mio_is_bch_xdigit
# define mio_is_ooch_alnum mio_is_bch_alnum
# define mio_is_ooch_space mio_is_bch_space
# define mio_is_ooch_print mio_is_bch_print
# define mio_is_ooch_graph mio_is_bch_graph
# define mio_is_ooch_cntrl mio_is_bch_cntrl
# define mio_is_ooch_punct mio_is_bch_punct
# define mio_is_ooch_blank mio_is_bch_blank
# define mio_to_ooch_upper mio_to_bch_upper
# define mio_to_ooch_lower mio_to_bch_lower
#endif
MIO_EXPORT int mio_ucstr_to_uch_prop (
const mio_uch_t* name,
mio_uch_prop_t* id
);
MIO_EXPORT int mio_uchars_to_uch_prop (
const mio_uch_t* name,
mio_oow_t len,
mio_uch_prop_t* id
);
MIO_EXPORT int mio_bcstr_to_bch_prop (
const mio_bch_t* name,
mio_bch_prop_t* id
);
MIO_EXPORT int mio_bchars_to_bch_prop (
const mio_bch_t* name,
mio_oow_t len,
mio_bch_prop_t* id
);
#if defined(MIO_OOCH_IS_UCH)
# define mio_oocstr_to_ooch_prop mio_ucstr_to_uch_prop
# define mio_oochars_to_ooch_prop mio_uchars_to_uch_prop
#else
# define mio_oocstr_to_ooch_prop mio_bcstr_to_bch_prop
# define mio_oochars_to_ooch_prop mio_bchars_to_bch_prop
#endif
/* ------------------------------------------------------------------------- */
MIO_EXPORT int mio_get_ucwidth (
mio_uch_t uc
);
/* ------------------------------------------------------------------------- */
MIO_EXPORT mio_oow_t mio_uc_to_utf8 (
mio_uch_t uc,
mio_bch_t* utf8,
mio_oow_t size
);
MIO_EXPORT mio_oow_t mio_utf8_to_uc (
const mio_bch_t* utf8,
mio_oow_t size,
mio_uch_t* uc
);
/* ------------------------------------------------------------------------- */
MIO_EXPORT mio_oow_t mio_uc_to_utf16 (
mio_uch_t uc,
mio_bch_t* utf16,
mio_oow_t size
);
MIO_EXPORT mio_oow_t mio_utf16_to_uc (
const mio_bch_t* utf16,
mio_oow_t size,
mio_uch_t* uc
);
/* ------------------------------------------------------------------------- */
MIO_EXPORT mio_oow_t mio_uc_to_mb8 (
mio_uch_t uc,
mio_bch_t* mb8,
mio_oow_t size
);
MIO_EXPORT mio_oow_t mio_mb8_to_uc (
const mio_bch_t* mb8,
mio_oow_t size,
mio_uch_t* uc
);
#if defined(__cplusplus)
}
#endif
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,609 +0,0 @@
/*
* $Id$
*
Copyright (c) 2016-2020 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 _MIO_DNS_H_
#define _MIO_DNS_H_
#include <mio.h>
#include <mio-skad.h>
#define MIO_DNS_PORT (53)
enum mio_dns_opcode_t
{
MIO_DNS_OPCODE_QUERY = 0, /* standard query */
MIO_DNS_OPCODE_IQUERY = 1, /* inverse query */
MIO_DNS_OPCODE_STATUS = 2, /* status request */
/* 3 unassigned */
MIO_DNS_OPCODE_NOTIFY = 4,
MIO_DNS_OPCODE_UPDATE = 5
};
typedef enum mio_dns_opcode_t mio_dns_opcode_t;
enum mio_dns_rcode_t
{
MIO_DNS_RCODE_NOERROR = 0,
MIO_DNS_RCODE_FORMERR = 1, /* format error */
MIO_DNS_RCODE_SERVFAIL = 2, /* server failure */
MIO_DNS_RCODE_NXDOMAIN = 3, /* non-existent domain */
MIO_DNS_RCODE_NOTIMPL = 4, /* not implemented */
MIO_DNS_RCODE_REFUSED = 5, /* query refused */
MIO_DNS_RCODE_YXDOMAIN = 6, /* name exists when it should not */
MIO_DNS_RCODE_YXRRSET = 7, /* RR set exists when it should not */
MIO_DNS_RCODE_NXRRSET = 8, /* RR set exists when it should not */
MIO_DNS_RCODE_NOTAUTH = 9, /* not authorized or server not authoritative for zone*/
MIO_DNS_RCODE_NOTZONE = 10, /* name not contained in zone */
/* the standard rcode field is 4 bit long. so the max is 15. */
/* items belows require EDNS0 */
MIO_DNS_RCODE_BADVERS = 16,
MIO_DNS_RCODE_BADSIG = 17,
MIO_DNS_RCODE_BADTIME = 18,
MIO_DNS_RCODE_BADMODE = 19,
MIO_DNS_RCODE_BADNAME = 20,
MIO_DNS_RCODE_BADALG = 21,
MIO_DNS_RCODE_BADTRUNC = 22,
MIO_DNS_RCODE_BADCOOKIE = 23
};
typedef enum mio_dns_rcode_t mio_dns_rcode_t;
enum mio_dns_rrt_t
{
/*
* [RFC1035]
* TYPE fields are used in resource records. Note that these types are a
* subset of QTYPEs.
*/
MIO_DNS_RRT_A = 1,
MIO_DNS_RRT_NS = 2,
MIO_DNS_RRT_MD = 3, /* mail destination. RFC973 replaced this with MX*/
MIO_DNS_RRT_MF = 4, /* mail forwarder. RFC973 replaced this with MX */
MIO_DNS_RRT_CNAME = 5,
MIO_DNS_RRT_SOA = 6,
MIO_DNS_RRT_MB = 7, /* kind of obsoleted. RFC1035, RFC2505 */
MIO_DNS_RRT_MG = 8, /* kind of obsoleted. RFC1035, RFC2505 */
MIO_DNS_RRT_MR = 9, /* kind of obsoleted. RFC1035, RFC2505 */
MIO_DNS_RRT_NULL = 10,
MIO_DNS_RRT_PTR = 12,
MIO_DNS_RRT_MINFO = 15, /* kind of obsoleted. RFC1035, RFC2505 */
MIO_DNS_RRT_MX = 15,
MIO_DNS_RRT_TXT = 16,
MIO_DNS_RRT_AAAA = 28,
MIO_DNS_RRT_EID = 31,
MIO_DNS_RRT_SRV = 33,
MIO_DNS_RRT_OPT = 41,
MIO_DNS_RRT_RRSIG = 46,
/*
* [RFC1035]
* QTYPE fields appear in the question part of a query. QTYPES are a
* superset of TYPEs, hence all TYPEs are valid QTYPEs. In addition, the
* following QTYPEs are defined:
*/
MIO_DNS_RRT_Q_AFXR = 252, /* A request for a transfer of an entire zone */
MIO_DNS_RRT_Q_MAILB = 253, /* A request for mailbox-related records (MB, MG or MR) */
MIO_DNS_RRT_Q_MAILA = 254, /* A request for mail agent RRs (Obsolete - see MX) */
MIO_DNS_RRT_Q_ANY = 255 /* A request for all records */
};
typedef enum mio_dns_rrt_t mio_dns_rrt_t;
/*
* CLASS fields appear in resource records. The following CLASS mnemonics
* and values are defined:
*/
enum mio_dns_rrc_t
{
MIO_DNS_RRC_IN = 1, /* internet */
MIO_DNS_RRC_CH = 3, /* chaos */
MIO_DNS_RRC_HS = 4, /* Hesiod [Dyer 87] */
MIO_DNS_RRC_NONE = 254,
/*
*
* QCLASS fields appear in the question section of a query. QCLASS values
* are a superset of CLASS values; every CLASS is a valid QCLASS. In
* addition to CLASS values, the following QCLASSes are defined:
*/
MIO_DNS_RRC_Q_ANY = 255
};
typedef enum mio_dns_rrc_t mio_dns_rrc_t;
enum mio_dns_eopt_code_t
{
MIO_DNS_EOPT_NSID = 3,
MIO_DNS_EOPT_DAU = 5,
MIO_DNS_EOPT_DHU = 6,
MIO_DNS_EOPT_N3U = 7,
MIO_DNS_EOPT_ECS = 8,
MIO_DNS_EOPT_EXPIRE = 9,
MIO_DNS_EOPT_COOKIE = 10,
MIO_DNS_EOPT_TCPKEEPALIVE = 11,
MIO_DNS_EOPT_PADDING = 12,
MIO_DNS_EOPT_CHAIN = 13,
MIO_DNS_EOPT_KEYTAG = 14,
};
typedef enum mio_dns_eopt_code_t mio_dns_eopt_code_t;
/* dns message preamble */
typedef struct mio_dns_msg_t mio_dns_msg_t;
struct mio_dns_msg_t
{
mio_oow_t msglen;
mio_oow_t ednsrrtroff; /* offset to trailing data after the name in the dns0 RR*/
mio_oow_t pktlen;
mio_oow_t pktalilen;
};
#include <mio-pac1.h>
struct mio_dns_pkt_t /* dns packet header */
{
mio_uint16_t id;
#if defined(MIO_ENDIAN_BIG)
mio_uint16_t qr: 1; /* query(0), answer(1) */
mio_uint16_t opcode: 4; /* operation type */
mio_uint16_t aa: 1; /* authoritative answer */
mio_uint16_t tc: 1; /* truncated. response too large for UDP */
mio_uint16_t rd: 1; /* recursion desired */
mio_uint16_t ra: 1; /* recursion available */
mio_uint16_t unused_1: 1;
mio_uint16_t ad: 1; /* authentication data - dnssec */
mio_uint16_t cd: 1; /* checking disabled - dnssec */
mio_uint16_t rcode: 4; /* reply code - for reply only */
#else
mio_uint16_t rd: 1;
mio_uint16_t tc: 1;
mio_uint16_t aa: 1;
mio_uint16_t opcode: 4;
mio_uint16_t qr: 1;
mio_uint16_t rcode: 4;
mio_uint16_t cd: 1;
mio_uint16_t ad: 1;
mio_uint16_t unused_1: 1;
mio_uint16_t ra: 1;
#endif
mio_uint16_t qdcount; /* number of questions */
mio_uint16_t ancount; /* number of answers (answer part) */
mio_uint16_t nscount; /* number of name servers (authority part. only NS types) */
mio_uint16_t arcount; /* number of additional resource (additional part) */
};
typedef struct mio_dns_pkt_t mio_dns_pkt_t;
struct mio_dns_pkt_alt_t
{
mio_uint16_t id;
mio_uint16_t flags;
mio_uint16_t rrcount[4];
};
typedef struct mio_dns_pkt_alt_t mio_dns_pkt_alt_t;
/* question
* name, qtype, qclass
* answer
* name, qtype, qclass, ttl, rlength, rdata
*/
/* trailing part after the domain name in a resource record in a question */
struct mio_dns_qrtr_t
{
/* qname upto 64 bytes */
mio_uint16_t qtype;
mio_uint16_t qclass;
};
typedef struct mio_dns_qrtr_t mio_dns_qrtr_t;
/* trailing part after the domain name in a resource record in an answer */
struct mio_dns_rrtr_t
{
/* qname upto 64 bytes */
mio_uint16_t rrtype;
mio_uint16_t rrclass;
mio_uint32_t ttl;
mio_uint16_t dlen; /* data length */
/* actual data if if dlen > 0 */
};
typedef struct mio_dns_rrtr_t mio_dns_rrtr_t;
struct mio_dns_eopt_t
{
mio_uint16_t code;
mio_uint16_t dlen;
/* actual data if if dlen > 0 */
};
typedef struct mio_dns_eopt_t mio_dns_eopt_t;
#include <mio-upac.h>
/* ---------------------------------------------------------------- */
/*
#define MIO_DNS_HEADER_MAKE_FLAGS(qr,opcode,aa,tc,rd,ra,ad,cd,rcode) \
((((qr) & 0x01) << 15) | (((opcode) & 0x0F) << 14) | (((aa) & 0x01) << 10) | (((tc) & 0x01) << 9) | \
(((rd) & 0x01) << 8) | (((ra) & 0x01) << 7) | (((ad) & 0x01) << 5) | (((cd) & 0x01) << 4) | ((rcode) & 0x0F))
*/
/* breakdown of the dns message id and flags. it excludes rr count fields.*/
struct mio_dns_bhdr_t
{
mio_int32_t id;
mio_uint8_t qr; /* query(0), answer(1) */
mio_uint8_t opcode; /* operation type */
mio_uint8_t aa; /* authoritative answer */
mio_uint8_t tc; /* truncated. response too large for UDP */
mio_uint8_t rd; /* recursion desired */
mio_uint8_t ra; /* recursion available */
mio_uint8_t ad; /* authentication data - dnssec */
mio_uint8_t cd; /* checking disabled - dnssec */
mio_uint8_t rcode; /* reply code - for reply only */
};
typedef struct mio_dns_bhdr_t mio_dns_bhdr_t;
/* breakdown of question record */
struct mio_dns_bqr_t
{
mio_bch_t* qname;
mio_uint16_t qtype;
mio_uint16_t qclass;
};
typedef struct mio_dns_bqr_t mio_dns_bqr_t;
enum mio_dns_rr_part_t
{
MIO_DNS_RR_PART_ANSWER,
MIO_DNS_RR_PART_AUTHORITY,
MIO_DNS_RR_PART_ADDITIONAL
};
typedef enum mio_dns_rr_part_t mio_dns_rr_part_t;
/* breakdown of resource record */
struct mio_dns_brr_t
{
mio_dns_rr_part_t part;
mio_bch_t* rrname;
mio_uint16_t rrtype;
mio_uint16_t rrclass;
mio_uint32_t ttl;
mio_uint16_t dlen;
void* dptr;
};
typedef struct mio_dns_brr_t mio_dns_brr_t;
#if 0
/* A RDATA */
struct mio_dns_brrd_a_t
{
};
typedef struct mio_dns_brrd_a_t mio_dns_brrd_a_t;
/* 3.3.1 CNAME RDATA format */
struct mio_dns_brrd_cname_t
{
};
typedef struct mio_dns_brrd_cname_t mio_dns_brc_cname_t;
#endif
/* 3.3.9 MX RDATA format */
struct mio_dns_brrd_mx_t
{
mio_uint16_t preference;
mio_bch_t* exchange;
};
typedef struct mio_dns_brrd_mx_t mio_dns_brrd_mx_t;
/* 3.3.13. SOA RDATA format */
struct mio_dns_brrd_soa_t
{
mio_bch_t* mname;
mio_bch_t* rname;
mio_uint32_t serial;
mio_uint32_t refresh;
mio_uint32_t retry;
mio_uint32_t expire;
mio_uint32_t minimum;
};
typedef struct mio_dns_brrd_soa_t mio_dns_brrd_soa_t;
struct mio_dns_beopt_t
{
mio_uint16_t code;
mio_uint16_t dlen;
void* dptr;
};
typedef struct mio_dns_beopt_t mio_dns_beopt_t;
/* the full rcode must be given. the macro takes the upper 8 bits */
#define MIO_DNS_EDNS_MAKE_TTL(rcode,version,dnssecok) ((((((mio_uint32_t)rcode) >> 4) & 0xFF) << 24) | (((mio_uint32_t)version & 0xFF) << 16) | (((mio_uint32_t)dnssecok & 0x1) << 15))
struct mio_dns_bedns_t
{
mio_uint16_t uplen; /* udp payload len - will be placed in the qclass field of RR. */
/* the ttl field(32 bits) of RR holds extended rcode, version, dnssecok */
mio_uint8_t version;
mio_uint8_t dnssecok;
mio_oow_t beonum; /* option count */
mio_dns_beopt_t* beoptr;
};
typedef struct mio_dns_bedns_t mio_dns_bedns_t;
/* ---------------------------------------------------------------- */
typedef struct mio_svc_dns_t mio_svc_dns_t; /* server service */
typedef struct mio_svc_dnc_t mio_svc_dnc_t; /* client service */
typedef struct mio_svc_dnr_t mio_svc_dnr_t; /* recursor service */
typedef void (*mio_svc_dnc_on_done_t) (
mio_svc_dnc_t* dnc,
mio_dns_msg_t* reqmsg,
mio_errnum_t status,
const void* data,
mio_oow_t len
);
typedef void (*mio_svc_dnc_on_resolve_t) (
mio_svc_dnc_t* dnc,
mio_dns_msg_t* reqmsg,
mio_errnum_t status,
const void* data,
mio_oow_t len
);
enum mio_svc_dnc_send_flag_t
{
MIO_SVC_DNC_SEND_FLAG_PREFER_TCP = (1 << 0),
MIO_SVC_DNC_SEND_FLAG_TCP_IF_TC = (1 << 1), // retry over tcp if the truncated bit is set in an answer over udp.
MIO_SVC_DNC_SEND_FLAG_ALL = (MIO_SVC_DNC_SEND_FLAG_PREFER_TCP | MIO_SVC_DNC_SEND_FLAG_TCP_IF_TC)
};
typedef enum mio_svc_dnc_send_flag_t mio_svc_dnc_send_flag_t;
enum mio_svc_dnc_resolve_flag_t
{
MIO_SVC_DNC_RESOLVE_FLAG_PREFER_TCP = MIO_SVC_DNC_SEND_FLAG_PREFER_TCP,
MIO_SVC_DNC_RESOLVE_FLAG_TCP_IF_TC = MIO_SVC_DNC_SEND_FLAG_TCP_IF_TC,
/* the following flag bits are resolver specific. it must not overlap with send flag bits */
MIO_SVC_DNC_RESOLVE_FLAG_BRIEF = (1 << 8),
MIO_SVC_DNC_RESOLVE_FLAG_COOKIE = (1 << 9),
MIO_SVC_DNC_RESOLVE_FLAG_DNSSEC = (1 << 10),
MIO_SVC_DNC_RESOLVE_FLAG_ALL = (MIO_SVC_DNC_RESOLVE_FLAG_PREFER_TCP | MIO_SVC_DNC_RESOLVE_FLAG_TCP_IF_TC | MIO_SVC_DNC_RESOLVE_FLAG_BRIEF | MIO_SVC_DNC_RESOLVE_FLAG_COOKIE | MIO_SVC_DNC_RESOLVE_FLAG_DNSSEC)
};
typedef enum mio_svc_dnc_resolve_flag_t mio_svc_dnc_resolve_flag_t;
/* ---------------------------------------------------------------- */
#define MIO_DNS_COOKIE_CLIENT_LEN (8)
#define MIO_DNS_COOKIE_SERVER_MIN_LEN (16)
#define MIO_DNS_COOKIE_SERVER_MAX_LEN (40)
#define MIO_DNS_COOKIE_MAX_LEN (MIO_DNS_COOKIE_CLIENT_LEN + MIO_DNS_COOKIE_SERVER_MAX_LEN)
typedef struct mio_dns_cookie_data_t mio_dns_cookie_data_t;
#include <mio-pac1.h>
struct mio_dns_cookie_data_t
{
mio_uint8_t client[MIO_DNS_COOKIE_CLIENT_LEN];
mio_uint8_t server[MIO_DNS_COOKIE_SERVER_MAX_LEN];
};
#include <mio-upac.h>
typedef struct mio_dns_cookie_t mio_dns_cookie_t;
struct mio_dns_cookie_t
{
mio_dns_cookie_data_t data;
mio_uint8_t client_len;
mio_uint8_t server_len;
mio_uint8_t key[16];
};
/* ---------------------------------------------------------------- */
struct mio_dns_pkt_info_t
{
/* the following 5 fields are internal use only */
mio_uint8_t* _start;
mio_uint8_t* _end;
mio_uint8_t* _ptr;
mio_oow_t _rrdlen; /* length needed to store RRs decoded */
mio_uint8_t* _rrdptr;
/* you may access the following fields */
mio_dns_bhdr_t hdr;
struct
{
int exist;
mio_uint16_t uplen; /* udp payload len - will be placed in the qclass field of RR. */
mio_uint8_t version;
mio_uint8_t dnssecok;
mio_dns_cookie_t cookie;
} edns;
mio_uint16_t qdcount; /* number of questions */
mio_uint16_t ancount; /* number of answers (answer part) */
mio_uint16_t nscount; /* number of name servers (authority part. only NS types) */
mio_uint16_t arcount; /* number of additional resource (additional part) */
struct
{
mio_dns_bqr_t* qd;
mio_dns_brr_t* an;
mio_dns_brr_t* ns;
mio_dns_brr_t* ar;
} rr;
};
typedef struct mio_dns_pkt_info_t mio_dns_pkt_info_t;
/* ---------------------------------------------------------------- */
#if defined(__cplusplus)
extern "C" {
#endif
MIO_EXPORT mio_svc_dnc_t* mio_svc_dnc_start (
mio_t* mio,
const mio_skad_t* serv_addr, /* required */
const mio_skad_t* bind_addr, /* optional. can be MIO_NULL */
const mio_ntime_t* send_tmout, /* required */
const mio_ntime_t* reply_tmout, /* required */
mio_oow_t max_tries /* required */
);
MIO_EXPORT void mio_svc_dnc_stop (
mio_svc_dnc_t* dnc
);
#if defined(MIO_HAVE_INLINE)
static MIO_INLINE mio_t* mio_svc_dns_getmio(mio_svc_dns_t* svc) { return mio_svc_getmio((mio_svc_t*)svc); }
static MIO_INLINE mio_t* mio_svc_dnc_getmio(mio_svc_dnc_t* svc) { return mio_svc_getmio((mio_svc_t*)svc); }
static MIO_INLINE mio_t* mio_svc_dnr_getmio(mio_svc_dnr_t* svc) { return mio_svc_getmio((mio_svc_t*)svc); }
#else
# define mio_svc_dns_getmio(svc) mio_svc_getmio(svc)
# define mio_svc_dnc_getmio(svc) mio_svc_getmio(svc)
# define mio_svc_dnr_getmio(svc) mio_svc_getmio(svc)
#endif
MIO_EXPORT mio_dns_msg_t* mio_svc_dnc_sendmsg (
mio_svc_dnc_t* dnc,
mio_dns_bhdr_t* bdns,
mio_dns_bqr_t* qr,
mio_oow_t qr_count,
mio_dns_brr_t* rr,
mio_oow_t rr_count,
mio_dns_bedns_t* edns,
int send_flags,
mio_svc_dnc_on_done_t on_done,
mio_oow_t xtnsize
);
MIO_EXPORT mio_dns_msg_t* mio_svc_dnc_sendreq (
mio_svc_dnc_t* dnc,
mio_dns_bhdr_t* bdns,
mio_dns_bqr_t* qr,
mio_dns_bedns_t* edns,
int send_flags,
mio_svc_dnc_on_done_t on_done,
mio_oow_t xtnsize
);
MIO_EXPORT mio_dns_msg_t* mio_svc_dnc_resolve (
mio_svc_dnc_t* dnc,
const mio_bch_t* qname,
mio_dns_rrt_t qtype,
int resolve_flags,
mio_svc_dnc_on_resolve_t on_resolve,
mio_oow_t xtnsize
);
/*
* -1: cookie in the request but no client cookie in the response. this may be ok or not ok depending on your policy
* 0: client cookie mismatch in the request in the response
* 1: client cookie match in the request in the response
* 2: no client cookie in the requset. so it deson't case about the response
*/
MIO_EXPORT int mio_svc_dnc_checkclientcookie (
mio_svc_dnc_t* dnc,
mio_dns_msg_t* reqmsg,
mio_dns_pkt_info_t* respi
);
/* ---------------------------------------------------------------- */
MIO_EXPORT mio_dns_pkt_info_t* mio_dns_make_pkt_info (
mio_t* mio,
const mio_dns_pkt_t* pkt,
mio_oow_t len
);
MIO_EXPORT void mio_dns_free_pkt_info (
mio_t* mio,
mio_dns_pkt_info_t* pi
);
/* ---------------------------------------------------------------- */
#if defined(MIO_HAVE_INLINE)
static MIO_INLINE mio_dns_pkt_t* mio_dns_msg_to_pkt (mio_dns_msg_t* msg) { return (mio_dns_pkt_t*)(msg + 1); }
#else
# define mio_dns_msg_to_pkt(msg) ((mio_dns_pkt_t*)((mio_dns_msg_t*)(msg) + 1))
#endif
MIO_EXPORT mio_dns_msg_t* mio_dns_make_msg (
mio_t* mio,
mio_dns_bhdr_t* bhdr,
mio_dns_bqr_t* qr,
mio_oow_t qr_count,
mio_dns_brr_t* rr,
mio_oow_t rr_count,
mio_dns_bedns_t* edns,
mio_oow_t xtnsize
);
MIO_EXPORT void mio_dns_free_msg (
mio_t* mio,
mio_dns_msg_t* msg
);
/*
* return the pointer to the client cookie data in the packet.
* if cookie is not MIO_NULL, it copies the client cookie there.
*/
MIO_EXPORT mio_uint8_t* mio_dns_find_client_cookie_in_msg (
mio_dns_msg_t* reqmsg,
mio_uint8_t (*cookie)[MIO_DNS_COOKIE_CLIENT_LEN]
);
MIO_EXPORT mio_bch_t* mio_dns_rcode_to_bcstr (
mio_dns_rcode_t rcode
);
#if defined(__cplusplus)
}
#endif
#endif

View File

@ -1,635 +0,0 @@
/*
* $Id$
*
Copyright (c) 2016-2020 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 WARRANTIES
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 _MIO_ECS_H_
#define _MIO_ECS_H_
#include <mio.h>
#include <stdarg.h>
/** string pointer and length as a aggregate */
#define MIO_BECS_BCS(s) (&((s)->val))
/** string length */
#define MIO_BECS_LEN(s) ((s)->val.len)
/** string pointer */
#define MIO_BECS_PTR(s) ((s)->val.ptr)
/** pointer to a particular position */
#define MIO_BECS_CPTR(s,idx) (&(s)->val.ptr[idx])
/** string capacity */
#define MIO_BECS_CAPA(s) ((s)->capa)
/** character at the given position */
#define MIO_BECS_CHAR(s,idx) ((s)->val.ptr[idx])
/**< last character. unsafe if length <= 0 */
#define MIO_BECS_LASTCHAR(s) ((s)->val.ptr[(s)->val.len-1])
/** string pointer and length as a aggregate */
#define MIO_UECS_UCS(s) (&((s)->val))
/** string length */
#define MIO_UECS_LEN(s) ((s)->val.len)
/** string pointer */
#define MIO_UECS_PTR(s) ((s)->val.ptr)
/** pointer to a particular position */
#define MIO_UECS_CPTR(s,idx) (&(s)->val.ptr[idx])
/** string capacity */
#define MIO_UECS_CAPA(s) ((s)->capa)
/** character at the given position */
#define MIO_UECS_CHAR(s,idx) ((s)->val.ptr[idx])
/**< last character. unsafe if length <= 0 */
#define MIO_UECS_LASTCHAR(s) ((s)->val.ptr[(s)->val.len-1])
typedef struct mio_becs_t mio_becs_t;
typedef struct mio_uecs_t mio_uecs_t;
typedef mio_oow_t (*mio_becs_sizer_t) (
mio_becs_t* data,
mio_oow_t hint
);
typedef mio_oow_t (*mio_uecs_sizer_t) (
mio_uecs_t* data,
mio_oow_t hint
);
#if defined(MIO_OOCH_IS_UCH)
# define MIO_OOECS_OOCS(s) MIO_UECS_UCS(s)
# define MIO_OOECS_LEN(s) MIO_UECS_LEN(s)
# define MIO_OOECS_PTR(s) MIO_UECS_PTR(s)
# define MIO_OOECS_CPTR(s,idx) MIO_UECS_CPTR(s,idx)
# define MIO_OOECS_CAPA(s) MIO_UECS_CAPA(s)
# define MIO_OOECS_CHAR(s,idx) MIO_UECS_CHAR(s,idx)
# define MIO_OOECS_LASTCHAR(s) MIO_UECS_LASTCHAR(s)
# define mio_ooecs_t mio_uecs_t
# define mio_ooecs_sizer_t mio_uecs_sizer_t
#else
# define MIO_OOECS_OOCS(s) MIO_BECS_BCS(s)
# define MIO_OOECS_LEN(s) MIO_BECS_LEN(s)
# define MIO_OOECS_PTR(s) MIO_BECS_PTR(s)
# define MIO_OOECS_CPTR(s,idx) MIO_BECS_CPTR(s,idx)
# define MIO_OOECS_CAPA(s) MIO_BECS_CAPA(s)
# define MIO_OOECS_CHAR(s,idx) MIO_BECS_CHAR(s,idx)
# define MIO_OOECS_LASTCHAR(s) MIO_BECS_LASTCHAR(s)
# define mio_ooecs_t mio_becs_t
# define mio_ooecs_sizer_t mio_becs_sizer_t
#endif
/**
* The mio_becs_t type defines a dynamically resizable multi-byte string.
*/
struct mio_becs_t
{
mio_t* mio;
mio_becs_sizer_t sizer; /**< buffer resizer function */
mio_bcs_t val; /**< buffer/string pointer and lengh */
mio_oow_t capa; /**< buffer capacity */
};
/**
* The mio_uecs_t type defines a dynamically resizable wide-character string.
*/
struct mio_uecs_t
{
mio_t* mio;
mio_uecs_sizer_t sizer; /**< buffer resizer function */
mio_ucs_t val; /**< buffer/string pointer and lengh */
mio_oow_t capa; /**< buffer capacity */
};
#if defined(__cplusplus)
extern "C" {
#endif
/**
* The mio_becs_open() function creates a dynamically resizable multibyte string.
*/
MIO_EXPORT mio_becs_t* mio_becs_open (
mio_t* mio,
mio_oow_t xtnsize,
mio_oow_t capa
);
MIO_EXPORT void mio_becs_close (
mio_becs_t* becs
);
/**
* The mio_becs_init() function initializes a dynamically resizable string
* If the parameter capa is 0, it doesn't allocate the internal buffer
* in advance and always succeeds.
* \return 0 on success, -1 on failure.
*/
MIO_EXPORT int mio_becs_init (
mio_becs_t* becs,
mio_t* mio,
mio_oow_t capa
);
/**
* The mio_becs_fini() function finalizes a dynamically resizable string.
*/
MIO_EXPORT void mio_becs_fini (
mio_becs_t* becs
);
#if defined(MIO_HAVE_INLINE)
static MIO_INLINE void* mio_becs_getxtn (mio_becs_t* becs) { return (void*)(becs + 1); }
#else
#define mio_becs_getxtn(becs) ((void*)((mio_becs_t*)(becs) + 1))
#endif
/**
* The mio_becs_yield() function assigns the buffer to an variable of the
* #mio_bcs_t type and recreate a new buffer of the \a new_capa capacity.
* The function fails if it fails to allocate a new buffer.
* \return 0 on success, and -1 on failure.
*/
MIO_EXPORT int mio_becs_yield (
mio_becs_t* becs, /**< string */
mio_bcs_t* buf, /**< buffer pointer */
mio_oow_t newcapa /**< new capacity */
);
MIO_EXPORT mio_bch_t* mio_becs_yieldptr (
mio_becs_t* becs, /**< string */
mio_oow_t newcapa /**< new capacity */
);
/**
* The mio_becs_getsizer() function gets the sizer.
* \return sizer function set or MIO_NULL if no sizer is set.
*/
#if defined(MIO_HAVE_INLINE)
static MIO_INLINE mio_becs_sizer_t mio_becs_getsizer (mio_becs_t* becs) { return becs->sizer; }
#else
# define mio_becs_getsizer(becs) ((becs)->sizer)
#endif
/**
* The mio_becs_setsizer() function specify a new sizer for a dynamic string.
* With no sizer specified, the dynamic string doubles the current buffer
* when it needs to increase its size. The sizer function is passed a dynamic
* string and the minimum capacity required to hold data after resizing.
* The string is truncated if the sizer function returns a smaller number
* than the hint passed.
*/
#if defined(MIO_HAVE_INLINE)
static MIO_INLINE void mio_becs_setsizer (mio_becs_t* becs, mio_becs_sizer_t sizer) { becs->sizer = sizer; }
#else
# define mio_becs_setsizer(becs,sizerfn) ((becs)->sizer = (sizerfn))
#endif
/**
* The mio_becs_getcapa() function returns the current capacity.
* You may use MIO_STR_CAPA(str) macro for performance sake.
* \return current capacity in number of characters.
*/
#if defined(MIO_HAVE_INLINE)
static MIO_INLINE mio_oow_t mio_becs_getcapa (mio_becs_t* becs) { return MIO_BECS_CAPA(becs); }
#else
# define mio_becs_getcapa(becs) MIO_BECS_CAPA(becs)
#endif
/**
* The mio_becs_setcapa() function sets the new capacity. If the new capacity
* is smaller than the old, the overflowing characters are removed from
* from the buffer.
* \return (mio_oow_t)-1 on failure, new capacity on success
*/
MIO_EXPORT mio_oow_t mio_becs_setcapa (
mio_becs_t* becs,
mio_oow_t capa
);
/**
* The mio_becs_getlen() function return the string length.
*/
#if defined(MIO_HAVE_INLINE)
static MIO_INLINE mio_oow_t mio_becs_getlen (mio_becs_t* becs) { return MIO_BECS_LEN(becs); }
#else
# define mio_becs_getlen(becs) MIO_BECS_LEN(becs)
#endif
/**
* The mio_becs_setlen() function changes the string length.
* \return (mio_oow_t)-1 on failure, new length on success
*/
MIO_EXPORT mio_oow_t mio_becs_setlen (
mio_becs_t* becs,
mio_oow_t len
);
/**
* The mio_becs_clear() funtion deletes all characters in a string and sets
* the length to 0. It doesn't resize the internal buffer.
*/
MIO_EXPORT void mio_becs_clear (
mio_becs_t* becs
);
/**
* The mio_becs_swap() function exchanges the pointers to a buffer between
* two strings. It updates the length and the capacity accordingly.
*/
MIO_EXPORT void mio_becs_swap (
mio_becs_t* becs1,
mio_becs_t* becs2
);
MIO_EXPORT mio_oow_t mio_becs_cpy (
mio_becs_t* becs,
const mio_bch_t* s
);
MIO_EXPORT mio_oow_t mio_becs_ncpy (
mio_becs_t* becs,
const mio_bch_t* s,
mio_oow_t len
);
MIO_EXPORT mio_oow_t mio_becs_cat (
mio_becs_t* becs,
const mio_bch_t* s
);
MIO_EXPORT mio_oow_t mio_becs_ncat (
mio_becs_t* becs,
const mio_bch_t* s,
mio_oow_t len
);
MIO_EXPORT mio_oow_t mio_becs_nrcat (
mio_becs_t* becs,
const mio_bch_t* s,
mio_oow_t len
);
MIO_EXPORT mio_oow_t mio_becs_ccat (
mio_becs_t* becs,
mio_bch_t c
);
MIO_EXPORT mio_oow_t mio_becs_nccat (
mio_becs_t* becs,
mio_bch_t c,
mio_oow_t len
);
MIO_EXPORT mio_oow_t mio_becs_del (
mio_becs_t* becs,
mio_oow_t index,
mio_oow_t size
);
MIO_EXPORT mio_oow_t mio_becs_amend (
mio_becs_t* becs,
mio_oow_t index,
mio_oow_t size,
const mio_bch_t* repl
);
MIO_EXPORT mio_oow_t mio_becs_vfcat (
mio_becs_t* str,
const mio_bch_t* fmt,
va_list ap
);
MIO_EXPORT mio_oow_t mio_becs_fcat (
mio_becs_t* str,
const mio_bch_t* fmt,
...
);
MIO_EXPORT mio_oow_t mio_becs_vfmt (
mio_becs_t* str,
const mio_bch_t* fmt,
va_list ap
);
MIO_EXPORT mio_oow_t mio_becs_fmt (
mio_becs_t* str,
const mio_bch_t* fmt,
...
);
/* ------------------------------------------------------------------------ */
/**
* The mio_uecs_open() function creates a dynamically resizable multibyte string.
*/
MIO_EXPORT mio_uecs_t* mio_uecs_open (
mio_t* mio,
mio_oow_t xtnsize,
mio_oow_t capa
);
MIO_EXPORT void mio_uecs_close (
mio_uecs_t* uecs
);
/**
* The mio_uecs_init() function initializes a dynamically resizable string
* If the parameter capa is 0, it doesn't allocate the internal buffer
* in advance and always succeeds.
* \return 0 on success, -1 on failure.
*/
MIO_EXPORT int mio_uecs_init (
mio_uecs_t* uecs,
mio_t* mio,
mio_oow_t capa
);
/**
* The mio_uecs_fini() function finalizes a dynamically resizable string.
*/
MIO_EXPORT void mio_uecs_fini (
mio_uecs_t* uecs
);
#if defined(MIO_HAVE_INLINE)
static MIO_INLINE void* mio_uecs_getxtn (mio_uecs_t* uecs) { return (void*)(uecs + 1); }
#else
#define mio_uecs_getxtn(uecs) ((void*)((mio_uecs_t*)(uecs) + 1))
#endif
/**
* The mio_uecs_yield() function assigns the buffer to an variable of the
* #mio_ucs_t type and recreate a new buffer of the \a new_capa capacity.
* The function fails if it fails to allocate a new buffer.
* \return 0 on success, and -1 on failure.
*/
MIO_EXPORT int mio_uecs_yield (
mio_uecs_t* uecs, /**< string */
mio_ucs_t* buf, /**< buffer pointer */
mio_oow_t newcapa /**< new capacity */
);
MIO_EXPORT mio_uch_t* mio_uecs_yieldptr (
mio_uecs_t* uecs, /**< string */
mio_oow_t newcapa /**< new capacity */
);
/**
* The mio_uecs_getsizer() function gets the sizer.
* \return sizer function set or MIO_NULL if no sizer is set.
*/
#if defined(MIO_HAVE_INLINE)
static MIO_INLINE mio_uecs_sizer_t mio_uecs_getsizer (mio_uecs_t* uecs) { return uecs->sizer; }
#else
# define mio_uecs_getsizer(uecs) ((uecs)->sizer)
#endif
/**
* The mio_uecs_setsizer() function specify a new sizer for a dynamic string.
* With no sizer specified, the dynamic string doubles the current buffer
* when it needs to increase its size. The sizer function is passed a dynamic
* string and the minimum capacity required to hold data after resizing.
* The string is truncated if the sizer function returns a smaller number
* than the hint passed.
*/
#if defined(MIO_HAVE_INLINE)
static MIO_INLINE void mio_uecs_setsizer (mio_uecs_t* uecs, mio_uecs_sizer_t sizer) { uecs->sizer = sizer; }
#else
# define mio_uecs_setsizer(uecs,sizerfn) ((uecs)->sizer = (sizerfn))
#endif
/**
* The mio_uecs_getcapa() function returns the current capacity.
* You may use MIO_STR_CAPA(str) macro for performance sake.
* \return current capacity in number of characters.
*/
#if defined(MIO_HAVE_INLINE)
static MIO_INLINE mio_oow_t mio_uecs_getcapa (mio_uecs_t* uecs) { return MIO_UECS_CAPA(uecs); }
#else
# define mio_uecs_getcapa(uecs) MIO_UECS_CAPA(uecs)
#endif
/**
* The mio_uecs_setcapa() function sets the new capacity. If the new capacity
* is smaller than the old, the overflowing characters are removed from
* from the buffer.
* \return (mio_oow_t)-1 on failure, new capacity on success
*/
MIO_EXPORT mio_oow_t mio_uecs_setcapa (
mio_uecs_t* uecs,
mio_oow_t capa
);
/**
* The mio_uecs_getlen() function return the string length.
*/
#if defined(MIO_HAVE_INLINE)
static MIO_INLINE mio_oow_t mio_uecs_getlen (mio_uecs_t* uecs) { return MIO_UECS_LEN(uecs); }
#else
# define mio_uecs_getlen(uecs) MIO_UECS_LEN(uecs)
#endif
/**
* The mio_uecs_setlen() function changes the string length.
* \return (mio_oow_t)-1 on failure, new length on success
*/
MIO_EXPORT mio_oow_t mio_uecs_setlen (
mio_uecs_t* uecs,
mio_oow_t len
);
/**
* The mio_uecs_clear() funtion deletes all characters in a string and sets
* the length to 0. It doesn't resize the internal buffer.
*/
MIO_EXPORT void mio_uecs_clear (
mio_uecs_t* uecs
);
/**
* The mio_uecs_swap() function exchanges the pointers to a buffer between
* two strings. It updates the length and the capacity accordingly.
*/
MIO_EXPORT void mio_uecs_swap (
mio_uecs_t* uecs1,
mio_uecs_t* uecs2
);
MIO_EXPORT mio_oow_t mio_uecs_cpy (
mio_uecs_t* uecs,
const mio_uch_t* s
);
MIO_EXPORT mio_oow_t mio_uecs_ncpy (
mio_uecs_t* uecs,
const mio_uch_t* s,
mio_oow_t len
);
MIO_EXPORT mio_oow_t mio_uecs_cat (
mio_uecs_t* uecs,
const mio_uch_t* s
);
MIO_EXPORT mio_oow_t mio_uecs_ncat (
mio_uecs_t* uecs,
const mio_uch_t* s,
mio_oow_t len
);
MIO_EXPORT mio_oow_t mio_uecs_nrcat (
mio_uecs_t* uecs,
const mio_uch_t* s,
mio_oow_t len
);
MIO_EXPORT mio_oow_t mio_uecs_ccat (
mio_uecs_t* uecs,
mio_uch_t c
);
MIO_EXPORT mio_oow_t mio_uecs_nccat (
mio_uecs_t* uecs,
mio_uch_t c,
mio_oow_t len
);
MIO_EXPORT mio_oow_t mio_uecs_del (
mio_uecs_t* uecs,
mio_oow_t index,
mio_oow_t size
);
MIO_EXPORT mio_oow_t mio_uecs_amend (
mio_uecs_t* uecs,
mio_oow_t index,
mio_oow_t size,
const mio_uch_t* repl
);
MIO_EXPORT mio_oow_t mio_uecs_vfcat (
mio_uecs_t* str,
const mio_uch_t* fmt,
va_list ap
);
MIO_EXPORT mio_oow_t mio_uecs_fcat (
mio_uecs_t* str,
const mio_uch_t* fmt,
...
);
MIO_EXPORT mio_oow_t mio_uecs_vfmt (
mio_uecs_t* str,
const mio_uch_t* fmt,
va_list ap
);
MIO_EXPORT mio_oow_t mio_uecs_fmt (
mio_uecs_t* str,
const mio_uch_t* fmt,
...
);
#if defined(MIO_OOCH_IS_UCH)
# define mio_ooecs_open mio_uecs_open
# define mio_ooecs_close mio_uecs_close
# define mio_ooecs_init mio_uecs_init
# define mio_ooecs_fini mio_uecs_fini
# define mio_ooecs_getxtn mio_uecs_getxtn
# define mio_ooecs_yield mio_uecs_yield
# define mio_ooecs_yieldptr mio_uecs_yieldptr
# define mio_ooecs_getsizer mio_uecs_getsizer
# define mio_ooecs_setsizer mio_uecs_setsizer
# define mio_ooecs_getcapa mio_uecs_getcapa
# define mio_ooecs_setcapa mio_uecs_setcapa
# define mio_ooecs_getlen mio_uecs_getlen
# define mio_ooecs_setlen mio_uecs_setlen
# define mio_ooecs_clear mio_uecs_clear
# define mio_ooecs_swap mio_uecs_swap
# define mio_ooecs_cpy mio_uecs_cpy
# define mio_ooecs_ncpy mio_uecs_ncpy
# define mio_ooecs_cat mio_uecs_cat
# define mio_ooecs_ncat mio_uecs_ncat
# define mio_ooecs_nrcat mio_uecs_nrcat
# define mio_ooecs_ccat mio_uecs_ccat
# define mio_ooecs_nccat mio_uecs_nccat
# define mio_ooecs_del mio_uecs_del
# define mio_ooecs_amend mio_uecs_amend
# define mio_ooecs_vfcat mio_uecs_vfcat
# define mio_ooecs_fcat mio_uecs_fcat
# define mio_ooecs_vfmt mio_uecs_vfmt
# define mio_ooecs_fmt mio_uecs_fmt
#else
# define mio_ooecs_open mio_becs_open
# define mio_ooecs_close mio_becs_close
# define mio_ooecs_init mio_becs_init
# define mio_ooecs_fini mio_becs_fini
# define mio_ooecs_getxtn mio_becs_getxtn
# define mio_ooecs_yield mio_becs_yield
# define mio_ooecs_yieldptr mio_becs_yieldptr
# define mio_ooecs_getsizer mio_becs_getsizer
# define mio_ooecs_setsizer mio_becs_setsizer
# define mio_ooecs_getcapa mio_becs_getcapa
# define mio_ooecs_setcapa mio_becs_setcapa
# define mio_ooecs_getlen mio_becs_getlen
# define mio_ooecs_setlen mio_becs_setlen
# define mio_ooecs_clear mio_becs_clear
# define mio_ooecs_swap mio_becs_swap
# define mio_ooecs_cpy mio_becs_cpy
# define mio_ooecs_ncpy mio_becs_ncpy
# define mio_ooecs_cat mio_becs_cat
# define mio_ooecs_ncat mio_becs_ncat
# define mio_ooecs_nrcat mio_becs_nrcat
# define mio_ooecs_ccat mio_becs_ccat
# define mio_ooecs_nccat mio_becs_nccat
# define mio_ooecs_del mio_becs_del
# define mio_ooecs_amend mio_becs_amend
# define mio_ooecs_vfcat mio_becs_vfcat
# define mio_ooecs_fcat mio_becs_fcat
# define mio_ooecs_vfmt mio_becs_vfmt
# define mio_ooecs_fmt mio_becs_fmt
#endif
MIO_EXPORT mio_oow_t mio_becs_ncatuchars (
mio_becs_t* str,
const mio_uch_t* s,
mio_oow_t len,
mio_cmgr_t* cmgr
);
MIO_EXPORT mio_oow_t mio_uecs_ncatbchars (
mio_uecs_t* str,
const mio_bch_t* s,
mio_oow_t len,
mio_cmgr_t* cmgr,
int all
);
#if defined(__cplusplus)
}
#endif
#endif

View File

@ -1,391 +0,0 @@
/*
* $Id$
*
Copyright (c) 2016-2020 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 WARRANTIES
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 _MIO_FMT_H_
#define _MIO_FMT_H_
#include <mio-cmn.h>
#include <stdarg.h>
/** \file
* This file defines various formatting functions.
*/
/* =========================================================================
* FORMATTED OUTPUT
* ========================================================================= */
typedef struct mio_fmtout_t mio_fmtout_t;
typedef int (*mio_fmtout_putbchars_t) (
mio_fmtout_t* fmtout,
const mio_bch_t* ptr,
mio_oow_t len
);
typedef int (*mio_fmtout_putuchars_t) (
mio_fmtout_t* fmtout,
const mio_uch_t* ptr,
mio_oow_t len
);
enum mio_fmtout_fmt_type_t
{
MIO_FMTOUT_FMT_TYPE_BCH = 0,
MIO_FMTOUT_FMT_TYPE_UCH
};
typedef enum mio_fmtout_fmt_type_t mio_fmtout_fmt_type_t;
struct mio_fmtout_t
{
mio_oow_t count; /* out */
mio_mmgr_t* mmgr; /* in */
mio_fmtout_putbchars_t putbchars; /* in */
mio_fmtout_putuchars_t putuchars; /* in */
mio_bitmask_t mask; /* in */
void* ctx; /* in */
/* internally set a input */
mio_fmtout_fmt_type_t fmt_type;
const void* fmt_str;
};
/* =========================================================================
* INTMAX FORMATTING
* ========================================================================= */
/**
* The mio_fmt_intmax_flag_t type defines enumerators to change the
* behavior of mio_fmt_intmax() and mio_fmt_uintmax().
*/
enum mio_fmt_intmax_flag_t
{
/* Use lower 6 bits to represent base between 2 and 36 inclusive.
* Upper bits are used for these flag options */
/** Don't truncate if the buffer is not large enough */
MIO_FMT_INTMAX_NOTRUNC = (0x40 << 0),
#define MIO_FMT_INTMAX_NOTRUNC MIO_FMT_INTMAX_NOTRUNC
#define MIO_FMT_UINTMAX_NOTRUNC MIO_FMT_INTMAX_NOTRUNC
#define MIO_FMT_INTMAX_TO_BCSTR_NOTRUNC MIO_FMT_INTMAX_NOTRUNC
#define MIO_FMT_UINTMAX_TO_BCSTR_NOTRUNC MIO_FMT_INTMAX_NOTRUNC
#define MIO_FMT_INTMAX_TO_UCSTR_NOTRUNC MIO_FMT_INTMAX_NOTRUNC
#define MIO_FMT_UINTMAX_TO_UCSTR_NOTRUNC MIO_FMT_INTMAX_NOTRUNC
#define MIO_FMT_INTMAX_TO_OOCSTR_NOTRUNC MIO_FMT_INTMAX_NOTRUNC
#define MIO_FMT_UINTMAX_TO_OOCSTR_NOTRUNC MIO_FMT_INTMAX_NOTRUNC
/** Don't append a terminating null */
MIO_FMT_INTMAX_NONULL = (0x40 << 1),
#define MIO_FMT_INTMAX_NONULL MIO_FMT_INTMAX_NONULL
#define MIO_FMT_UINTMAX_NONULL MIO_FMT_INTMAX_NONULL
#define MIO_FMT_INTMAX_TO_BCSTR_NONULL MIO_FMT_INTMAX_NONULL
#define MIO_FMT_UINTMAX_TO_BCSTR_NONULL MIO_FMT_INTMAX_NONULL
#define MIO_FMT_INTMAX_TO_UCSTR_NONULL MIO_FMT_INTMAX_NONULL
#define MIO_FMT_UINTMAX_TO_UCSTR_NONULL MIO_FMT_INTMAX_NONULL
#define MIO_FMT_INTMAX_TO_OOCSTR_NONULL MIO_FMT_INTMAX_NONULL
#define MIO_FMT_UINTMAX_TO_OOCSTR_NONULL MIO_FMT_INTMAX_NONULL
/** Produce no digit for a value of zero */
MIO_FMT_INTMAX_NOZERO = (0x40 << 2),
#define MIO_FMT_INTMAX_NOZERO MIO_FMT_INTMAX_NOZERO
#define MIO_FMT_UINTMAX_NOZERO MIO_FMT_INTMAX_NOZERO
#define MIO_FMT_INTMAX_TO_BCSTR_NOZERO MIO_FMT_INTMAX_NOZERO
#define MIO_FMT_UINTMAX_TO_BCSTR_NOZERO MIO_FMT_INTMAX_NOZERO
#define MIO_FMT_INTMAX_TO_UCSTR_NOZERO MIO_FMT_INTMAX_NOZERO
#define MIO_FMT_UINTMAX_TO_UCSTR_NOZERO MIO_FMT_INTMAX_NOZERO
#define MIO_FMT_INTMAX_TO_OOCSTR_NOZERO MIO_FMT_INTMAX_NOZERO
#define MIO_FMT_UINTMAX_TO_OOCSTR_NOZERO MIO_FMT_INTMAX_NOZERO
/** Produce a leading zero for a non-zero value */
MIO_FMT_INTMAX_ZEROLEAD = (0x40 << 3),
#define MIO_FMT_INTMAX_ZEROLEAD MIO_FMT_INTMAX_ZEROLEAD
#define MIO_FMT_UINTMAX_ZEROLEAD MIO_FMT_INTMAX_ZEROLEAD
#define MIO_FMT_INTMAX_TO_BCSTR_ZEROLEAD MIO_FMT_INTMAX_ZEROLEAD
#define MIO_FMT_UINTMAX_TO_BCSTR_ZEROLEAD MIO_FMT_INTMAX_ZEROLEAD
#define MIO_FMT_INTMAX_TO_UCSTR_ZEROLEAD MIO_FMT_INTMAX_ZEROLEAD
#define MIO_FMT_UINTMAX_TO_UCSTR_ZEROLEAD MIO_FMT_INTMAX_ZEROLEAD
#define MIO_FMT_INTMAX_TO_OOCSTR_ZEROLEAD MIO_FMT_INTMAX_ZEROLEAD
#define MIO_FMT_UINTMAX_TO_OOCSTR_ZEROLEAD MIO_FMT_INTMAX_ZEROLEAD
/** Use uppercase letters for alphabetic digits */
MIO_FMT_INTMAX_UPPERCASE = (0x40 << 4),
#define MIO_FMT_INTMAX_UPPERCASE MIO_FMT_INTMAX_UPPERCASE
#define MIO_FMT_UINTMAX_UPPERCASE MIO_FMT_INTMAX_UPPERCASE
#define MIO_FMT_INTMAX_TO_BCSTR_UPPERCASE MIO_FMT_INTMAX_UPPERCASE
#define MIO_FMT_UINTMAX_TO_BCSTR_UPPERCASE MIO_FMT_INTMAX_UPPERCASE
#define MIO_FMT_INTMAX_TO_UCSTR_UPPERCASE MIO_FMT_INTMAX_UPPERCASE
#define MIO_FMT_UINTMAX_TO_UCSTR_UPPERCASE MIO_FMT_INTMAX_UPPERCASE
#define MIO_FMT_INTMAX_TO_OOCSTR_UPPERCASE MIO_FMT_INTMAX_UPPERCASE
#define MIO_FMT_UINTMAX_TO_OOCSTR_UPPERCASE MIO_FMT_INTMAX_UPPERCASE
/** Insert a plus sign for a positive integer including 0 */
MIO_FMT_INTMAX_PLUSSIGN = (0x40 << 5),
#define MIO_FMT_INTMAX_PLUSSIGN MIO_FMT_INTMAX_PLUSSIGN
#define MIO_FMT_UINTMAX_PLUSSIGN MIO_FMT_INTMAX_PLUSSIGN
#define MIO_FMT_INTMAX_TO_BCSTR_PLUSSIGN MIO_FMT_INTMAX_PLUSSIGN
#define MIO_FMT_UINTMAX_TO_BCSTR_PLUSSIGN MIO_FMT_INTMAX_PLUSSIGN
#define MIO_FMT_INTMAX_TO_UCSTR_PLUSSIGN MIO_FMT_INTMAX_PLUSSIGN
#define MIO_FMT_UINTMAX_TO_UCSTR_PLUSSIGN MIO_FMT_INTMAX_PLUSSIGN
#define MIO_FMT_INTMAX_TO_OOCSTR_PLUSSIGN MIO_FMT_INTMAX_PLUSSIGN
#define MIO_FMT_UINTMAX_TO_OOCSTR_PLUSSIGN MIO_FMT_INTMAX_PLUSSIGN
/** Insert a space for a positive integer including 0 */
MIO_FMT_INTMAX_EMPTYSIGN = (0x40 << 6),
#define MIO_FMT_INTMAX_EMPTYSIGN MIO_FMT_INTMAX_EMPTYSIGN
#define MIO_FMT_UINTMAX_EMPTYSIGN MIO_FMT_INTMAX_EMPTYSIGN
#define MIO_FMT_INTMAX_TO_BCSTR_EMPTYSIGN MIO_FMT_INTMAX_EMPTYSIGN
#define MIO_FMT_UINTMAX_TO_BCSTR_EMPTYSIGN MIO_FMT_INTMAX_EMPTYSIGN
#define MIO_FMT_INTMAX_TO_UCSTR_EMPTYSIGN MIO_FMT_INTMAX_EMPTYSIGN
#define MIO_FMT_UINTMAX_TO_UCSTR_EMPTYSIGN MIO_FMT_INTMAX_EMPTYSIGN
/** Fill the right part of the string */
MIO_FMT_INTMAX_FILLRIGHT = (0x40 << 7),
#define MIO_FMT_INTMAX_FILLRIGHT MIO_FMT_INTMAX_FILLRIGHT
#define MIO_FMT_UINTMAX_FILLRIGHT MIO_FMT_INTMAX_FILLRIGHT
#define MIO_FMT_INTMAX_TO_BCSTR_FILLRIGHT MIO_FMT_INTMAX_FILLRIGHT
#define MIO_FMT_UINTMAX_TO_BCSTR_FILLRIGHT MIO_FMT_INTMAX_FILLRIGHT
#define MIO_FMT_INTMAX_TO_UCSTR_FILLRIGHT MIO_FMT_INTMAX_FILLRIGHT
#define MIO_FMT_UINTMAX_TO_UCSTR_FILLRIGHT MIO_FMT_INTMAX_FILLRIGHT
#define MIO_FMT_INTMAX_TO_OOCSTR_FILLRIGHT MIO_FMT_INTMAX_FILLRIGHT
#define MIO_FMT_UINTMAX_TO_OOCSTR_FILLRIGHT MIO_FMT_INTMAX_FILLRIGHT
/** Fill between the sign chacter and the digit part */
MIO_FMT_INTMAX_FILLCENTER = (0x40 << 8)
#define MIO_FMT_INTMAX_FILLCENTER MIO_FMT_INTMAX_FILLCENTER
#define MIO_FMT_UINTMAX_FILLCENTER MIO_FMT_INTMAX_FILLCENTER
#define MIO_FMT_INTMAX_TO_BCSTR_FILLCENTER MIO_FMT_INTMAX_FILLCENTER
#define MIO_FMT_UINTMAX_TO_BCSTR_FILLCENTER MIO_FMT_INTMAX_FILLCENTER
#define MIO_FMT_INTMAX_TO_UCSTR_FILLCENTER MIO_FMT_INTMAX_FILLCENTER
#define MIO_FMT_UINTMAX_TO_UCSTR_FILLCENTER MIO_FMT_INTMAX_FILLCENTER
#define MIO_FMT_INTMAX_TO_OOCSTR_FILLCENTER MIO_FMT_INTMAX_FILLCENTER
#define MIO_FMT_UINTMAX_TO_OOCSTR_FILLCENTER MIO_FMT_INTMAX_FILLCENTER
};
#if defined(__cplusplus)
extern "C" {
#endif
/* =========================================================================
* FORMATTED OUTPUT
* ========================================================================= */
MIO_EXPORT int mio_bfmt_outv (
mio_fmtout_t* fmtout,
const mio_bch_t* fmt,
va_list ap
);
MIO_EXPORT int mio_ufmt_outv (
mio_fmtout_t* fmtout,
const mio_uch_t* fmt,
va_list ap
);
MIO_EXPORT int mio_bfmt_out (
mio_fmtout_t* fmtout,
const mio_bch_t* fmt,
...
);
MIO_EXPORT int mio_ufmt_out (
mio_fmtout_t* fmtout,
const mio_uch_t* fmt,
...
);
/* =========================================================================
* INTMAX FORMATTING
* ========================================================================= */
/**
* The mio_fmt_intmax_to_bcstr() function formats an integer \a value to a
* multibyte string according to the given base and writes it to a buffer
* pointed to by \a buf. It writes to the buffer at most \a size characters
* including the terminating null. The base must be between 2 and 36 inclusive
* and can be ORed with zero or more #mio_fmt_intmax_to_bcstr_flag_t enumerators.
* This ORed value is passed to the function via the \a base_and_flags
* parameter. If the formatted string is shorter than \a bufsize, the redundant
* slots are filled with the fill character \a fillchar if it is not a null
* character. The filling behavior is determined by the flags shown below:
*
* - If #MIO_FMT_INTMAX_TO_BCSTR_FILLRIGHT is set in \a base_and_flags, slots
* after the formatting string are filled.
* - If #MIO_FMT_INTMAX_TO_BCSTR_FILLCENTER is set in \a base_and_flags, slots
* before the formatting string are filled. However, if it contains the
* sign character, the slots between the sign character and the digit part
* are filled.
* - If neither #MIO_FMT_INTMAX_TO_BCSTR_FILLRIGHT nor #MIO_FMT_INTMAX_TO_BCSTR_FILLCENTER
* , slots before the formatting string are filled.
*
* The \a precision parameter specified the minimum number of digits to
* produce from the \a value. If \a value produces fewer digits than
* \a precision, the actual digits are padded with '0' to meet the precision
* requirement. You can pass a negative number if you don't wish to specify
* precision.
*
* The terminating null is not added if #MIO_FMT_INTMAX_TO_BCSTR_NONULL is set;
* The #MIO_FMT_INTMAX_TO_BCSTR_UPPERCASE flag indicates that the function should
* use the uppercase letter for a alphabetic digit;
* You can set #MIO_FMT_INTMAX_TO_BCSTR_NOTRUNC if you require lossless formatting.
* The #MIO_FMT_INTMAX_TO_BCSTR_PLUSSIGN flag and #MIO_FMT_INTMAX_TO_BCSTR_EMPTYSIGN
* ensures that the plus sign and a space is added for a positive integer
* including 0 respectively.
* The #MIO_FMT_INTMAX_TO_BCSTR_ZEROLEAD flag ensures that the numeric string
* begins with '0' before applying the prefix.
* You can set the #MIO_FMT_INTMAX_TO_BCSTR_NOZERO flag if you want the value of
* 0 to produce nothing. If both #MIO_FMT_INTMAX_TO_BCSTR_NOZERO and
* #MIO_FMT_INTMAX_TO_BCSTR_ZEROLEAD are specified, '0' is still produced.
*
* If \a prefix is not #MIO_NULL, it is inserted before the digits.
*
* \return
* - -1 if the base is not between 2 and 36 inclusive.
* - negated number of characters required for lossless formatting
* - if \a bufsize is 0.
* - if #MIO_FMT_INTMAX_TO_BCSTR_NOTRUNC is set and \a bufsize is less than
* the minimum required for lossless formatting.
* - number of characters written to the buffer excluding a terminating
* null in all other cases.
*/
MIO_EXPORT int mio_fmt_intmax_to_bcstr (
mio_bch_t* buf, /**< buffer pointer */
int bufsize, /**< buffer size */
mio_intmax_t value, /**< integer to format */
int base_and_flags, /**< base ORed with flags */
int precision, /**< precision */
mio_bch_t fillchar, /**< fill character */
const mio_bch_t* prefix /**< prefix */
);
/**
* The mio_fmt_intmax_to_ucstr() function formats an integer \a value to a
* wide-character string according to the given base and writes it to a buffer
* pointed to by \a buf. It writes to the buffer at most \a size characters
* including the terminating null. The base must be between 2 and 36 inclusive
* and can be ORed with zero or more #mio_fmt_intmax_to_ucstr_flag_t enumerators.
* This ORed value is passed to the function via the \a base_and_flags
* parameter. If the formatted string is shorter than \a bufsize, the redundant
* slots are filled with the fill character \a fillchar if it is not a null
* character. The filling behavior is determined by the flags shown below:
*
* - If #MIO_FMT_INTMAX_TO_UCSTR_FILLRIGHT is set in \a base_and_flags, slots
* after the formatting string are filled.
* - If #MIO_FMT_INTMAX_TO_UCSTR_FILLCENTER is set in \a base_and_flags, slots
* before the formatting string are filled. However, if it contains the
* sign character, the slots between the sign character and the digit part
* are filled.
* - If neither #MIO_FMT_INTMAX_TO_UCSTR_FILLRIGHT nor #MIO_FMT_INTMAX_TO_UCSTR_FILLCENTER
* , slots before the formatting string are filled.
*
* The \a precision parameter specified the minimum number of digits to
* produce from the \ value. If \a value produces fewer digits than
* \a precision, the actual digits are padded with '0' to meet the precision
* requirement. You can pass a negative number if don't wish to specify
* precision.
*
* The terminating null is not added if #MIO_FMT_INTMAX_TO_UCSTR_NONULL is set;
* The #MIO_FMT_INTMAX_TO_UCSTR_UPPERCASE flag indicates that the function should
* use the uppercase letter for a alphabetic digit;
* You can set #MIO_FMT_INTMAX_TO_UCSTR_NOTRUNC if you require lossless formatting.
* The #MIO_FMT_INTMAX_TO_UCSTR_PLUSSIGN flag and #MIO_FMT_INTMAX_TO_UCSTR_EMPTYSIGN
* ensures that the plus sign and a space is added for a positive integer
* including 0 respectively.
* The #MIO_FMT_INTMAX_TO_UCSTR_ZEROLEAD flag ensures that the numeric string
* begins with 0 before applying the prefix.
* You can set the #MIO_FMT_INTMAX_TO_UCSTR_NOZERO flag if you want the value of
* 0 to produce nothing. If both #MIO_FMT_INTMAX_TO_UCSTR_NOZERO and
* #MIO_FMT_INTMAX_TO_UCSTR_ZEROLEAD are specified, '0' is still produced.
*
* If \a prefix is not #MIO_NULL, it is inserted before the digits.
*
* \return
* - -1 if the base is not between 2 and 36 inclusive.
* - negated number of characters required for lossless formatting
* - if \a bufsize is 0.
* - if #MIO_FMT_INTMAX_TO_UCSTR_NOTRUNC is set and \a bufsize is less than
* the minimum required for lossless formatting.
* - number of characters written to the buffer excluding a terminating
* null in all other cases.
*/
MIO_EXPORT int mio_fmt_intmax_to_ucstr (
mio_uch_t* buf, /**< buffer pointer */
int bufsize, /**< buffer size */
mio_intmax_t value, /**< integer to format */
int base_and_flags, /**< base ORed with flags */
int precision, /**< precision */
mio_uch_t fillchar, /**< fill character */
const mio_uch_t* prefix /**< prefix */
);
/**
* The mio_fmt_uintmax_to_bcstr() function formats an unsigned integer \a value
* to a multibyte string buffer. It behaves the same as mio_fmt_intmax_to_bcstr()
* except that it handles an unsigned integer.
*/
MIO_EXPORT int mio_fmt_uintmax_to_bcstr (
mio_bch_t* buf, /**< buffer pointer */
int bufsize, /**< buffer size */
mio_uintmax_t value, /**< integer to format */
int base_and_flags, /**< base ORed with flags */
int precision, /**< precision */
mio_bch_t fillchar, /**< fill character */
const mio_bch_t* prefix /**< prefix */
);
/**
* The mio_fmt_uintmax_to_ucstr() function formats an unsigned integer \a value
* to a unicode string buffer. It behaves the same as mio_fmt_intmax_to_ucstr()
* except that it handles an unsigned integer.
*/
MIO_EXPORT int mio_fmt_uintmax_to_ucstr (
mio_uch_t* buf, /**< buffer pointer */
int bufsize, /**< buffer size */
mio_uintmax_t value, /**< integer to format */
int base_and_flags, /**< base ORed with flags */
int precision, /**< precision */
mio_uch_t fillchar, /**< fill character */
const mio_uch_t* prefix /**< prefix */
);
#if defined(MIO_OOCH_IS_BCH)
# define mio_fmt_intmax_to_oocstr mio_fmt_intmax_to_bcstr
# define mio_fmt_uintmax_to_oocstr mio_fmt_uintmax_to_bcstr
#else
# define mio_fmt_intmax_to_oocstr mio_fmt_intmax_to_ucstr
# define mio_fmt_uintmax_to_oocstr mio_fmt_uintmax_to_ucstr
#endif
/* TODO: mio_fmt_fltmax_to_bcstr()... mio_fmt_fltmax_to_ucstr() */
#if defined(__cplusplus)
}
#endif
#endif

View File

@ -1,682 +0,0 @@
/*
* $Id$
*
Copyright (c) 2016-2020 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 WARRANTIES
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 _MIO_HTB_H_
#define _MIO_HTB_H_
#include <mio.h>
/**@file
* This file provides a hash table encapsulated in the #mio_htb_t type that
* maintains buckets for key/value pairs with the same key hash chained under
* the same bucket. Its interface is very close to #mio_rbt_t.
*
* This sample code adds a series of keys and values and print them
* in the randome order.
* @code
* #include <mio-htb.h>
*
* static mio_htb_walk_t walk (mio_htb_t* htb, mio_htb_pair_t* pair, void* ctx)
* {
* mio_printf (MIO_T("key = %d, value = %d\n"),
* *(int*)MIO_HTB_KPTR(pair), *(int*)MIO_HTB_VPTR(pair));
* return MIO_HTB_WALK_FORWARD;
* }
*
* int main ()
* {
* mio_htb_t* s1;
* int i;
*
* mio_open_stdsios ();
* s1 = mio_htb_open (MIO_MMGR_GETDFL(), 0, 30, 75, 1, 1); // error handling skipped
* mio_htb_setstyle (s1, mio_get_htb_style(MIO_HTB_STYLE_INLINE_COPIERS));
*
* for (i = 0; i < 20; i++)
* {
* int x = i * 20;
* mio_htb_insert (s1, &i, MIO_SIZEOF(i), &x, MIO_SIZEOF(x)); // eror handling skipped
* }
*
* mio_htb_walk (s1, walk, MIO_NULL);
*
* mio_htb_close (s1);
* mio_close_stdsios ();
* return 0;
* }
* @endcode
*/
typedef struct mio_htb_t mio_htb_t;
typedef struct mio_htb_pair_t mio_htb_pair_t;
/**
* The mio_htb_walk_t type defines values that the callback function can
* return to control mio_htb_walk().
*/
enum mio_htb_walk_t
{
MIO_HTB_WALK_STOP = 0,
MIO_HTB_WALK_FORWARD = 1
};
typedef enum mio_htb_walk_t mio_htb_walk_t;
/**
* The mio_htb_id_t type defines IDs to indicate a key or a value in various
* functions.
*/
enum mio_htb_id_t
{
MIO_HTB_KEY = 0,
MIO_HTB_VAL = 1
};
typedef enum mio_htb_id_t mio_htb_id_t;
/**
* The mio_htb_copier_t type defines a pair contruction callback.
* A special copier #MIO_HTB_COPIER_INLINE is provided. This copier enables
* you to copy the data inline to the internal node. No freeer is invoked
* when the node is freeed.
*/
typedef void* (*mio_htb_copier_t) (
mio_htb_t* htb /* hash table */,
void* dptr /* pointer to a key or a value */,
mio_oow_t dlen /* length of a key or a value */
);
/**
* The mio_htb_freeer_t defines a key/value destruction callback
* The freeer is called when a node containing the element is destroyed.
*/
typedef void (*mio_htb_freeer_t) (
mio_htb_t* htb, /**< hash table */
void* dptr, /**< pointer to a key or a value */
mio_oow_t dlen /**< length of a key or a value */
);
/**
* The mio_htb_comper_t type defines a key comparator that is called when
* the htb needs to compare keys. A hash table is created with a default
* comparator which performs bitwise comparison of two keys.
* The comparator should return 0 if the keys are the same and a non-zero
* integer otherwise.
*/
typedef int (*mio_htb_comper_t) (
const mio_htb_t* htb, /**< hash table */
const void* kptr1, /**< key pointer */
mio_oow_t klen1, /**< key length */
const void* kptr2, /**< key pointer */
mio_oow_t klen2 /**< key length */
);
/**
* The mio_htb_keeper_t type defines a value keeper that is called when
* a value is retained in the context that it should be destroyed because
* it is identical to a new value. Two values are identical if their
* pointers and lengths are equal.
*/
typedef void (*mio_htb_keeper_t) (
mio_htb_t* htb, /**< hash table */
void* vptr, /**< value pointer */
mio_oow_t vlen /**< value length */
);
/**
* The mio_htb_sizer_t type defines a bucket size claculator that is called
* when hash table should resize the bucket. The current bucket size + 1 is
* passed as the hint.
*/
typedef mio_oow_t (*mio_htb_sizer_t) (
mio_htb_t* htb, /**< htb */
mio_oow_t hint /**< sizing hint */
);
/**
* The mio_htb_hasher_t type defines a key hash function
*/
typedef mio_oow_t (*mio_htb_hasher_t) (
const mio_htb_t* htb, /**< hash table */
const void* kptr, /**< key pointer */
mio_oow_t klen /**< key length in bytes */
);
/**
* The mio_htb_walker_t defines a pair visitor.
*/
typedef mio_htb_walk_t (*mio_htb_walker_t) (
mio_htb_t* htb, /**< htb */
mio_htb_pair_t* pair, /**< pointer to a key/value pair */
void* ctx /**< pointer to user-defined data */
);
/**
* The mio_htb_cbserter_t type defines a callback function for mio_htb_cbsert().
* The mio_htb_cbserter() function calls it to allocate a new pair for the
* key pointed to by @a kptr of the length @a klen and the callback context
* @a ctx. The second parameter @a pair is passed the pointer to the existing
* pair for the key or #MIO_NULL in case of no existing key. The callback
* must return a pointer to a new or a reallocated pair. When reallocating the
* existing pair, this callback must destroy the existing pair and return the
* newly reallocated pair. It must return #MIO_NULL for failure.
*/
typedef mio_htb_pair_t* (*mio_htb_cbserter_t) (
mio_htb_t* htb, /**< hash table */
mio_htb_pair_t* pair, /**< pair pointer */
void* kptr, /**< key pointer */
mio_oow_t klen, /**< key length */
void* ctx /**< callback context */
);
/**
* The mio_htb_pair_t type defines hash table pair. A pair is composed of a key
* and a value. It maintains pointers to the beginning of a key and a value
* plus their length. The length is scaled down with the scale factor
* specified in an owning hash table.
*/
struct mio_htb_pair_t
{
mio_ptl_t key;
mio_ptl_t val;
/* management information below */
mio_htb_pair_t* next;
};
typedef struct mio_htb_style_t mio_htb_style_t;
struct mio_htb_style_t
{
mio_htb_copier_t copier[2];
mio_htb_freeer_t freeer[2];
mio_htb_comper_t comper; /**< key comparator */
mio_htb_keeper_t keeper; /**< value keeper */
mio_htb_sizer_t sizer; /**< bucket capacity recalculator */
mio_htb_hasher_t hasher; /**< key hasher */
};
/**
* The mio_htb_style_kind_t type defines the type of predefined
* callback set for pair manipulation.
*/
enum mio_htb_style_kind_t
{
/** store the key and the value pointer */
MIO_HTB_STYLE_DEFAULT,
/** copy both key and value into the pair */
MIO_HTB_STYLE_INLINE_COPIERS,
/** copy the key into the pair but store the value pointer */
MIO_HTB_STYLE_INLINE_KEY_COPIER,
/** copy the value into the pair but store the key pointer */
MIO_HTB_STYLE_INLINE_VALUE_COPIER
};
typedef enum mio_htb_style_kind_t mio_htb_style_kind_t;
/**
* The mio_htb_t type defines a hash table.
*/
struct mio_htb_t
{
mio_t* mio;
const mio_htb_style_t* style;
mio_uint8_t scale[2]; /**< length scale */
mio_uint8_t factor; /**< load factor in percentage */
mio_oow_t size;
mio_oow_t capa;
mio_oow_t threshold;
mio_htb_pair_t** bucket;
};
struct mio_htb_itr_t
{
mio_htb_pair_t* pair;
mio_oow_t buckno;
};
typedef struct mio_htb_itr_t mio_htb_itr_t;
/**
* The MIO_HTB_COPIER_SIMPLE macros defines a copier that remembers the
* pointer and length of data in a pair.
**/
#define MIO_HTB_COPIER_SIMPLE ((mio_htb_copier_t)1)
/**
* The MIO_HTB_COPIER_INLINE macros defines a copier that copies data into
* a pair.
**/
#define MIO_HTB_COPIER_INLINE ((mio_htb_copier_t)2)
#define MIO_HTB_COPIER_DEFAULT (MIO_HTB_COPIER_SIMPLE)
#define MIO_HTB_FREEER_DEFAULT (MIO_NULL)
#define MIO_HTB_COMPER_DEFAULT (mio_htb_dflcomp)
#define MIO_HTB_KEEPER_DEFAULT (MIO_NULL)
#define MIO_HTB_SIZER_DEFAULT (MIO_NULL)
#define MIO_HTB_HASHER_DEFAULT (mio_htb_dflhash)
/**
* The MIO_HTB_SIZE() macro returns the number of pairs in a hash table.
*/
#define MIO_HTB_SIZE(m) (*(const mio_oow_t*)&(m)->size)
/**
* The MIO_HTB_CAPA() macro returns the maximum number of pairs that can be
* stored in a hash table without further reorganization.
*/
#define MIO_HTB_CAPA(m) (*(const mio_oow_t*)&(m)->capa)
#define MIO_HTB_FACTOR(m) (*(const int*)&(m)->factor)
#define MIO_HTB_KSCALE(m) (*(const int*)&(m)->scale[MIO_HTB_KEY])
#define MIO_HTB_VSCALE(m) (*(const int*)&(m)->scale[MIO_HTB_VAL])
#define MIO_HTB_KPTL(p) (&(p)->key)
#define MIO_HTB_VPTL(p) (&(p)->val)
#define MIO_HTB_KPTR(p) ((p)->key.ptr)
#define MIO_HTB_KLEN(p) ((p)->key.len)
#define MIO_HTB_VPTR(p) ((p)->val.ptr)
#define MIO_HTB_VLEN(p) ((p)->val.len)
#define MIO_HTB_NEXT(p) ((p)->next)
#if defined(__cplusplus)
extern "C" {
#endif
/**
* The mio_get_htb_style() functions returns a predefined callback set for
* pair manipulation.
*/
MIO_EXPORT const mio_htb_style_t* mio_get_htb_style (
mio_htb_style_kind_t kind
);
/**
* The mio_htb_open() function creates a hash table with a dynamic array
* bucket and a list of values chained. The initial capacity should be larger
* than 0. The load factor should be between 0 and 100 inclusive and the load
* factor of 0 disables bucket resizing. If you need extra space associated
* with hash table, you may pass a non-zero value for @a xtnsize.
* The MIO_HTB_XTN() macro and the mio_htb_getxtn() function return the
* pointer to the beginning of the extension.
* The @a kscale and @a vscale parameters specify the unit of the key and
* value size.
* @return #mio_htb_t pointer on success, #MIO_NULL on failure.
*/
MIO_EXPORT mio_htb_t* mio_htb_open (
mio_t* mio,
mio_oow_t xtnsize, /**< extension size in bytes */
mio_oow_t capa, /**< initial capacity */
int factor, /**< load factor */
int kscale, /**< key scale - 1 to 255 */
int vscale /**< value scale - 1 to 255 */
);
/**
* The mio_htb_close() function destroys a hash table.
*/
MIO_EXPORT void mio_htb_close (
mio_htb_t* htb /**< hash table */
);
/**
* The mio_htb_init() function initializes a hash table
*/
MIO_EXPORT int mio_htb_init (
mio_htb_t* htb, /**< hash table */
mio_t* mio,
mio_oow_t capa, /**< initial capacity */
int factor, /**< load factor */
int kscale, /**< key scale */
int vscale /**< value scale */
);
/**
* The mio_htb_fini() funtion finalizes a hash table
*/
MIO_EXPORT void mio_htb_fini (
mio_htb_t* htb
);
#if defined(MIO_HAVE_INLINE)
static MIO_INLINE void* mio_htb_getxtn (mio_htb_t* htb) { return (void*)(htb + 1); }
#else
#define mio_htb_getxtn(htb) ((void*)((mio_htb_t*)(htb) + 1))
#endif
/**
* The mio_htb_getstyle() function gets manipulation callback function set.
*/
MIO_EXPORT const mio_htb_style_t* mio_htb_getstyle (
const mio_htb_t* htb /**< hash table */
);
/**
* The mio_htb_setstyle() function sets internal manipulation callback
* functions for data construction, destruction, resizing, hashing, etc.
* The callback structure pointed to by \a style must outlive the hash
* table pointed to by \a htb as the hash table doesn't copy the contents
* of the structure.
*/
MIO_EXPORT void mio_htb_setstyle (
mio_htb_t* htb, /**< hash table */
const mio_htb_style_t* style /**< callback function set */
);
/**
* The mio_htb_getsize() function gets the number of pairs in hash table.
*/
MIO_EXPORT mio_oow_t mio_htb_getsize (
const mio_htb_t* htb
);
/**
* The mio_htb_getcapa() function gets the number of slots allocated
* in a hash bucket.
*/
MIO_EXPORT mio_oow_t mio_htb_getcapa (
const mio_htb_t* htb /**< hash table */
);
/**
* The mio_htb_search() function searches a hash table to find a pair with a
* matching key. It returns the pointer to the pair found. If it fails
* to find one, it returns MIO_NULL.
* @return pointer to the pair with a maching key,
* or #MIO_NULL if no match is found.
*/
MIO_EXPORT mio_htb_pair_t* mio_htb_search (
const mio_htb_t* htb, /**< hash table */
const void* kptr, /**< key pointer */
mio_oow_t klen /**< key length */
);
/**
* The mio_htb_upsert() function searches a hash table for the pair with a
* matching key. If one is found, it updates the pair. Otherwise, it inserts
* a new pair with the key and value given. It returns the pointer to the
* pair updated or inserted.
* @return pointer to the updated or inserted pair on success,
* #MIO_NULL on failure.
*/
MIO_EXPORT mio_htb_pair_t* mio_htb_upsert (
mio_htb_t* htb, /**< hash table */
void* kptr, /**< key pointer */
mio_oow_t klen, /**< key length */
void* vptr, /**< value pointer */
mio_oow_t vlen /**< value length */
);
/**
* The mio_htb_ensert() function inserts a new pair with the key and the value
* given. If there exists a pair with the key given, the function returns
* the pair containing the key.
* @return pointer to a pair on success, #MIO_NULL on failure.
*/
MIO_EXPORT mio_htb_pair_t* mio_htb_ensert (
mio_htb_t* htb, /**< hash table */
void* kptr, /**< key pointer */
mio_oow_t klen, /**< key length */
void* vptr, /**< value pointer */
mio_oow_t vlen /**< value length */
);
/**
* The mio_htb_insert() function inserts a new pair with the key and the value
* given. If there exists a pair with the key given, the function returns
* #MIO_NULL without channging the value.
* @return pointer to the pair created on success, #MIO_NULL on failure.
*/
MIO_EXPORT mio_htb_pair_t* mio_htb_insert (
mio_htb_t* htb, /**< hash table */
void* kptr, /**< key pointer */
mio_oow_t klen, /**< key length */
void* vptr, /**< value pointer */
mio_oow_t vlen /**< value length */
);
/**
* The mio_htb_update() function updates the value of an existing pair
* with a matching key.
* @return pointer to the pair on success, #MIO_NULL on no matching pair
*/
MIO_EXPORT mio_htb_pair_t* mio_htb_update (
mio_htb_t* htb, /**< hash table */
void* kptr, /**< key pointer */
mio_oow_t klen, /**< key length */
void* vptr, /**< value pointer */
mio_oow_t vlen /**< value length */
);
/**
* The mio_htb_cbsert() function inserts a key/value pair by delegating pair
* allocation to a callback function. Depending on the callback function,
* it may behave like mio_htb_insert(), mio_htb_upsert(), mio_htb_update(),
* mio_htb_ensert(), or totally differently. The sample code below inserts
* a new pair if the key is not found and appends the new value to the
* existing value delimited by a comma if the key is found.
*
* @code
* #include <mio-htb.h>
*
* mio_htb_walk_t print_map_pair (mio_htb_t* map, mio_htb_pair_t* pair, void* ctx)
* {
* mio_printf (MIO_T("%.*s[%d] => %.*s[%d]\n"),
* MIO_HTB_KLEN(pair), MIO_HTB_KPTR(pair), (int)MIO_HTB_KLEN(pair),
* MIO_HTB_VLEN(pair), MIO_HTB_VPTR(pair), (int)MIO_HTB_VLEN(pair));
* return MIO_HTB_WALK_FORWARD;
* }
*
* mio_htb_pair_t* cbserter (
* mio_htb_t* htb, mio_htb_pair_t* pair,
* void* kptr, mio_oow_t klen, void* ctx)
* {
* mio_cstr_t* v = (mio_cstr_t*)ctx;
* if (pair == MIO_NULL)
* {
* // no existing key for the key
* return mio_htb_allocpair (htb, kptr, klen, v->ptr, v->len);
* }
* else
* {
* // a pair with the key exists.
* // in this sample, i will append the new value to the old value
* // separated by a comma
* mio_htb_pair_t* new_pair;
* mio_ooch_t comma = MIO_T(',');
* mio_uint8_t* vptr;
*
* // allocate a new pair, but without filling the actual value.
* // note vptr is given MIO_NULL for that purpose
* new_pair = mio_htb_allocpair (
* htb, kptr, klen, MIO_NULL, MIO_HTB_VLEN(pair) + 1 + v->len);
* if (new_pair == MIO_NULL) return MIO_NULL;
*
* // fill in the value space
* vptr = MIO_HTB_VPTR(new_pair);
* mio_memcpy (vptr, MIO_HTB_VPTR(pair), MIO_HTB_VLEN(pair)*MIO_SIZEOF(mio_ooch_t));
* vptr += MIO_HTB_VLEN(pair)*MIO_SIZEOF(mio_ooch_t);
* mio_memcpy (vptr, &comma, MIO_SIZEOF(mio_ooch_t));
* vptr += MIO_SIZEOF(mio_ooch_t);
* mio_memcpy (vptr, v->ptr, v->len*MIO_SIZEOF(mio_ooch_t));
*
* // this callback requires the old pair to be destroyed
* mio_htb_freepair (htb, pair);
*
* // return the new pair
* return new_pair;
* }
* }
*
* int main ()
* {
* mio_htb_t* s1;
* int i;
* mio_ooch_t* keys[] = { MIO_T("one"), MIO_T("two"), MIO_T("three") };
* mio_ooch_t* vals[] = { MIO_T("1"), MIO_T("2"), MIO_T("3"), MIO_T("4"), MIO_T("5") };
*
* mio_open_stdsios ();
* s1 = mio_htb_open (
* MIO_MMGR_GETDFL(), 0, 10, 70,
* MIO_SIZEOF(mio_ooch_t), MIO_SIZEOF(mio_ooch_t)
* ); // note error check is skipped
* mio_htb_setstyle (s1, mio_get_htb_style(MIO_HTB_STYLE_INLINE_COPIERS));
*
* for (i = 0; i < MIO_COUNTOF(vals); i++)
* {
* mio_cstr_t ctx;
* ctx.ptr = vals[i]; ctx.len = mio_count_oocstr(vals[i]);
* mio_htb_cbsert (s1,
* keys[i%MIO_COUNTOF(keys)], mio_count_oocstr(keys[i%MIO_COUNTOF(keys)]),
* cbserter, &ctx
* ); // note error check is skipped
* }
* mio_htb_walk (s1, print_map_pair, MIO_NULL);
*
* mio_htb_close (s1);
* mio_close_stdsios ();
* return 0;
* }
* @endcode
*/
MIO_EXPORT mio_htb_pair_t* mio_htb_cbsert (
mio_htb_t* htb, /**< hash table */
void* kptr, /**< key pointer */
mio_oow_t klen, /**< key length */
mio_htb_cbserter_t cbserter, /**< callback function */
void* ctx /**< callback context */
);
/**
* The mio_htb_delete() function deletes a pair with a matching key
* @return 0 on success, -1 on failure
*/
MIO_EXPORT int mio_htb_delete (
mio_htb_t* htb, /**< hash table */
const void* kptr, /**< key pointer */
mio_oow_t klen /**< key length */
);
/**
* The mio_htb_clear() function empties a hash table
*/
MIO_EXPORT void mio_htb_clear (
mio_htb_t* htb /**< hash table */
);
/**
* The mio_htb_walk() function traverses a hash table.
*/
MIO_EXPORT void mio_htb_walk (
mio_htb_t* htb, /**< hash table */
mio_htb_walker_t walker, /**< callback function for each pair */
void* ctx /**< pointer to user-specific data */
);
MIO_EXPORT void mio_init_htb_itr (
mio_htb_itr_t* itr
);
/**
* The mio_htb_getfirstpair() function returns the pointer to the first pair
* in a hash table.
*/
MIO_EXPORT mio_htb_pair_t* mio_htb_getfirstpair (
mio_htb_t* htb, /**< hash table */
mio_htb_itr_t* itr /**< iterator*/
);
/**
* The mio_htb_getnextpair() function returns the pointer to the next pair
* to the current pair @a pair in a hash table.
*/
MIO_EXPORT mio_htb_pair_t* mio_htb_getnextpair (
mio_htb_t* htb, /**< hash table */
mio_htb_itr_t* itr /**< iterator*/
);
/**
* The mio_htb_allocpair() function allocates a pair for a key and a value
* given. But it does not chain the pair allocated into the hash table @a htb.
* Use this function at your own risk.
*
* Take note of he following special behavior when the copier is
* #MIO_HTB_COPIER_INLINE.
* - If @a kptr is #MIO_NULL, the key space of the size @a klen is reserved but
* not propagated with any data.
* - If @a vptr is #MIO_NULL, the value space of the size @a vlen is reserved
* but not propagated with any data.
*/
MIO_EXPORT mio_htb_pair_t* mio_htb_allocpair (
mio_htb_t* htb,
void* kptr,
mio_oow_t klen,
void* vptr,
mio_oow_t vlen
);
/**
* The mio_htb_freepair() function destroys a pair. But it does not detach
* the pair destroyed from the hash table @a htb. Use this function at your
* own risk.
*/
MIO_EXPORT void mio_htb_freepair (
mio_htb_t* htb,
mio_htb_pair_t* pair
);
/**
* The mio_htb_dflhash() function is a default hash function.
*/
MIO_EXPORT mio_oow_t mio_htb_dflhash (
const mio_htb_t* htb,
const void* kptr,
mio_oow_t klen
);
/**
* The mio_htb_dflcomp() function is default comparator.
*/
MIO_EXPORT int mio_htb_dflcomp (
const mio_htb_t* htb,
const void* kptr1,
mio_oow_t klen1,
const void* kptr2,
mio_oow_t klen2
);
#if defined(__cplusplus)
}
#endif
#endif

View File

@ -1,214 +0,0 @@
/*
Copyright (c) 2016-2020 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 WARRANTIES
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 _MIO_HTRD_H_
#define _MIO_HTRD_H_
#include <mio-http.h>
#include <mio-htre.h>
typedef struct mio_htrd_t mio_htrd_t;
enum mio_htrd_errnum_t
{
MIO_HTRD_ENOERR,
MIO_HTRD_EOTHER,
MIO_HTRD_ENOIMPL,
MIO_HTRD_ESYSERR,
MIO_HTRD_EINTERN,
MIO_HTRD_ENOMEM,
MIO_HTRD_EBADRE,
MIO_HTRD_EBADHDR,
MIO_HTRD_ESUSPENDED
};
typedef enum mio_htrd_errnum_t mio_htrd_errnum_t;
/**
* The mio_htrd_option_t type defines various options to
* change the behavior of the mio_htrd_t reader.
*/
enum mio_htrd_option_t
{
MIO_HTRD_SKIP_EMPTY_LINES = ((mio_bitmask_t)1 << 0), /**< skip leading empty lines before the initial line */
MIO_HTRD_SKIP_INITIAL_LINE = ((mio_bitmask_t)1 << 1), /**< skip processing an initial line */
MIO_HTRD_CANONQPATH = ((mio_bitmask_t)1 << 2), /**< canonicalize the query path */
MIO_HTRD_REQUEST = ((mio_bitmask_t)1 << 3), /**< parse input as a request */
MIO_HTRD_RESPONSE = ((mio_bitmask_t)1 << 4), /**< parse input as a response */
MIO_HTRD_TRAILERS = ((mio_bitmask_t)1 << 5), /**< store trailers in a separate table */
MIO_HTRD_STRICT = ((mio_bitmask_t)1 << 6) /**< be more picky */
};
typedef enum mio_htrd_option_t mio_htrd_option_t;
typedef struct mio_htrd_recbs_t mio_htrd_recbs_t;
struct mio_htrd_recbs_t
{
int (*peek) (mio_htrd_t* htrd, mio_htre_t* re);
int (*poke) (mio_htrd_t* htrd, mio_htre_t* re);
int (*push_content) (mio_htrd_t* htrd, mio_htre_t* re, const mio_bch_t* data, mio_oow_t len);
};
struct mio_htrd_t
{
mio_t* mio;
mio_htrd_errnum_t errnum;
mio_bitmask_t option;
int flags;
mio_htrd_recbs_t recbs;
struct
{
struct
{
int flags;
int crlf; /* crlf status */
mio_oow_t plen; /* raw request length excluding crlf */
mio_oow_t need; /* number of octets needed for contents */
struct
{
mio_oow_t len;
mio_oow_t count;
int phase;
} chunk;
} s; /* state */
/* buffers needed for processing a request */
struct
{
mio_becs_t raw; /* buffer to hold raw octets */
mio_becs_t tra; /* buffer for handling trailers */
} b;
} fed;
mio_htre_t re;
int clean;
};
#if defined(__cplusplus)
extern "C" {
#endif
/**
* The mio_htrd_open() function creates a htrd processor.
*/
MIO_EXPORT mio_htrd_t* mio_htrd_open (
mio_t* mio, /**< memory manager */
mio_oow_t xtnsize /**< extension size in bytes */
);
/**
* The mio_htrd_close() function destroys a htrd processor.
*/
MIO_EXPORT void mio_htrd_close (
mio_htrd_t* htrd
);
MIO_EXPORT int mio_htrd_init (
mio_htrd_t* htrd,
mio_t* mio
);
MIO_EXPORT void mio_htrd_fini (
mio_htrd_t* htrd
);
#if defined(MIO_HAVE_INLINE)
static MIO_INLINE void* mio_htrd_getxtn (mio_htrd_t* htrd) { return (void*)(htrd + 1); }
#else
#define mio_htrd_getxtn(htrd) ((void*)((mio_htrd_t*)(htrd) + 1))
#endif
MIO_EXPORT mio_htrd_errnum_t mio_htrd_geterrnum (
mio_htrd_t* htrd
);
MIO_EXPORT void mio_htrd_clear (
mio_htrd_t* htrd
);
MIO_EXPORT mio_bitmask_t mio_htrd_getoption (
mio_htrd_t* htrd
);
MIO_EXPORT void mio_htrd_setoption (
mio_htrd_t* htrd,
mio_bitmask_t mask
);
MIO_EXPORT const mio_htrd_recbs_t* mio_htrd_getrecbs (
mio_htrd_t* htrd
);
MIO_EXPORT void mio_htrd_setrecbs (
mio_htrd_t* htrd,
const mio_htrd_recbs_t* recbs
);
/**
* The mio_htrd_feed() function accepts htrd request octets and invokes a
* callback function if it has processed a proper htrd request.
*/
MIO_EXPORT int mio_htrd_feed (
mio_htrd_t* htrd, /**< htrd */
const mio_bch_t* req, /**< request octets */
mio_oow_t len, /**< number of octets */
mio_oow_t* rem
);
/**
* The mio_htrd_halt() function indicates the end of feeeding
* if the current response should be processed until the
* connection is closed.
*/
MIO_EXPORT int mio_htrd_halt (
mio_htrd_t* htrd
);
MIO_EXPORT void mio_htrd_suspend (
mio_htrd_t* htrd
);
MIO_EXPORT void mio_htrd_resume (
mio_htrd_t* htrd
);
MIO_EXPORT void mio_htrd_dummify (
mio_htrd_t* htrd
);
MIO_EXPORT void mio_htrd_undummify (
mio_htrd_t* htrd
);
#if defined(__cplusplus)
}
#endif
#endif

View File

@ -1,324 +0,0 @@
/*
* $Id$
*
Copyright (c) 2016-2020 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 WARRANTIES
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 _MIO_HTRE_H_
#define _MIO_HTRE_H_
#include <mio-htb.h>
#include <mio-ecs.h>
/**
* The mio_http_version_t type defines http version.
*/
struct mio_http_version_t
{
short major; /**< major version */
short minor; /**< minor version */
};
typedef struct mio_http_version_t mio_http_version_t;
/**
* The mio_http_method_t type defines http methods .
*/
enum mio_http_method_t
{
MIO_HTTP_OTHER,
/* rfc 2616 */
MIO_HTTP_HEAD,
MIO_HTTP_GET,
MIO_HTTP_POST,
MIO_HTTP_PUT,
MIO_HTTP_DELETE,
MIO_HTTP_PATCH,
MIO_HTTP_OPTIONS,
MIO_HTTP_TRACE,
MIO_HTTP_CONNECT
#if 0
/* rfc 2518 */
MIO_HTTP_PROPFIND,
MIO_HTTP_PROPPATCH,
MIO_HTTP_MKCOL,
MIO_HTTP_COPY,
MIO_HTTP_MOVE,
MIO_HTTP_LOCK,
MIO_HTTP_UNLOCK,
/* rfc 3253 */
MIO_HTTP_VERSION_CONTROL,
MIO_HTTP_REPORT,
MIO_HTTP_CHECKOUT,
MIO_HTTP_CHECKIN,
MIO_HTTP_UNCHECKOUT,
MIO_HTTP_MKWORKSPACE,
MIO_HTTP_UPDATE,
MIO_HTTP_LABEL,
MIO_HTTP_MERGE,
MIO_HTTP_BASELINE_CONTROL,
MIO_HTTP_MKACTIVITY,
/* microsoft */
MIO_HTTP_BPROPFIND,
MIO_HTTP_BPROPPATCH,
MIO_HTTP_BCOPY,
MIO_HTTP_BDELETE,
MIO_HTTP_BMOVE,
MIO_HTTP_NOTIFY,
MIO_HTTP_POLL,
MIO_HTTP_SUBSCRIBE,
MIO_HTTP_UNSUBSCRIBE,
#endif
};
typedef enum mio_http_method_t mio_http_method_t;
/*
* You should not manipulate an object of the #mio_htre_t
* type directly since it's complex. Use #mio_htrd_t to
* create an object of the mio_htre_t type.
*/
/* header and contents of request/response */
typedef struct mio_htre_t mio_htre_t;
typedef struct mio_htre_hdrval_t mio_htre_hdrval_t;
enum mio_htre_state_t
{
MIO_HTRE_DISCARDED = (1 << 0), /** content has been discarded */
MIO_HTRE_COMPLETED = (1 << 1) /** complete content has been seen */
};
typedef enum mio_htre_state_t mio_htre_state_t;
typedef int (*mio_htre_concb_t) (
mio_htre_t* re,
const mio_bch_t* ptr,
mio_oow_t len,
void* ctx
);
struct mio_htre_hdrval_t
{
const mio_bch_t* ptr;
mio_oow_t len;
mio_htre_hdrval_t* next;
};
struct mio_htre_t
{
mio_t* mio;
enum
{
MIO_HTRE_Q,
MIO_HTRE_S
} type;
/* version */
mio_http_version_t version;
const mio_bch_t* verstr; /* version string include HTTP/ */
union
{
struct
{
struct
{
mio_http_method_t type;
const mio_bch_t* name;
} method;
mio_bcs_t path;
mio_bcs_t param;
mio_bcs_t anchor;
} q;
struct
{
struct
{
int val;
mio_bch_t* str;
} code;
mio_bch_t* mesg;
} s;
} u;
#define MIO_HTRE_ATTR_CHUNKED (1 << 0)
#define MIO_HTRE_ATTR_LENGTH (1 << 1)
#define MIO_HTRE_ATTR_KEEPALIVE (1 << 2)
#define MIO_HTRE_ATTR_EXPECT (1 << 3)
#define MIO_HTRE_ATTR_EXPECT100 (1 << 4)
#define MIO_HTRE_ATTR_PROXIED (1 << 5)
#define MIO_HTRE_QPATH_PERDEC (1 << 6) /* the qpath has been percent-decoded */
int flags;
/* original query path for a request.
* meaningful if MIO_HTRE_QPATH_PERDEC is set in the flags */
struct
{
mio_bch_t* buf; /* buffer pointer */
mio_oow_t capa; /* buffer capacity */
mio_bch_t* ptr;
mio_oow_t len;
} orgqpath;
/* special attributes derived from the header */
struct
{
mio_oow_t content_length;
const mio_bch_t* status; /* for cgi */
} attr;
/* header table */
mio_htb_t hdrtab;
mio_htb_t trailers;
/* content octets */
mio_becs_t content;
/* content callback */
mio_htre_concb_t concb;
void* concb_ctx;
/* bitwise-ORed of mio_htre_state_t */
int state;
};
#define mio_htre_getversion(re) (&((re)->version))
#define mio_htre_getmajorversion(re) ((re)->version.major)
#define mio_htre_getminorversion(re) ((re)->version.minor)
#define mio_htre_getverstr(re) ((re)->verstr)
#define mio_htre_getqmethodtype(re) ((re)->u.q.method.type)
#define mio_htre_getqmethodname(re) ((re)->u.q.method.name)
#define mio_htre_getqpath(re) ((re)->u.q.path.ptr)
#define mio_htre_getqparam(re) ((re)->u.q.param.ptr)
#define mio_htre_getqanchor(re) ((re)->u.q.anchor.ptr)
#define mio_htre_getorgqpath(re) ((re)->orgqpath.ptr)
#define mio_htre_getscodeval(re) ((re)->u.s.code.val)
#define mio_htre_getscodestr(re) ((re)->u.s.code.str)
#define mio_htre_getsmesg(re) ((re)->u.s.mesg)
#define mio_htre_getcontent(re) (&(re)->content)
#define mio_htre_getcontentbcs(re) MIO_BECS_BCS(&(re)->content)
#define mio_htre_getcontentptr(re) MIO_BECS_PTR(&(re)->content)
#define mio_htre_getcontentlen(re) MIO_BECS_LEN(&(re)->content)
typedef int (*mio_htre_header_walker_t) (
mio_htre_t* re,
const mio_bch_t* key,
const mio_htre_hdrval_t* val,
void* ctx
);
#if defined(__cplusplus)
extern "C" {
#endif
MIO_EXPORT int mio_htre_init (
mio_htre_t* re,
mio_t* mio
);
MIO_EXPORT void mio_htre_fini (
mio_htre_t* re
);
MIO_EXPORT void mio_htre_clear (
mio_htre_t* re
);
MIO_EXPORT const mio_htre_hdrval_t* mio_htre_getheaderval (
const mio_htre_t* re,
const mio_bch_t* key
);
MIO_EXPORT const mio_htre_hdrval_t* mio_htre_gettrailerval (
const mio_htre_t* re,
const mio_bch_t* key
);
MIO_EXPORT int mio_htre_walkheaders (
mio_htre_t* re,
mio_htre_header_walker_t walker,
void* ctx
);
MIO_EXPORT int mio_htre_walktrailers (
mio_htre_t* re,
mio_htre_header_walker_t walker,
void* ctx
);
/**
* The mio_htre_addcontent() function adds a content semgnet pointed to by
* @a ptr of @a len bytes to the content buffer. If @a re is already completed
* or discarded, this function returns 0 without adding the segment to the
* content buffer.
* @return 1 on success, -1 on failure, 0 if adding is skipped.
*/
MIO_EXPORT int mio_htre_addcontent (
mio_htre_t* re,
const mio_bch_t* ptr,
mio_oow_t len
);
MIO_EXPORT void mio_htre_completecontent (
mio_htre_t* re
);
MIO_EXPORT void mio_htre_discardcontent (
mio_htre_t* re
);
MIO_EXPORT void mio_htre_unsetconcb (
mio_htre_t* re
);
MIO_EXPORT void mio_htre_setconcb (
mio_htre_t* re,
mio_htre_concb_t concb,
void* ctx
);
MIO_EXPORT int mio_htre_perdecqpath (
mio_htre_t* req
);
MIO_EXPORT int mio_htre_getreqcontentlen (
mio_htre_t* req,
mio_oow_t* len
);
#if defined(__cplusplus)
}
#endif
#endif

View File

@ -1,346 +0,0 @@
/*
Copyright (c) 2016-2020 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 WARRANTIES
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 _MIO_HTTP_H_
#define _MIO_HTTP_H_
#include <mio-ecs.h>
#include <mio-sck.h>
#include <mio-htre.h>
#include <mio-thr.h>
/** \file
* This file provides basic data types and functions for the http protocol.
*/
enum mio_http_range_type_t
{
MIO_HTTP_RANGE_PROPER,
MIO_HTTP_RANGE_PREFIX,
MIO_HTTP_RANGE_SUFFIX
};
typedef enum mio_http_range_type_t mio_http_range_type_t;
/**
* The mio_http_range_t type defines a structure that can represent
* a value for the \b Range: http header.
*
* If type is #MIO_HTTP_RANGE_PREFIX, 'to' is meaningless and 'from' indicates
* the number of bytes from the start.
* - 500- => from the 501st bytes all the way to the back.
*
* If type is #MIO_HTTP_RANGE_SUFFIX, 'from' is meaningless and 'to' indicates
* the number of bytes from the back.
* - -500 => last 500 bytes
*
* If type is #MIO_HTTP_RANGE_PROPER, 'from' and 'to' represents a proper range
* where the value of 0 indicates the first byte. This doesn't require any
* adjustment.
* - 0-999 => first 1000 bytes
* - 99- => from the 100th bytes to the end.
*/
struct mio_http_range_t
{
mio_http_range_type_t type; /**< type indicator */
mio_foff_t from; /**< starting offset */
mio_foff_t to; /**< ending offset */
};
typedef struct mio_http_range_t mio_http_range_t;
enum mio_perenc_http_opt_t
{
MIO_PERENC_HTTP_KEEP_SLASH = (1 << 0)
};
typedef enum mio_perenc_http_opt_t mio_perenc_bcstr_opt_t;
/* -------------------------------------------------------------- */
typedef struct mio_svc_htts_t mio_svc_htts_t;
typedef struct mio_svc_httc_t mio_svc_httc_t;
/* -------------------------------------------------------------- */
typedef struct mio_svc_htts_rsrc_t mio_svc_htts_rsrc_t;
typedef void (*mio_svc_htts_rsrc_on_kill_t) (
mio_svc_htts_rsrc_t* rsrc
);
#define MIO_SVC_HTTS_RSRC_HEADER \
mio_svc_htts_t* htts; \
mio_oow_t rsrc_size; \
mio_oow_t rsrc_refcnt; \
mio_svc_htts_rsrc_on_kill_t rsrc_on_kill
struct mio_svc_htts_rsrc_t
{
MIO_SVC_HTTS_RSRC_HEADER;
};
#define MIO_SVC_HTTS_RSRC_ATTACH(rsrc, var) do { (var) = (rsrc); ++(rsrc)->rsrc_refcnt; } while(0)
#define MIO_SVC_HTTS_RSRC_DETACH(rsrc_var) do { if (--(rsrc_var)->rsrc_refcnt == 0) { mio_svc_htts_rsrc_t* __rsrc_tmp = (rsrc_var); (rsrc_var) = MIO_NULL; mio_svc_htts_rsrc_kill(__rsrc_tmp); } else { (rsrc_var) = MIO_NULL; } } while(0)
/* -------------------------------------------------------------- */
typedef int (*mio_svc_htts_proc_req_t) (
mio_svc_htts_t* htts,
mio_dev_sck_t* sck,
mio_htre_t* req
);
/* -------------------------------------------------------------- */
struct mio_svc_htts_thr_func_info_t
{
mio_t* mio;
mio_http_method_t req_method;
mio_http_version_t req_version;
mio_bch_t* req_path;
mio_bch_t* req_param;
int req_x_http_method_override; /* -1 or mio_http_method_t */
/* TODO: header table */
mio_skad_t client_addr;
mio_skad_t server_addr;
};
typedef struct mio_svc_htts_thr_func_info_t mio_svc_htts_thr_func_info_t;
typedef void (*mio_svc_htts_thr_func_t) (
mio_t* mio,
mio_dev_thr_iopair_t* iop,
mio_svc_htts_thr_func_info_t* info,
void* ctx
);
/* -------------------------------------------------------------- */
#if defined(__cplusplus)
extern "C" {
#endif
MIO_EXPORT int mio_comp_http_versions (
const mio_http_version_t* v1,
const mio_http_version_t* v2
);
MIO_EXPORT int mio_comp_http_version_numbers (
const mio_http_version_t* v1,
int v2_major,
int v2_minor
);
MIO_EXPORT const mio_bch_t* mio_http_status_to_bcstr (
int code
);
MIO_EXPORT const mio_bch_t* mio_http_method_to_bcstr (
mio_http_method_t type
);
MIO_EXPORT mio_http_method_t mio_bcstr_to_http_method (
const mio_bch_t* name
);
MIO_EXPORT mio_http_method_t mio_bchars_to_http_method (
const mio_bch_t* nameptr,
mio_oow_t namelen
);
MIO_EXPORT int mio_parse_http_range_bcstr (
const mio_bch_t* str,
mio_http_range_t* range
);
MIO_EXPORT int mio_parse_http_time_bcstr (
const mio_bch_t* str,
mio_ntime_t* nt
);
MIO_EXPORT mio_bch_t* mio_fmt_http_time_to_bcstr (
const mio_ntime_t* nt,
mio_bch_t* buf,
mio_oow_t bufsz
);
/**
* The mio_is_perenced_http_bcstr() function determines if the given string
* contains a valid percent-encoded sequence.
*/
MIO_EXPORT int mio_is_perenced_http_bcstr (
const mio_bch_t* str
);
/**
* The mio_perdec_http_bcstr() function performs percent-decoding over a string.
* The caller must ensure that the output buffer \a buf is large enough.
* If \a ndecs is not #MIO_NULL, it is set to the number of characters
* decoded. 0 means no characters in the input string required decoding
* \return the length of the output string.
*/
MIO_EXPORT mio_oow_t mio_perdec_http_bcstr (
const mio_bch_t* str,
mio_bch_t* buf,
mio_oow_t* ndecs
);
/**
* The mio_perdec_http_bcstr() function performs percent-decoding over a length-bound string.
* It doesn't insert the terminating null.
*/
MIO_EXPORT mio_oow_t mio_perdec_http_bcs (
const mio_bcs_t* str,
mio_bch_t* buf,
mio_oow_t* ndecs
);
/**
* The mio_perenc_http_bcstr() function performs percent-encoding over a string.
* The caller must ensure that the output buffer \a buf is large enough.
* If \a nencs is not #MIO_NULL, it is set to the number of characters
* encoded. 0 means no characters in the input string required encoding.
* \return the length of the output string.
*/
MIO_EXPORT mio_oow_t mio_perenc_http_bcstr (
int opt, /**< 0 or bitwise-OR'ed of #mio_perenc_http_bcstr_opt_t */
const mio_bch_t* str,
mio_bch_t* buf,
mio_oow_t* nencs
);
#if 0
/* TODO: rename this function according to the naming convension */
MIO_EXPORT mio_bch_t* mio_perenc_http_bcstrdup (
int opt, /**< 0 or bitwise-OR'ed of #mio_perenc_http_bcstr_opt_t */
const mio_bch_t* str,
mio_mmgr_t* mmgr
);
#endif
MIO_EXPORT int mio_scan_http_qparam (
mio_bch_t* qparam,
int (*qparamcb) (mio_bcs_t* key, mio_bcs_t* val, void* ctx),
void* ctx
);
/* ------------------------------------------------------------------------- */
/* HTTP SERVER SERVICE */
/* ------------------------------------------------------------------------- */
MIO_EXPORT mio_svc_htts_t* mio_svc_htts_start (
mio_t* mio,
mio_dev_sck_bind_t* sck_bind,
mio_svc_htts_proc_req_t proc_req
);
MIO_EXPORT void mio_svc_htts_stop (
mio_svc_htts_t* htts
);
#if defined(MIO_HAVE_INLINE)
static MIO_INLINE mio_t* mio_svc_htts_getmio(mio_svc_htts_t* svc) { return mio_svc_getmio((mio_svc_t*)svc); }
#else
# define mio_svc_htts_getmio(svc) mio_svc_getmio(svc)
#endif
MIO_EXPORT int mio_svc_htts_writetosidechan (
mio_svc_htts_t* htts,
const void* dptr,
mio_oow_t dlen
);
MIO_EXPORT int mio_svc_htts_setservernamewithbcstr (
mio_svc_htts_t* htts,
const mio_bch_t* server_name
);
MIO_EXPORT int mio_svc_htts_getsockaddr (
mio_svc_htts_t* htts,
mio_skad_t* skad
);
MIO_EXPORT int mio_svc_htts_docgi (
mio_svc_htts_t* htts,
mio_dev_sck_t* csck,
mio_htre_t* req,
const mio_bch_t* docroot,
const mio_bch_t* script
);
MIO_EXPORT int mio_svc_htts_dofile (
mio_svc_htts_t* htts,
mio_dev_sck_t* csck,
mio_htre_t* req,
const mio_bch_t* docroot,
const mio_bch_t* filepath,
const mio_bch_t* mime_type
);
MIO_EXPORT int mio_svc_htts_dothr (
mio_svc_htts_t* htts,
mio_dev_sck_t* csck,
mio_htre_t* req,
mio_svc_htts_thr_func_t func,
void* ctx
);
MIO_EXPORT int mio_svc_htts_dotxt (
mio_svc_htts_t* htts,
mio_dev_sck_t* csck,
mio_htre_t* req,
int status_code,
const mio_bch_t* content_type,
const mio_bch_t* content_text
);
MIO_EXPORT mio_svc_htts_rsrc_t* mio_svc_htts_rsrc_make (
mio_svc_htts_t* htts,
mio_oow_t rsrc_size,
mio_svc_htts_rsrc_on_kill_t on_kill
);
MIO_EXPORT void mio_svc_htts_rsrc_kill (
mio_svc_htts_rsrc_t* rsrc
);
MIO_EXPORT void mio_svc_htts_fmtgmtime (
mio_svc_htts_t* htts,
const mio_ntime_t* nt,
mio_bch_t* buf,
mio_oow_t len
);
MIO_EXPORT mio_bch_t* mio_svc_htts_dupmergepaths (
mio_svc_htts_t* htts,
const mio_bch_t* base,
const mio_bch_t* path
);
#if defined(__cplusplus)
}
#endif
#endif

View File

@ -1,396 +0,0 @@
/*
* $Id$
*
Copyright (c) 2016-2020 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 WARRANTIES
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 _MIO_JSON_H_
#define _MIO_JSON_H_
#include <mio.h>
/**
* The mio_json_t type defines a simple json parser.
*/
typedef struct mio_json_t mio_json_t;
/* ========================================================================= */
enum mio_json_state_t
{
MIO_JSON_STATE_START,
MIO_JSON_STATE_IN_ARRAY,
MIO_JSON_STATE_IN_OBJECT,
MIO_JSON_STATE_IN_WORD_VALUE,
MIO_JSON_STATE_IN_NUMERIC_VALUE,
MIO_JSON_STATE_IN_STRING_VALUE
};
typedef enum mio_json_state_t mio_json_state_t;
/* ========================================================================= */
enum mio_json_inst_t
{
MIO_JSON_INST_START_ARRAY,
MIO_JSON_INST_END_ARRAY,
MIO_JSON_INST_START_OBJECT,
MIO_JSON_INST_END_OBJECT,
MIO_JSON_INST_KEY,
MIO_JSON_INST_STRING,
MIO_JSON_INST_NUMBER,
MIO_JSON_INST_NIL,
MIO_JSON_INST_TRUE,
MIO_JSON_INST_FALSE,
};
typedef enum mio_json_inst_t mio_json_inst_t;
typedef int (*mio_json_instcb_t) (
mio_json_t* json,
mio_json_inst_t inst,
mio_oow_t level,
mio_oow_t index,
mio_json_state_t container_state,
const mio_oocs_t* str,
void* ctx
);
typedef struct mio_json_state_node_t mio_json_state_node_t;
struct mio_json_state_node_t
{
mio_json_state_t state;
mio_oow_t level;
mio_oow_t index;
int in_comment;
union
{
struct
{
int got_value;
} ia; /* in array */
struct
{
/* 0: ready to get key (at the beginning or got comma),
* 1: got key, 2: got colon, 3: got value */
int state;
} io; /* in object */
struct
{
int escaped;
int digit_count;
/* acc is always of unicode type to handle \u and \U.
* in the bch mode, it will get converted to a utf8 stream. */
mio_uch_t acc;
} sv;
struct
{
int escaped;
int digit_count;
/* for a character, no way to support the unicode character
* in the bch mode */
mio_ooch_t acc;
} cv;
struct
{
int progress;
} nv;
} u;
mio_json_state_node_t* next;
};
enum mio_json_option_t
{
/* allow an unquoted word as an object key */
MIO_JSON_PERMIT_WORD_KEY = ((mio_bitmask_t)1 << 0),
/* a comma as a separator is not mandatory */
MIO_JSON_OPTIONAL_COMMA = ((mio_bitmask_t)1 << 1),
/* support the line comment. the text beginning with # is a comment to the end of the line */
MIO_JSON_LINE_COMMENT = ((mio_bitmask_t)1 << 2)
};
typedef enum mio_json_option_t mio_json_option_t;
struct mio_json_t
{
mio_t* mio;
mio_json_instcb_t instcb;
void* rctx;
mio_bitmask_t option;
mio_json_state_node_t state_top;
mio_json_state_node_t* state_stack;
mio_oocs_t tok;
mio_oow_t tok_capa;
mio_oow_t tok_line;
mio_oow_t tok_col;
mio_oow_t c_line;
mio_oow_t c_col;
};
/* ========================================================================= */
typedef struct mio_jsonwr_t mio_jsonwr_t;
typedef int (*mio_jsonwr_writecb_t) (
mio_jsonwr_t* jsonwr,
const mio_bch_t* dptr,
mio_oow_t dlen,
void* ctx
);
typedef struct mio_jsonwr_state_node_t mio_jsonwr_state_node_t;
struct mio_jsonwr_state_node_t
{
mio_json_state_t state;
mio_oow_t level;
mio_oow_t index;
int obj_awaiting_val;
mio_jsonwr_state_node_t* next;
};
enum mio_jsonwr_flag_t
{
MIO_JSONWR_FLAG_PRETTY = (1 << 0)
};
typedef enum mio_jsonwr_flag_t mio_jsonwr_flag_t;
struct mio_jsonwr_t
{
mio_t* mio;
mio_jsonwr_writecb_t writecb;
mio_jsonwr_state_node_t state_top;
mio_jsonwr_state_node_t* state_stack;
int flags;
void* wctx;
mio_bch_t wbuf[8192];
mio_oow_t wbuf_len;
};
/* ========================================================================= */
#if defined(__cplusplus)
extern "C" {
#endif
MIO_EXPORT mio_json_t* mio_json_open (
mio_t* mio,
mio_oow_t xtnsize
);
MIO_EXPORT void mio_json_close (
mio_json_t* json
);
MIO_EXPORT int mio_json_init (
mio_json_t* json,
mio_t* mio
);
MIO_EXPORT void mio_json_fini (
mio_json_t* json
);
#if defined(MIO_HAVE_INLINE)
static MIO_INLINE mio_t* mio_json_getmio (mio_json_t* json) { return json->mio; }
#else
# define mio_json_getmio(json) (((mio_json_t*)(json))->mio)
#endif
#if defined(MIO_HAVE_INLINE)
static MIO_INLINE void* mio_json_getxtn (mio_json_t* json) { return (void*)(json + 1); }
#else
#define mio_json_getxtn(json) ((void*)((mio_json_t*)(json) + 1))
#endif
MIO_EXPORT mio_bitmask_t mio_json_getoption (
mio_json_t* json
);
MIO_EXPORT void mio_json_setoption (
mio_json_t* json,
mio_bitmask_t mask
);
MIO_EXPORT void mio_json_setinstcb (
mio_json_t* json,
mio_json_instcb_t instcb,
void* ctx
);
MIO_EXPORT mio_json_state_t mio_json_getstate (
mio_json_t* json
);
MIO_EXPORT void mio_json_resetstates (
mio_json_t* json
);
MIO_EXPORT void mio_json_resetfeedloc (
mio_json_t* json
);
/**
* The mio_json_feed() function processes the raw data.
*
* If stop_if_ever_complted is 0, it returns 0 on success. If the value pointed to by
* rem is greater 0 after the call, processing is not complete and more feeding is
* required. Incomplete feeding may be caused by incomplete byte sequences or incomplete
* json object.
*
* If stop_if_ever_completed is non-zero, it returns 0 upon incomplet byte sequence or
* incomplete json object. It returns 1 if it sees the first complete json object. It stores
* the size of remaning raw data in the memory pointed to by rem.
*
* The function returns -1 upon failure.
*/
MIO_EXPORT int mio_json_feed (
mio_json_t* json,
const void* ptr,
mio_oow_t len,
mio_oow_t* rem,
int stop_if_ever_completed
);
/* ========================================================================= */
MIO_EXPORT mio_jsonwr_t* mio_jsonwr_open (
mio_t* mio,
mio_oow_t xtnsize,
int flags
);
MIO_EXPORT void mio_jsonwr_close (
mio_jsonwr_t* jsonwr
);
MIO_EXPORT int mio_jsonwr_init (
mio_jsonwr_t* jsonwr,
mio_t* mio,
int flags
);
MIO_EXPORT void mio_jsonwr_fini (
mio_jsonwr_t* jsonwr
);
#if defined(MIO_HAVE_INLINE)
static MIO_INLINE mio_t* mio_jsonwr_getmio (mio_jsonwr_t* jsonwr) { return jsonwr->mio; }
#else
# define mio_jsonwr_getmio(jsonwr) (((mio_jsonwr_t*)(jsonwr))->mio)
#endif
#if defined(MIO_HAVE_INLINE)
static MIO_INLINE void* mio_jsonwr_getxtn (mio_jsonwr_t* jsonwr) { return (void*)(jsonwr + 1); }
#else
#define mio_jsonwr_getxtn(jsonwr) ((void*)((mio_jsonwr_t*)(jsonwr) + 1))
#endif
MIO_EXPORT void mio_jsonwr_setwritecb (
mio_jsonwr_t* jsonwr,
mio_jsonwr_writecb_t writecb,
void* ctx
);
MIO_EXPORT int mio_jsonwr_write (
mio_jsonwr_t* jsonwr,
mio_json_inst_t inst,
int is_uchars,
const void* dptr,
mio_oow_t dlen
);
#define mio_jsonwr_startarray(jsonwr) mio_jsonwr_write(jsonwr, MIO_JSON_INST_START_ARRAY, 0, MIO_NULL, 0)
#define mio_jsonwr_endarray(jsonwr) mio_jsonwr_write(jsonwr, MIO_JSON_INST_END_ARRAY, 0, MIO_NULL, 0)
#define mio_jsonwr_startobject(jsonwr) mio_jsonwr_write(jsonwr, MIO_JSON_INST_START_OBJECT, 0, MIO_NULL, 0)
#define mio_jsonwr_endobject(jsonwr) mio_jsonwr_write(jsonwr, MIO_JSON_INST_END_OBJECT, 0, MIO_NULL, 0)
#define mio_jsonwr_writenil(jsonwr) mio_jsonwr_write(jsonwr, MIO_JSON_INST_NIL, 0, MIO_NULL, 0)
#define mio_jsonwr_writetrue(jsonwr) mio_jsonwr_write(jsonwr, MIO_JSON_INST_TRUE, 0, MIO_NULL, 0)
#define mio_jsonwr_writefalse(jsonwr) mio_jsonwr_write(jsonwr, MIO_JSON_INST_FALSE, 0, MIO_NULL, 0)
#define mio_jsonwr_writekeywithuchars(jsonwr,dptr,dlen) mio_jsonwr_write(jsonwr, MIO_JSON_INST_KEY, 1, dptr, dlen)
#define mio_jsonwr_writekeywithbchars(jsonwr,dptr,dlen) mio_jsonwr_write(jsonwr, MIO_JSON_INST_KEY, 0, dptr, dlen)
#define mio_jsonwr_writekeywithucstr(jsonwr,dptr) mio_jsonwr_write(jsonwr, MIO_JSON_INST_KEY, 1, dptr, mio_count_ucstr(dptr))
#define mio_jsonwr_writekeywithbcstr(jsonwr,dptr) mio_jsonwr_write(jsonwr, MIO_JSON_INST_KEY, 0, dptr, mio_count_bcstr(dptr))
#define mio_jsonwr_writenumberwithuchars(jsonwr,dptr,dlen) mio_jsonwr_write(jsonwr, MIO_JSON_INST_NUMBER, 1, dptr, dlen)
#define mio_jsonwr_writenumberwithbchars(jsonwr,dptr,dlen) mio_jsonwr_write(jsonwr, MIO_JSON_INST_NUMBER, 0, dptr, dlen)
#define mio_jsonwr_writenumberwithucstr(jsonwr,dptr) mio_jsonwr_write(jsonwr, MIO_JSON_INST_NUMBER, 1, dptr, mio_count_ucstr(dptr))
#define mio_jsonwr_writenumberwithbcstr(jsonwr,dptr) mio_jsonwr_write(jsonwr, MIO_JSON_INST_NUMBER, 0, dptr, mio_count_bcstr(dptr))
#define mio_jsonwr_writestringwithuchars(jsonwr,dptr,dlen) mio_jsonwr_write(jsonwr, MIO_JSON_INST_STRING, 1, dptr, dlen)
#define mio_jsonwr_writestringwithbchars(jsonwr,dptr,dlen) mio_jsonwr_write(jsonwr, MIO_JSON_INST_STRING, 0, dptr, dlen)
#define mio_jsonwr_writestringwithucstr(jsonwr,dptr) mio_jsonwr_write(jsonwr, MIO_JSON_INST_STRING, 1, dptr, mio_count_ucstr(dptr))
#define mio_jsonwr_writestringwithbcstr(jsonwr,dptr) mio_jsonwr_write(jsonwr, MIO_JSON_INST_STRING, 0, dptr, mio_count_bcstr(dptr))
MIO_EXPORT int mio_jsonwr_writeintmax (
mio_jsonwr_t* jsonwr,
mio_intmax_t v
);
MIO_EXPORT int mio_jsonwr_writeuintmax (
mio_jsonwr_t* jsonwr,
mio_uintmax_t v
);
MIO_EXPORT int mio_jsonwr_writerawuchars (
mio_jsonwr_t* jsonwr,
const mio_uch_t* dptr,
mio_oow_t dlen
);
MIO_EXPORT int mio_jsonwr_writerawucstr (
mio_jsonwr_t* jsonwr,
const mio_uch_t* dptr
);
MIO_EXPORT int mio_jsonwr_writerawbchars (
mio_jsonwr_t* jsonwr,
const mio_bch_t* dptr,
mio_oow_t dlen
);
MIO_EXPORT int mio_jsonwr_writerawbcstr (
mio_jsonwr_t* jsonwr,
const mio_bch_t* dptr
);
#if defined(__cplusplus)
}
#endif
#endif

View File

@ -1,288 +0,0 @@
/*
* $Id$
*
Copyright (c) 2016-2020 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 PIPEVIDED 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, PIPECUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PIPEFITS; 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 _MIO_MAR_H_
#define _MIO_MAR_H_
#include <mio.h>
typedef struct mio_dev_mar_t mio_dev_mar_t;
enum mio_dev_mar_progress_t
{
MIO_DEV_MAR_INITIAL,
MIO_DEV_MAR_CONNECTING,
MIO_DEV_MAR_CONNECTED,
MIO_DEV_MAR_QUERY_STARTING,
MIO_DEV_MAR_QUERY_STARTED,
MIO_DEV_MAR_ROW_FETCHING,
MIO_DEV_MAR_ROW_FETCHED
};
typedef enum mio_dev_mar_progress_t mio_dev_mar_progress_t;
#define MIO_DEV_MAR_SET_PROGRESS(dev,value) ((dev)->progress = (value))
#define MIO_DEV_MAR_GET_PROGRESS(dev) ((dev)->progress)
typedef int (*mio_dev_mar_on_read_t) (
mio_dev_mar_t* dev,
const void* data,
mio_iolen_t len
);
typedef int (*mio_dev_mar_on_write_t) (
mio_dev_mar_t* dev,
mio_iolen_t wrlen,
void* wrctx
);
typedef void (*mio_dev_mar_on_connect_t) (
mio_dev_mar_t* dev
);
typedef void (*mio_dev_mar_on_disconnect_t) (
mio_dev_mar_t* dev
);
typedef void (*mio_dev_mar_on_query_started_t) (
mio_dev_mar_t* dev,
int mar_ret,
const mio_bch_t* mar_errmsg
);
typedef void (*mio_dev_mar_on_row_fetched_t) (
mio_dev_mar_t* dev,
void* row_data
);
struct mio_dev_mar_t
{
MIO_DEV_HEADER;
void* hnd;
void* res;
mio_dev_mar_progress_t progress;
unsigned int connected: 1;
unsigned int connected_deferred: 1;
unsigned int query_started_deferred: 1;
/*unsigned int query_started: 1;*/
unsigned int row_fetched_deferred: 1;
unsigned int broken: 1;
mio_syshnd_t broken_syshnd;
int row_wstatus;
void* row;
mio_dev_mar_on_read_t on_read;
mio_dev_mar_on_write_t on_write;
mio_dev_mar_on_connect_t on_connect;
mio_dev_mar_on_disconnect_t on_disconnect;
mio_dev_mar_on_query_started_t on_query_started;
mio_dev_mar_on_row_fetched_t on_row_fetched;
};
enum mio_dev_mar_make_flag_t
{
MIO_DEV_MAR_USE_TMOUT = (1 << 0)
};
typedef enum mio_dev_mar_make_flag_t mio_dev_mar_make_flag_t;
typedef struct mio_dev_mar_tmout_t mio_dev_mar_tmout_t;
struct mio_dev_mar_tmout_t
{
mio_ntime_t c;
mio_ntime_t r;
mio_ntime_t w;
};
typedef struct mio_dev_mar_make_t mio_dev_mar_make_t;
struct mio_dev_mar_make_t
{
int flags;
mio_dev_mar_tmout_t tmout;
mio_dev_mar_on_write_t on_write; /* mandatory */
mio_dev_mar_on_read_t on_read; /* mandatory */
mio_dev_mar_on_connect_t on_connect; /* optional */
mio_dev_mar_on_disconnect_t on_disconnect; /* optional */
mio_dev_mar_on_query_started_t on_query_started;
mio_dev_mar_on_row_fetched_t on_row_fetched;
};
typedef struct mio_dev_mar_connect_t mio_dev_mar_connect_t;
struct mio_dev_mar_connect_t
{
const mio_bch_t* host;
const mio_bch_t* username;
const mio_bch_t* password;
const mio_bch_t* dbname;
mio_uint16_t port;
};
enum mio_dev_mar_ioctl_cmd_t
{
MIO_DEV_MAR_CONNECT,
MIO_DEV_MAR_QUERY_WITH_BCS,
MIO_DEV_MAR_FETCH_ROW
};
typedef enum mio_dev_mar_ioctl_cmd_t mio_dev_mar_ioctl_cmd_t;
/* -------------------------------------------------------------- */
typedef struct mio_svc_marc_t mio_svc_marc_t;
typedef mio_dev_mar_connect_t mio_svc_marc_connect_t;
typedef mio_dev_mar_tmout_t mio_svc_marc_tmout_t;
enum mio_svc_marc_qtype_t
{
MIO_SVC_MARC_QTYPE_SELECT, /* SELECT, SHOW, ... */
MIO_SVC_MARC_QTYPE_ACTION /* UPDATE, INSERT, DELETE, ALTER ... */
};
typedef enum mio_svc_marc_qtype_t mio_svc_marc_qtype_t;
enum mio_svc_marc_rcode_t
{
MIO_SVC_MARC_RCODE_ROW, /* has row *- data is MYSQL_ROW */
MIO_SVC_MARC_RCODE_DONE, /* completed or no more row - data is NULL */
MIO_SVC_MARC_RCODE_ERROR /* query error - data is mio_sv_marc_dev_error_t* */
};
typedef enum mio_svc_marc_rcode_t mio_svc_marc_rcode_t;
struct mio_svc_marc_dev_error_t
{
int mar_errcode;
const mio_bch_t* mar_errmsg;
};
typedef struct mio_svc_marc_dev_error_t mio_svc_marc_dev_error_t;
typedef void (*mio_svc_marc_on_result_t) (
mio_svc_marc_t* marc,
mio_oow_t sid,
mio_svc_marc_rcode_t rcode,
void* data,
void* qctx
);
/* -------------------------------------------------------------- */
#ifdef __cplusplus
extern "C" {
#endif
MIO_EXPORT mio_dev_mar_t* mio_dev_mar_make (
mio_t* mio,
mio_oow_t xtnsize,
const mio_dev_mar_make_t* data
);
#if defined(MIO_HAVE_INLINE)
static MIO_INLINE mio_t* mio_dev_mar_getmio (mio_dev_mar_t* mar) { return mio_dev_getmio((mio_dev_t*)mar); }
#else
# define mio_dev_mar_getmio(mar) mio_dev_getmio(mar)
#endif
#if defined(MIO_HAVE_INLINE)
static MIO_INLINE void* mio_dev_mar_getxtn (mio_dev_mar_t* mar) { return (void*)(mar + 1); }
#else
# define mio_dev_mar_getxtn(mar) ((void*)(((mio_dev_mar_t*)mar) + 1))
#endif
MIO_EXPORT int mio_dev_mar_connect (
mio_dev_mar_t* mar,
mio_dev_mar_connect_t* ci
);
MIO_EXPORT int mio_dev_mar_querywithbchars (
mio_dev_mar_t* mar,
const mio_bch_t* qstr,
mio_oow_t qlen
);
MIO_EXPORT int mio_dev_mar_fetchrows (
mio_dev_mar_t* mar
);
#if defined(MIO_HAVE_INLINE)
static MIO_INLINE void mio_dev_mar_kill (mio_dev_mar_t* mar) { mio_dev_kill ((mio_dev_t*)mar); }
static MIO_INLINE void mio_dev_mar_halt (mio_dev_mar_t* mar) { mio_dev_halt ((mio_dev_t*)mar); }
#else
# define mio_dev_mar_kill(mar) mio_dev_kill((mio_dev_t*)mar)
# define mio_dev_mar_halt(mar) mio_dev_halt((mio_dev_t*)mar)
#endif
MIO_EXPORT mio_oow_t mio_dev_mar_escapebchars (
mio_dev_mar_t* dev,
const mio_bch_t* qstr,
mio_oow_t qlen,
mio_bch_t* buf
);
/* ------------------------------------------------------------------------- */
/* MARDB CLIENT SERVICE */
/* ------------------------------------------------------------------------- */
MIO_EXPORT mio_svc_marc_t* mio_svc_marc_start (
mio_t* mio,
const mio_svc_marc_connect_t* ci,
const mio_svc_marc_tmout_t* tmout
);
MIO_EXPORT void mio_svc_marc_stop (
mio_svc_marc_t* marc
);
#if defined(MIO_HAVE_INLINE)
static MIO_INLINE mio_t* mio_svc_marc_getmio(mio_svc_marc_t* svc) { return mio_svc_getmio((mio_svc_t*)svc); }
#else
# define mio_svc_marc_getmio(svc) mio_svc_getmio(svc)
#endif
MIO_EXPORT int mio_svc_marc_querywithbchars (
mio_svc_marc_t* marc,
mio_oow_t sid,
mio_svc_marc_qtype_t qtype,
const mio_bch_t* qptr,
mio_oow_t qlen,
mio_svc_marc_on_result_t on_result,
void* qctx
);
MIO_EXPORT mio_oow_t mio_svc_marc_escapebchars (
mio_svc_marc_t* marc,
const mio_bch_t* qstr,
mio_oow_t qlen,
mio_bch_t* buf
);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -1,160 +0,0 @@
/*
* $Id$
*
Copyright (c) 2016-2020 Chung, Hyung-Hwan. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted pipevided 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 repipeduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials pipevided with the distribution.
THIS SOFTWARE IS PIPEVIDED 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, PIPECUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PIPEFITS; 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 _MIO_PIPE_H_
#define _MIO_PIPE_H_
#include <mio.h>
enum mio_dev_pipe_sid_t
{
MIO_DEV_PIPE_MASTER = -1, /* no io occurs on this. used only in on_close() */
MIO_DEV_PIPE_IN = 0, /* input */
MIO_DEV_PIPE_OUT = 1 /* output */
};
typedef enum mio_dev_pipe_sid_t mio_dev_pipe_sid_t;
typedef struct mio_dev_pipe_t mio_dev_pipe_t;
typedef struct mio_dev_pipe_slave_t mio_dev_pipe_slave_t;
typedef int (*mio_dev_pipe_on_read_t) (
mio_dev_pipe_t* dev,
const void* data,
mio_iolen_t len
);
typedef int (*mio_dev_pipe_on_write_t) (
mio_dev_pipe_t* dev,
mio_iolen_t wrlen,
void* wrctx
);
typedef void (*mio_dev_pipe_on_close_t) (
mio_dev_pipe_t* dev,
mio_dev_pipe_sid_t sid
);
struct mio_dev_pipe_t
{
MIO_DEV_HEADER;
mio_dev_pipe_slave_t* slave[2];
int slave_count;
mio_dev_pipe_on_read_t on_read;
mio_dev_pipe_on_write_t on_write;
mio_dev_pipe_on_close_t on_close;
};
struct mio_dev_pipe_slave_t
{
MIO_DEV_HEADER;
mio_dev_pipe_sid_t id;
mio_syshnd_t pfd;
mio_dev_pipe_t* master; /* parent device */
};
typedef struct mio_dev_pipe_make_t mio_dev_pipe_make_t;
struct mio_dev_pipe_make_t
{
mio_dev_pipe_on_write_t on_write; /* mandatory */
mio_dev_pipe_on_read_t on_read; /* mandatory */
mio_dev_pipe_on_close_t on_close; /* optional */
};
enum mio_dev_pipe_ioctl_cmd_t
{
MIO_DEV_PIPE_CLOSE
};
typedef enum mio_dev_pipe_ioctl_cmd_t mio_dev_pipe_ioctl_cmd_t;
#ifdef __cplusplus
extern "C" {
#endif
MIO_EXPORT mio_dev_pipe_t* mio_dev_pipe_make (
mio_t* mio,
mio_oow_t xtnsize,
const mio_dev_pipe_make_t* data
);
#if defined(MIO_HAVE_INLINE)
static MIO_INLINE mio_t* mio_dev_pipe_getmio (mio_dev_pipe_t* pipe) { return mio_dev_getmio((mio_dev_t*)pipe); }
#else
# define mio_dev_pipe_getmio(pipe) mio_dev_getmio(pipe)
#endif
#if defined(MIO_HAVE_INLINE)
static MIO_INLINE void* mio_dev_pipe_getxtn (mio_dev_pipe_t* pipe) { return (void*)(pipe + 1); }
#else
# define mio_dev_pipe_getxtn(pipe) ((void*)(((mio_dev_pipe_t*)pipe) + 1))
#endif
MIO_EXPORT void mio_dev_pipe_kill (
mio_dev_pipe_t* pipe
);
MIO_EXPORT void mio_dev_pipe_halt (
mio_dev_pipe_t* pipe
);
MIO_EXPORT int mio_dev_pipe_read (
mio_dev_pipe_t* pipe,
int enabled
);
MIO_EXPORT int mio_dev_pipe_timedread (
mio_dev_pipe_t* pipe,
int enabled,
const mio_ntime_t* tmout
);
MIO_EXPORT int mio_dev_pipe_write (
mio_dev_pipe_t* pipe,
const void* data,
mio_iolen_t len,
void* wrctx
);
MIO_EXPORT int mio_dev_pipe_timedwrite (
mio_dev_pipe_t* pipe,
const void* data,
mio_iolen_t len,
const mio_ntime_t* tmout,
void* wrctx
);
MIO_EXPORT int mio_dev_pipe_close (
mio_dev_pipe_t* pipe,
mio_dev_pipe_sid_t sid
);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -1,212 +0,0 @@
/*
* $Id$
*
Copyright (c) 2016-2020 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 _MIO_PRO_H_
#define _MIO_PRO_H_
#include <mio.h>
enum mio_dev_pro_sid_t
{
MIO_DEV_PRO_MASTER = -1, /* no io occurs on this. used only in on_close() */
MIO_DEV_PRO_IN = 0, /* input of the child process */
MIO_DEV_PRO_OUT = 1, /* output of the child process */
MIO_DEV_PRO_ERR = 2 /* error output of the child process */
};
typedef enum mio_dev_pro_sid_t mio_dev_pro_sid_t;
typedef struct mio_dev_pro_t mio_dev_pro_t;
typedef struct mio_dev_pro_slave_t mio_dev_pro_slave_t;
typedef int (*mio_dev_pro_on_read_t) (
mio_dev_pro_t* dev,
mio_dev_pro_sid_t sid,
const void* data,
mio_iolen_t len
);
typedef int (*mio_dev_pro_on_write_t) (
mio_dev_pro_t* dev,
mio_iolen_t wrlen,
void* wrctx
);
typedef void (*mio_dev_pro_on_close_t) (
mio_dev_pro_t* dev,
mio_dev_pro_sid_t sid
);
typedef int (*mio_dev_pro_on_fork_t) (
mio_dev_pro_t* dev,
void* fork_ctx
);
struct mio_dev_pro_t
{
MIO_DEV_HEADER;
int flags;
mio_intptr_t child_pid;
mio_dev_pro_slave_t* slave[3];
int slave_count;
mio_dev_pro_on_read_t on_read;
mio_dev_pro_on_write_t on_write;
mio_dev_pro_on_close_t on_close;
mio_bch_t* mcmd;
};
struct mio_dev_pro_slave_t
{
MIO_DEV_HEADER;
mio_dev_pro_sid_t id;
mio_syshnd_t pfd;
mio_dev_pro_t* master; /* parent device */
};
enum mio_dev_pro_make_flag_t
{
MIO_DEV_PRO_WRITEIN = (1 << 0),
MIO_DEV_PRO_READOUT = (1 << 1),
MIO_DEV_PRO_READERR = (1 << 2),
MIO_DEV_PRO_ERRTOOUT = (1 << 3),
MIO_DEV_PRO_OUTTOERR = (1 << 4),
MIO_DEV_PRO_INTONUL = (1 << 5),
MIO_DEV_PRO_OUTTONUL = (1 << 6),
MIO_DEV_PRO_ERRTONUL = (1 << 7),
MIO_DEV_PRO_DROPIN = (1 << 8),
MIO_DEV_PRO_DROPOUT = (1 << 9),
MIO_DEV_PRO_DROPERR = (1 << 10),
MIO_DEV_PRO_SHELL = (1 << 13),
/* perform no waitpid() on a child process upon device destruction.
* you should set this flag if your application has automatic child
* process reaping enabled. for instance, SIGCHLD is set to SIG_IGN
* on POSIX.1-2001 compliant systems */
MIO_DEV_PRO_FORGET_CHILD = (1 << 14),
MIO_DEV_PRO_FORGET_DIEHARD_CHILD = (1 << 15)
};
typedef enum mio_dev_pro_make_flag_t mio_dev_pro_make_flag_t;
typedef struct mio_dev_pro_make_t mio_dev_pro_make_t;
struct mio_dev_pro_make_t
{
int flags; /**< bitwise-ORed of mio_dev_pro_make_flag_t enumerators */
const void* cmd;
mio_dev_pro_on_write_t on_write; /* mandatory */
mio_dev_pro_on_read_t on_read; /* mandatory */
mio_dev_pro_on_close_t on_close; /* optional */
mio_dev_pro_on_fork_t on_fork; /* optional */
void* fork_ctx;
};
enum mio_dev_pro_ioctl_cmd_t
{
MIO_DEV_PRO_CLOSE,
MIO_DEV_PRO_KILL_CHILD
};
typedef enum mio_dev_pro_ioctl_cmd_t mio_dev_pro_ioctl_cmd_t;
#ifdef __cplusplus
extern "C" {
#endif
MIO_EXPORT mio_dev_pro_t* mio_dev_pro_make (
mio_t* mio,
mio_oow_t xtnsize,
const mio_dev_pro_make_t* data
);
#if defined(MIO_HAVE_INLINE)
static MIO_INLINE mio_t* mio_dev_pro_getmio (mio_dev_pro_t* pro) { return mio_dev_getmio((mio_dev_t*)pro); }
#else
# define mio_dev_pro_getmio(pro) mio_dev_getmio(pro)
#endif
#if defined(MIO_HAVE_INLINE)
static MIO_INLINE void* mio_dev_pro_getxtn (mio_dev_pro_t* pro) { return (void*)(pro + 1); }
#else
# define mio_dev_pro_getxtn(pro) ((void*)(((mio_dev_pro_t*)pro) + 1))
#endif
MIO_EXPORT void mio_dev_pro_kill (
mio_dev_pro_t* pro
);
MIO_EXPORT void mio_dev_pro_halt (
mio_dev_pro_t* pro
);
MIO_EXPORT int mio_dev_pro_read (
mio_dev_pro_t* pro,
mio_dev_pro_sid_t sid, /**< either #MIO_DEV_PRO_OUT or #MIO_DEV_PRO_ERR */
int enabled
);
MIO_EXPORT int mio_dev_pro_timedread (
mio_dev_pro_t* pro,
mio_dev_pro_sid_t sid, /**< either #MIO_DEV_PRO_OUT or #MIO_DEV_PRO_ERR */
int enabled,
const mio_ntime_t* tmout
);
MIO_EXPORT int mio_dev_pro_write (
mio_dev_pro_t* pro,
const void* data,
mio_iolen_t len,
void* wrctx
);
MIO_EXPORT int mio_dev_pro_timedwrite (
mio_dev_pro_t* pro,
const void* data,
mio_iolen_t len,
const mio_ntime_t* tmout,
void* wrctx
);
MIO_EXPORT int mio_dev_pro_close (
mio_dev_pro_t* pro,
mio_dev_pro_sid_t sid
);
MIO_EXPORT int mio_dev_pro_killchild (
mio_dev_pro_t* pro
);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -1,618 +0,0 @@
/*
* $Id$
*
Copyright (c) 2016-2020 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 _MIO_SCK_H_
#define _MIO_SCK_H_
#include <mio.h>
#include <mio-skad.h>
/* ========================================================================= */
/* TOOD: move these to a separate file */
#define MIO_ETHHDR_PROTO_IP4 0x0800
#define MIO_ETHHDR_PROTO_ARP 0x0806
#define MIO_ETHHDR_PROTO_8021Q 0x8100 /* 802.1Q VLAN */
#define MIO_ETHHDR_PROTO_IP6 0x86DD
#define MIO_ARPHDR_OPCODE_REQUEST 1
#define MIO_ARPHDR_OPCODE_REPLY 2
#define MIO_ARPHDR_HTYPE_ETH 0x0001
#define MIO_ARPHDR_PTYPE_IP4 0x0800
#include <mio-pac1.h>
struct MIO_PACKED mio_ethhdr_t
{
mio_uint8_t dest[MIO_ETHAD_LEN];
mio_uint8_t source[MIO_ETHAD_LEN];
mio_uint16_t proto;
};
typedef struct mio_ethhdr_t mio_ethhdr_t;
struct MIO_PACKED mio_arphdr_t
{
mio_uint16_t htype; /* hardware type (ethernet: 0x0001) */
mio_uint16_t ptype; /* protocol type (ipv4: 0x0800) */
mio_uint8_t hlen; /* hardware address length (ethernet: 6) */
mio_uint8_t plen; /* protocol address length (ipv4 :4) */
mio_uint16_t opcode; /* operation code */
};
typedef struct mio_arphdr_t mio_arphdr_t;
/* arp payload for ipv4 over ethernet */
struct MIO_PACKED mio_etharp_t
{
mio_uint8_t sha[MIO_ETHAD_LEN]; /* source hardware address */
mio_uint8_t spa[MIO_IP4AD_LEN]; /* source protocol address */
mio_uint8_t tha[MIO_ETHAD_LEN]; /* target hardware address */
mio_uint8_t tpa[MIO_IP4AD_LEN]; /* target protocol address */
};
typedef struct mio_etharp_t mio_etharp_t;
struct MIO_PACKED mio_etharp_pkt_t
{
mio_ethhdr_t ethhdr;
mio_arphdr_t arphdr;
mio_etharp_t arppld;
};
typedef struct mio_etharp_pkt_t mio_etharp_pkt_t;
struct mio_iphdr_t
{
#if defined(MIO_ENDIAN_LITTLE)
mio_uint8_t ihl:4;
mio_uint8_t version:4;
#elif defined(MIO_ENDIAN_BIG)
mio_uint8_t version:4;
mio_uint8_t ihl:4;
#else
# UNSUPPORTED ENDIAN
#endif
mio_int8_t tos;
mio_int16_t tot_len;
mio_int16_t id;
mio_int16_t frag_off;
mio_int8_t ttl;
mio_int8_t protocol;
mio_int16_t check;
mio_int32_t saddr;
mio_int32_t daddr;
/*The options start here. */
};
typedef struct mio_iphdr_t mio_iphdr_t;
struct MIO_PACKED mio_icmphdr_t
{
mio_uint8_t type; /* message type */
mio_uint8_t code; /* subcode */
mio_uint16_t checksum;
union
{
struct
{
mio_uint16_t id;
mio_uint16_t seq;
} echo;
mio_uint32_t gateway;
struct
{
mio_uint16_t frag_unused;
mio_uint16_t mtu;
} frag; /* path mut discovery */
} u;
};
typedef struct mio_icmphdr_t mio_icmphdr_t;
#include <mio-upac.h>
/* ICMP types */
#define MIO_ICMP_ECHO_REPLY 0
#define MIO_ICMP_UNREACH 3 /* destination unreachable */
#define MIO_ICMP_SOURCE_QUENCE 4
#define MIO_ICMP_REDIRECT 5
#define MIO_ICMP_ECHO_REQUEST 8
#define MIO_ICMP_TIME_EXCEEDED 11
#define MIO_ICMP_PARAM_PROBLEM 12
#define MIO_ICMP_TIMESTAMP_REQUEST 13
#define MIO_ICMP_TIMESTAMP_REPLY 14
#define MIO_ICMP_INFO_REQUEST 15
#define MIO_ICMP_INFO_REPLY 16
#define MIO_ICMP_ADDR_MASK_REQUEST 17
#define MIO_ICMP_ADDR_MASK_REPLY 18
/* Subcode for MIO_ICMP_UNREACH */
#define MIO_ICMP_UNREACH_NET 0
#define MIO_ICMP_UNREACH_HOST 1
#define MIO_ICMP_UNREACH_PROTOCOL 2
#define MIO_ICMP_UNREACH_PORT 3
#define MIO_ICMP_UNREACH_FRAG_NEEDED 4
/* Subcode for MIO_ICMP_REDIRECT */
#define MIO_ICMP_REDIRECT_NET 0
#define MIO_ICMP_REDIRECT_HOST 1
#define MIO_ICMP_REDIRECT_NETTOS 2
#define MIO_ICMP_REDIRECT_HOSTTOS 3
/* Subcode for MIO_ICMP_TIME_EXCEEDED */
#define MIO_ICMP_TIME_EXCEEDED_TTL 0
#define MIO_ICMP_TIME_EXCEEDED_FRAGTIME 1
/* ========================================================================= */
#if (MIO_SIZEOF_SOCKLEN_T == MIO_SIZEOF_INT)
#if defined(MIO_SOCKLEN_T_IS_SIGNED)
typedef int mio_scklen_t;
#else
typedef unsigned int mio_scklen_t;
#endif
#elif (MIO_SIZEOF_SOCKLEN_T == MIO_SIZEOF_LONG)
#if defined(MIO_SOCKLEN_T_IS_SIGNED)
typedef long mio_scklen_t;
#else
typedef unsigned long mio_scklen_t;
#endif
#else
typedef int mio_scklen_t;
#endif
/* ========================================================================= */
enum mio_dev_sck_ioctl_cmd_t
{
MIO_DEV_SCK_BIND,
MIO_DEV_SCK_CONNECT,
MIO_DEV_SCK_LISTEN
};
typedef enum mio_dev_sck_ioctl_cmd_t mio_dev_sck_ioctl_cmd_t;
#define MIO_DEV_SCK_SET_PROGRESS(dev,bit) do { \
(dev)->state &= ~MIO_DEV_SCK_ALL_PROGRESS_BITS; \
(dev)->state |= (bit); \
} while(0)
#define MIO_DEV_SCK_GET_PROGRESS(dev) ((dev)->state & MIO_DEV_SCK_ALL_PROGRESS_BITS)
enum mio_dev_sck_state_t
{
/* the following items(progress bits) are mutually exclusive */
MIO_DEV_SCK_CONNECTING = (1 << 0),
MIO_DEV_SCK_CONNECTING_SSL = (1 << 1),
MIO_DEV_SCK_CONNECTED = (1 << 2),
MIO_DEV_SCK_LISTENING = (1 << 3),
MIO_DEV_SCK_ACCEPTING_SSL = (1 << 4),
MIO_DEV_SCK_ACCEPTED = (1 << 5),
/* the following items can be bitwise-ORed with an exclusive item above */
MIO_DEV_SCK_LENIENT = (1 << 14),
MIO_DEV_SCK_INTERCEPTED = (1 << 15),
/* convenience bit masks */
MIO_DEV_SCK_ALL_PROGRESS_BITS = (MIO_DEV_SCK_CONNECTING |
MIO_DEV_SCK_CONNECTING_SSL |
MIO_DEV_SCK_CONNECTED |
MIO_DEV_SCK_LISTENING |
MIO_DEV_SCK_ACCEPTING_SSL |
MIO_DEV_SCK_ACCEPTED)
};
typedef enum mio_dev_sck_state_t mio_dev_sck_state_t;
typedef struct mio_dev_sck_t mio_dev_sck_t;
typedef int (*mio_dev_sck_on_read_t) (
mio_dev_sck_t* dev,
const void* data,
mio_iolen_t dlen,
const mio_skad_t* srcaddr
);
typedef int (*mio_dev_sck_on_write_t) (
mio_dev_sck_t* dev,
mio_iolen_t wrlen,
void* wrctx,
const mio_skad_t* dstaddr
);
typedef void (*mio_dev_sck_on_disconnect_t) (
mio_dev_sck_t* dev
);
typedef void (*mio_dev_sck_on_connect_t) (
mio_dev_sck_t* dev
);
typedef void (*mio_dev_sck_on_raw_accept_t) (
mio_dev_sck_t* dev,
mio_syshnd_t syshnd,
mio_skad_t* peeradr
);
enum mio_dev_sck_type_t
{
MIO_DEV_SCK_QX,
MIO_DEV_SCK_TCP4,
MIO_DEV_SCK_TCP6,
MIO_DEV_SCK_UDP4,
MIO_DEV_SCK_UDP6,
/* ICMP at the IPv4 layer */
MIO_DEV_SCK_ICMP4,
/* ICMP at the IPv6 layer */
MIO_DEV_SCK_ICMP6,
/* ARP at the ethernet layer */
MIO_DEV_SCK_ARP,
MIO_DEV_SCK_ARP_DGRAM,
/* raw L2-level packet */
MIO_DEV_SCK_PACKET,
/* bpf socket */
MIO_DEV_SCK_BPF
};
typedef enum mio_dev_sck_type_t mio_dev_sck_type_t;
enum mio_dev_sck_make_option_t
{
/* for now, accept failure doesn't affect the listing socket if this is set */
MIO_DEV_SCK_MAKE_LENIENT = (1 << 0)
};
typedef enum mio_dev_sck_make_option_t mio_dev_sck_make_option_t;
typedef struct mio_dev_sck_make_t mio_dev_sck_make_t;
struct mio_dev_sck_make_t
{
mio_dev_sck_type_t type;
int options;
mio_syshnd_t syshnd;
mio_dev_sck_on_write_t on_write;
mio_dev_sck_on_read_t on_read;
mio_dev_sck_on_connect_t on_connect;
mio_dev_sck_on_disconnect_t on_disconnect;
mio_dev_sck_on_raw_accept_t on_raw_accept; /* optional */
};
enum mio_dev_sck_bind_option_t
{
MIO_DEV_SCK_BIND_BROADCAST = (1 << 0),
MIO_DEV_SCK_BIND_REUSEADDR = (1 << 1),
MIO_DEV_SCK_BIND_REUSEPORT = (1 << 2),
MIO_DEV_SCK_BIND_TRANSPARENT = (1 << 3),
/* TODO: more options --- SO_RCVBUF, SO_SNDBUF, SO_RCVTIMEO, SO_SNDTIMEO, SO_KEEPALIVE */
/* BINDTODEVICE??? */
MIO_DEV_SCK_BIND_IGNERR = (1 << 14), /* ignore non-critical error in binding */
MIO_DEV_SCK_BIND_SSL = (1 << 15)
};
typedef enum mio_dev_sck_bind_option_t mio_dev_sck_bind_option_t;
typedef struct mio_dev_sck_bind_t mio_dev_sck_bind_t;
struct mio_dev_sck_bind_t
{
int options; /** 0 or bitwise-OR'ed of mio_dev_sck_bind_option_t enumerators */
mio_skad_t localaddr;
/* TODO: add device name for BIND_TO_DEVICE */
const mio_bch_t* ssl_certfile;
const mio_bch_t* ssl_keyfile;
};
enum mio_dev_sck_connect_option_t
{
MIO_DEV_SCK_CONNECT_SSL = (1 << 15)
};
typedef enum mio_dev_sck_connect_option_t mio_dev_sck_connect_option_t;
typedef struct mio_dev_sck_connect_t mio_dev_sck_connect_t;
struct mio_dev_sck_connect_t
{
int options;
mio_skad_t remoteaddr;
mio_ntime_t connect_tmout;
};
#if 0
enum mio_dev_sck_listen_option_t
{
};
typedef enum mio_dev_sck_listen_option_t mio_dev_sck_listen_option_t;
#endif
typedef struct mio_dev_sck_listen_t mio_dev_sck_listen_t;
struct mio_dev_sck_listen_t
{
int options; /* no options as of now. set it to 0 */
int backlogs;
mio_ntime_t accept_tmout;
};
struct mio_dev_sck_t
{
MIO_DEV_HEADER;
mio_dev_sck_type_t type;
mio_syshnd_t hnd;
int state;
/* remote peer address for a stateful stream socket. valid if one of the
* followings is set in state:
* MIO_DEV_TCP_ACCEPTING_SSL
* MIO_DEV_TCP_ACCEPTED
* MIO_DEV_TCP_CONNECTED
* MIO_DEV_TCP_CONNECTING
* MIO_DEV_TCP_CONNECTING_SSL
*
* also used as a placeholder to store source address for
* a stateless socket */
mio_skad_t remoteaddr;
/* local socket address */
mio_skad_t localaddr;
/* original destination address */
mio_skad_t orgdstaddr;
mio_dev_sck_on_write_t on_write;
mio_dev_sck_on_read_t on_read;
/* called on a new tcp device for an accepted client or
* on a tcp device conntected to a remote server */
mio_dev_sck_on_connect_t on_connect;
mio_dev_sck_on_disconnect_t on_disconnect;
mio_dev_sck_on_raw_accept_t on_raw_accept;
/* timer job index for handling
* - connect() timeout for a connecting socket.
* - SSL_accept() timeout for a socket accepting SSL */
mio_tmridx_t tmrjob_index;
/* connect timeout, ssl-connect timeout, ssl-accept timeout.
* it denotes timeout duration under some circumstances
* or an absolute expiry time under some other circumstances. */
mio_ntime_t tmout;
void* ssl_ctx;
void* ssl;
mio_syshnd_t side_chan; /* side-channel for MIO_DEV_SCK_QX */
};
enum mio_dev_sck_shutdown_how_t
{
MIO_DEV_SCK_SHUTDOWN_READ = (1 << 0),
MIO_DEV_SCK_SHUTDOWN_WRITE = (1 << 1)
};
typedef enum mio_dev_sck_shutdown_how_t mio_dev_sck_shutdown_how_t;
enum mio_dev_sck_qxmsg_cmd_t
{
MIO_DEV_SCK_QXMSG_NEWCONN = 0
};
typedef enum mio_dev_sck_qxmsg_cmd_t mio_dev_sck_qxmsg_cmd_t;
struct mio_dev_sck_qxmsg_t
{
mio_dev_sck_qxmsg_cmd_t cmd;
mio_dev_sck_type_t scktype;
mio_syshnd_t syshnd;
mio_skad_t remoteaddr;
};
typedef struct mio_dev_sck_qxmsg_t mio_dev_sck_qxmsg_t;
#ifdef __cplusplus
extern "C" {
#endif
/* ========================================================================= */
MIO_EXPORT mio_dev_sck_t* mio_dev_sck_make (
mio_t* mio,
mio_oow_t xtnsize,
const mio_dev_sck_make_t* info
);
#if defined(MIO_HAVE_INLINE)
static MIO_INLINE mio_t* mio_dev_sck_getmio (mio_dev_sck_t* sck) { return mio_dev_getmio((mio_dev_t*)sck); }
static MIO_INLINE void* mio_dev_sck_getxtn (mio_dev_sck_t* sck) { return (void*)(sck + 1); }
static MIO_INLINE mio_dev_sck_type_t mio_dev_sck_gettype (mio_dev_sck_t* sck) { return sck->type; }
static MIO_INLINE mio_syshnd_t mio_dev_sck_getsyshnd (mio_dev_sck_t* sck) { return sck->hnd; }
#else
# define mio_dev_sck_getmio(sck) mio_dev_getmio(sck)
# define mio_dev_sck_getxtn(sck) ((void*)(((mio_dev_sck_t*)sck) + 1))
# define mio_dev_sck_gettype(sck) (((mio_dev_sck_t*)sck)->type)
# define mio_dev_sck_getsyshnd(sck) (((mio_dev_sck_t*)sck)->hnd)
#endif
MIO_EXPORT int mio_dev_sck_bind (
mio_dev_sck_t* dev,
mio_dev_sck_bind_t* info
);
MIO_EXPORT int mio_dev_sck_connect (
mio_dev_sck_t* dev,
mio_dev_sck_connect_t* info
);
MIO_EXPORT int mio_dev_sck_listen (
mio_dev_sck_t* dev,
mio_dev_sck_listen_t* info
);
MIO_EXPORT int mio_dev_sck_write (
mio_dev_sck_t* dev,
const void* data,
mio_iolen_t len,
void* wrctx,
const mio_skad_t* dstaddr
);
MIO_EXPORT int mio_dev_sck_writev (
mio_dev_sck_t* dev,
mio_iovec_t* iov,
mio_iolen_t iovcnt,
void* wrctx,
const mio_skad_t* dstaddr
);
MIO_EXPORT int mio_dev_sck_timedwrite (
mio_dev_sck_t* dev,
const void* data,
mio_iolen_t len,
const mio_ntime_t* tmout,
void* wrctx,
const mio_skad_t* dstaddr
);
MIO_EXPORT int mio_dev_sck_timedwritev (
mio_dev_sck_t* dev,
mio_iovec_t* iov,
mio_iolen_t iovcnt,
const mio_ntime_t* tmout,
void* wrctx,
const mio_skad_t* dstaddr
);
#if defined(MIO_HAVE_INLINE)
static MIO_INLINE void mio_dev_sck_kill (mio_dev_sck_t* sck)
{
mio_dev_kill ((mio_dev_t*)sck);
}
static MIO_INLINE void mio_dev_sck_halt (mio_dev_sck_t* sck)
{
mio_dev_halt ((mio_dev_t*)sck);
}
static MIO_INLINE int mio_dev_sck_read (mio_dev_sck_t* sck, int enabled)
{
return mio_dev_read((mio_dev_t*)sck, enabled);
}
static MIO_INLINE int mio_dev_sck_timedread (mio_dev_sck_t* sck, int enabled, mio_ntime_t* tmout)
{
return mio_dev_timedread((mio_dev_t*)sck, enabled, tmout);
}
static MIO_INLINE int mio_dev_sck_sendfile (mio_dev_sck_t* sck, mio_syshnd_t in_fd, mio_foff_t foff, mio_iolen_t len, void* wrctx)
{
return mio_dev_sendfile((mio_dev_t*)sck, in_fd, foff, len, wrctx);
}
static MIO_INLINE int mio_dev_sck_timedsendfile (mio_dev_sck_t* sck, mio_syshnd_t in_fd, mio_foff_t foff, mio_iolen_t len, mio_ntime_t* tmout, void* wrctx)
{
return mio_dev_timedsendfile((mio_dev_t*)sck, in_fd, foff, len, tmout, wrctx);
}
#else
#define mio_dev_sck_kill(sck) mio_dev_kill((mio_dev_t*)sck)
#define mio_dev_sck_halt(sck) mio_dev_halt((mio_dev_t*)sck)
#define mio_dev_sck_read(sck,enabled) mio_dev_read((mio_dev_t*)sck, enabled)
#define mio_dev_sck_timedread(sck,enabled,tmout) mio_dev_timedread((mio_dev_t*)sck, enabled, tmout)
#define mio_dev_sck_sendfile(sck,in_fd,foff,len,wrctx) mio_dev_sendfile((mio_dev_t*)sck, in_fd, foff, len, wrctx)
#define mio_dev_sck_timedsendfile(sck,in_fd,foff,len,tmout,wrctx) mio_dev_timedsendfile((mio_dev_t*)sck, in_fd, foff, len, tmout, wrctx)
#endif
MIO_EXPORT int mio_dev_sck_setsockopt (
mio_dev_sck_t* dev,
int level,
int optname,
void* optval,
mio_scklen_t optlen
);
MIO_EXPORT int mio_dev_sck_getsockopt (
mio_dev_sck_t* dev,
int level,
int optname,
void* optval,
mio_scklen_t* optlen
);
MIO_EXPORT int mio_dev_sck_getsockaddr (
mio_dev_sck_t* dev,
mio_skad_t* skad
);
MIO_EXPORT int mio_dev_sck_getpeeraddr (
mio_dev_sck_t* dev,
mio_skad_t* skad
);
MIO_EXPORT int mio_dev_sck_shutdown (
mio_dev_sck_t* dev,
int how /* bitwise-ORed of mio_dev_sck_shutdown_how_t enumerators */
);
MIO_EXPORT int mio_dev_sck_sendfileok (
mio_dev_sck_t* dev
);
MIO_EXPORT int mio_dev_sck_writetosidechan (
mio_dev_sck_t* htts,
const void* dptr,
mio_oow_t dlen
);
MIO_EXPORT mio_uint16_t mio_checksum_ip (
const void* hdr,
mio_oow_t len
);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -1,236 +0,0 @@
/*
* $Id$
*
Copyright (c) 2016-2020 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 WARRANTIES
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 _MIO_SKAD_H_
#define _MIO_SKAD_H_
#include <mio.h>
#include <mio-utl.h>
#define MIO_SIZEOF_SKAD_T 1
#if (MIO_SIZEOF_STRUCT_SOCKADDR_IN > MIO_SIZEOF_SKAD_T)
# undef MIO_SIZEOF_SKAD_T
# define MIO_SIZEOF_SKAD_T MIO_SIZEOF_STRUCT_SOCKADDR_IN
#endif
#if (MIO_SIZEOF_STRUCT_SOCKADDR_IN6 > MIO_SIZEOF_SKAD_T)
# undef MIO_SIZEOF_SKAD_T
# define MIO_SIZEOF_SKAD_T MIO_SIZEOF_STRUCT_SOCKADDR_IN6
#endif
#if (MIO_SIZEOF_STRUCT_SOCKADDR_LL > MIO_SIZEOF_SKAD_T)
# undef MIO_SIZEOF_SKAD_T
# define MIO_SIZEOF_SKAD_T MIO_SIZEOF_STRUCT_SOCKADDR_LL
#endif
#if (MIO_SIZEOF_STRUCT_SOCKADDR_DL > MIO_SIZEOF_SKAD_T)
# undef MIO_SIZEOF_SKAD_T
# define MIO_SIZEOF_SKAD_T MIO_SIZEOF_STRUCT_SOCKADDR_DL
#endif
#if (MIO_SIZEOF_STRUCT_SOCKADDR_UN > MIO_SIZEOF_SKAD_T)
# undef MIO_SIZEOF_SKAD_T
# define MIO_SIZEOF_SKAD_T MIO_SIZEOF_STRUCT_SOCKADDR_UN
#endif
struct mio_skad_t
{
mio_uint8_t data[MIO_SIZEOF_SKAD_T];
};
typedef struct mio_skad_t mio_skad_t;
#define MIO_SKAD_TO_OOCSTR_ADDR (1 << 0)
#define MIO_SKAD_TO_OOCSTR_PORT (1 << 1)
#define MIO_SKAD_TO_UCSTR_ADDR MIO_SKAD_TO_OOCSTR_ADDR
#define MIO_SKAD_TO_UCSTR_PORT MIO_SKAD_TO_OOCSTR_PORT
#define MIO_SKAD_TO_BCSTR_ADDR MIO_SKAD_TO_OOCSTR_ADDR
#define MIO_SKAD_TO_BCSTR_PORT MIO_SKAD_TO_OOCSTR_PORT
#define MIO_IP4AD_STRLEN (15) /* not including the terminating '\0' */
#define MIO_IP6AD_STRLEN (45) /* not including the terminating '\0'. pure IPv6 address, not including the scope(e.g. %10, %eth0) */
/* size large enough to hold the ip address plus port number.
* [IPV6ADDR%SCOPE]:PORT -> 9 for [] % : and PORT
* Let's reserve 16 for SCOPE and not include the terminting '\0'
*/
#define MIO_SKAD_IP_STRLEN (MIO_IP6AD_STRLEN + 25)
/* -------------------------------------------------------------------- */
#define MIO_ETHAD_LEN (6)
#define MIO_IP4AD_LEN (4)
#define MIO_IP6AD_LEN (16)
#include <mio-pac1.h>
struct MIO_PACKED mio_ethad_t
{
mio_uint8_t v[MIO_ETHAD_LEN];
};
typedef struct mio_ethad_t mio_ethad_t;
struct MIO_PACKED mio_ip4ad_t
{
mio_uint8_t v[MIO_IP4AD_LEN];
};
typedef struct mio_ip4ad_t mio_ip4ad_t;
struct MIO_PACKED mio_ip6ad_t
{
mio_uint8_t v[MIO_IP6AD_LEN];
};
typedef struct mio_ip6ad_t mio_ip6ad_t;
#include <mio-upac.h>
#if defined(__cplusplus)
extern "C" {
#endif
MIO_EXPORT int mio_ucharstoskad (
mio_t* mio,
const mio_uch_t* str,
mio_oow_t len,
mio_skad_t* skad
);
MIO_EXPORT int mio_bcharstoskad (
mio_t* mio,
const mio_bch_t* str,
mio_oow_t len,
mio_skad_t* skad
);
#define mio_bcstrtoskad(mio,str,skad) mio_bcharstoskad(mio, str, mio_count_bcstr(str), skad)
#define mio_ucstrtoskad(mio,str,skad) mio_ucharstoskad(mio, str, mio_count_ucstr(str), skad)
MIO_EXPORT mio_oow_t mio_skadtoucstr (
mio_t* mio,
const mio_skad_t* skad,
mio_uch_t* buf,
mio_oow_t len,
int flags
);
MIO_EXPORT mio_oow_t mio_skadtobcstr (
mio_t* mio,
const mio_skad_t* skad,
mio_bch_t* buf,
mio_oow_t len,
int flags
);
#if defined(MIO_OOCH_IS_UCH)
# define mio_oocharstoskad mio_ucharstoskad
# define mio_skadtooocstr mio_skadtoucstr
#else
# define mio_oocharstoskad mio_bcharstoskad
# define mio_skadtooocstr mio_skadtobcstr
#endif
MIO_EXPORT void mio_skad_init_for_ip4 (
mio_skad_t* skad,
mio_uint16_t port,
mio_ip4ad_t* ip4ad
);
MIO_EXPORT void mio_skad_init_for_ip6 (
mio_skad_t* skad,
mio_uint16_t port,
mio_ip6ad_t* ip6ad,
int scope_id
);
MIO_EXPORT void mio_skad_init_for_ip_with_bytes (
mio_skad_t* skad,
mio_uint16_t port,
const mio_uint8_t* bytes,
mio_oow_t len
);
MIO_EXPORT void mio_skad_init_for_eth (
mio_skad_t* skad,
int ifindex,
mio_ethad_t* ethad
);
MIO_EXPORT int mio_skad_family (
const mio_skad_t* skad
);
MIO_EXPORT int mio_skad_size (
const mio_skad_t* skad
);
MIO_EXPORT int mio_skad_port (
const mio_skad_t* skad
);
MIO_EXPORT int mio_skad_ifindex (
const mio_skad_t* skad
);
MIO_EXPORT void mio_clear_skad (
mio_skad_t* skad
);
MIO_EXPORT int mio_equal_skads (
const mio_skad_t* addr1,
const mio_skad_t* addr2,
int strict
);
MIO_EXPORT mio_oow_t mio_ipad_bytes_to_ucstr (
const mio_uint8_t* iptr,
mio_oow_t ilen,
mio_uch_t* buf,
mio_oow_t blen
);
MIO_EXPORT mio_oow_t mio_ipad_bytes_to_bcstr (
const mio_uint8_t* iptr,
mio_oow_t ilen,
mio_bch_t* buf,
mio_oow_t blen
);
MIO_EXPORT int mio_uchars_to_ipad_bytes (
const mio_uch_t* str,
mio_oow_t slen,
mio_uint8_t* buf,
mio_oow_t blen
);
MIO_EXPORT int mio_bchars_to_ipad_bytes (
const mio_bch_t* str,
mio_oow_t slen,
mio_uint8_t* buf,
mio_oow_t blen
);
#if defined(__cplusplus)
}
#endif
#endif

View File

@ -1,184 +0,0 @@
/*
* $Id$
*
Copyright (c) 2016-2020 Chung, Hyung-Hwan. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted thrvided 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 rethrduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials thrvided 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 _MIO_THR_H_
#define _MIO_THR_H_
#include <mio.h>
enum mio_dev_thr_sid_t
{
MIO_DEV_THR_MASTER = -1, /* no io occurs on this. used only in on_close() */
MIO_DEV_THR_IN = 0, /* input to the thread */
MIO_DEV_THR_OUT = 1, /* output from the thread */
};
typedef enum mio_dev_thr_sid_t mio_dev_thr_sid_t;
typedef struct mio_dev_thr_t mio_dev_thr_t;
typedef struct mio_dev_thr_slave_t mio_dev_thr_slave_t;
typedef int (*mio_dev_thr_on_read_t) (
mio_dev_thr_t* dev,
const void* data,
mio_iolen_t len
);
typedef int (*mio_dev_thr_on_write_t) (
mio_dev_thr_t* dev,
mio_iolen_t wrlen,
void* wrctx
);
typedef void (*mio_dev_thr_on_close_t) (
mio_dev_thr_t* dev,
mio_dev_thr_sid_t sid
);
struct mio_dev_thr_iopair_t
{
mio_syshnd_t rfd;
mio_syshnd_t wfd;
};
typedef struct mio_dev_thr_iopair_t mio_dev_thr_iopair_t;
typedef void (*mio_dev_thr_func_t) (
mio_t* mio,
mio_dev_thr_iopair_t* iop,
void* ctx
);
typedef struct mio_dev_thr_info_t mio_dev_thr_info_t;
struct mio_dev_thr_t
{
MIO_DEV_HEADER;
mio_dev_thr_slave_t* slave[2];
int slave_count;
mio_dev_thr_info_t* thr_info;
mio_dev_thr_on_read_t on_read;
mio_dev_thr_on_write_t on_write;
mio_dev_thr_on_close_t on_close;
};
struct mio_dev_thr_slave_t
{
MIO_DEV_HEADER;
mio_dev_thr_sid_t id;
mio_syshnd_t pfd;
mio_dev_thr_t* master; /* parent device */
};
typedef struct mio_dev_thr_make_t mio_dev_thr_make_t;
struct mio_dev_thr_make_t
{
mio_dev_thr_func_t thr_func;
void* thr_ctx;
mio_dev_thr_on_write_t on_write; /* mandatory */
mio_dev_thr_on_read_t on_read; /* mandatory */
mio_dev_thr_on_close_t on_close; /* optional */
};
enum mio_dev_thr_ioctl_cmd_t
{
MIO_DEV_THR_CLOSE,
MIO_DEV_THR_KILL_CHILD
};
typedef enum mio_dev_thr_ioctl_cmd_t mio_dev_thr_ioctl_cmd_t;
#ifdef __cplusplus
extern "C" {
#endif
MIO_EXPORT mio_dev_thr_t* mio_dev_thr_make (
mio_t* mio,
mio_oow_t xtnsize,
const mio_dev_thr_make_t* data
);
#if defined(MIO_HAVE_INLINE)
static MIO_INLINE mio_t* mio_dev_thr_getmio (mio_dev_thr_t* thr) { return mio_dev_getmio((mio_dev_t*)thr); }
#else
# define mio_dev_thr_getmio(thr) mio_dev_getmio(thr)
#endif
#if defined(MIO_HAVE_INLINE)
static MIO_INLINE void* mio_dev_thr_getxtn (mio_dev_thr_t* thr) { return (void*)(thr + 1); }
#else
# define mio_dev_thr_getxtn(thr) ((void*)(((mio_dev_thr_t*)thr) + 1))
#endif
MIO_EXPORT void mio_dev_thr_kill (
mio_dev_thr_t* thr
);
MIO_EXPORT void mio_dev_thr_halt (
mio_dev_thr_t* thr
);
MIO_EXPORT int mio_dev_thr_read (
mio_dev_thr_t* thr,
int enabled
);
MIO_EXPORT int mio_dev_thr_timedread (
mio_dev_thr_t* thr,
int enabled,
const mio_ntime_t* tmout
);
MIO_EXPORT int mio_dev_thr_write (
mio_dev_thr_t* thr,
const void* data,
mio_iolen_t len,
void* wrctx
);
MIO_EXPORT int mio_dev_thr_timedwrite (
mio_dev_thr_t* thr,
const void* data,
mio_iolen_t len,
const mio_ntime_t* tmout,
void* wrctx
);
MIO_EXPORT int mio_dev_thr_close (
mio_dev_thr_t* thr,
mio_dev_thr_sid_t sid
);
void mio_dev_thr_haltslave (
mio_dev_thr_t* dev,
mio_dev_thr_sid_t sid
);
#ifdef __cplusplus
}
#endif
#endif

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -849,14 +849,7 @@ static hio_oow_t ip4ad_to_ucstr (const struct in_addr* ipad, hio_uch_t* buf, hio
return p - buf;
}
<<<<<<< .mine
static hio_oow_t ip6ad_to_ucstr (const struct in6_addr* ipad, hio_uch_t* buf, hio_oow_t size)
||||||| .r361
static mio_oow_t ip6ad_to_ucstr (const struct in6_addr* ipad, mio_uch_t* buf, mio_oow_t size)
=======
static mio_oow_t ip6ad_to_ucstr (const struct in6_addr* ipad, mio_uch_t* buf, mio_oow_t size)
>>>>>>> .r366
{
/*
* Note that int32_t and int16_t need only be "at least" large enough
@ -866,23 +859,11 @@ static mio_oow_t ip6ad_to_ucstr (const struct in6_addr* ipad, mio_uch_t* buf, mi
* to use pointer overlays. All the world's not a VAX.
*/
<<<<<<< .mine
#define IP6AD_NWORDS (HIO_SIZEOF(ipad->s6_addr) / HIO_SIZEOF(hio_uint16_t))
||||||| .r361
#define IP6ADDR_NWORDS (MIO_SIZEOF(ipad->s6_addr) / MIO_SIZEOF(mio_uint16_t))
=======
#define IP6AD_NWORDS (MIO_SIZEOF(ipad->s6_addr) / MIO_SIZEOF(mio_uint16_t))
>>>>>>> .r366
hio_uch_t tmp[HIO_COUNTOF("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")], *tp;
struct { int base, len; } best, cur;
<<<<<<< .mine
hio_uint16_t words[IP6AD_NWORDS];
||||||| .r361
mio_uint16_t words[IP6ADDR_NWORDS];
=======
mio_uint16_t words[IP6AD_NWORDS];
>>>>>>> .r366
int i;
if (size <= 0) return 0;
@ -1124,23 +1105,11 @@ static hio_oow_t ip6ad_to_bcstr (const struct in6_addr* ipad, hio_bch_t* buf, hi
* to use pointer overlays. All the world's not a VAX.
*/
<<<<<<< .mine
#define IP6AD_NWORDS (HIO_SIZEOF(ipad->s6_addr) / HIO_SIZEOF(hio_uint16_t))
||||||| .r361
#define IP6ADDR_NWORDS (MIO_SIZEOF(ipad->s6_addr) / MIO_SIZEOF(mio_uint16_t))
=======
#define IP6AD_NWORDS (MIO_SIZEOF(ipad->s6_addr) / MIO_SIZEOF(mio_uint16_t))
>>>>>>> .r366
hio_bch_t tmp[HIO_COUNTOF("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")], *tp;
struct { int base, len; } best, cur;
<<<<<<< .mine
hio_uint16_t words[IP6AD_NWORDS];
||||||| .r361
mio_uint16_t words[IP6ADDR_NWORDS];
=======
mio_uint16_t words[IP6AD_NWORDS];
>>>>>>> .r366
int i;
if (size <= 0) return 0;
@ -1408,16 +1377,8 @@ void hio_skad_init_for_ip4 (hio_skad_t* skad, hio_uint16_t port, hio_ip4ad_t* ip
struct sockaddr_in* sin = (struct sockaddr_in*)skad;
HIO_MEMSET (sin, 0, HIO_SIZEOF(*sin));
sin->sin_family = AF_INET;
<<<<<<< .mine
sin->sin_port = hio_hton16(port);
if (ip4ad) HIO_MEMCPY (&sin->sin_addr, ip4ad->v, HIO_IP4AD_LEN);
||||||| .r361
sin->sin_port = mio_hton16(port);
if (ip4ad) MIO_MEMCPY (&sin->sin_addr, ip4ad->v, MIO_IP4ADDR_LEN);
=======
sin->sin_port = mio_hton16(port);
if (ip4ad) MIO_MEMCPY (&sin->sin_addr, ip4ad->v, MIO_IP4AD_LEN);
>>>>>>> .r366
#endif
}
@ -1429,13 +1390,7 @@ void hio_skad_init_for_ip6 (hio_skad_t* skad, hio_uint16_t port, hio_ip6ad_t* ip
sin->sin6_family = AF_INET6;
sin->sin6_port = hio_hton16(port);
sin->sin6_scope_id = scope_id;
<<<<<<< .mine
if (ip6ad) HIO_MEMCPY (&sin->sin6_addr, ip6ad->v, HIO_IP6AD_LEN);
||||||| .r361
if (ip6ad) MIO_MEMCPY (&sin->sin6_addr, ip6ad->v, MIO_IP6ADDR_LEN);
=======
if (ip6ad) MIO_MEMCPY (&sin->sin6_addr, ip6ad->v, MIO_IP6AD_LEN);
>>>>>>> .r366
#endif
}
@ -1443,16 +1398,8 @@ void hio_skad_init_for_ip_with_bytes (hio_skad_t* skad, hio_uint16_t port, const
{
switch (len)
{
<<<<<<< .mine
#if (HIO_SIZEOF_STRUCT_SOCKADDR_IN > 0)
case HIO_IP4AD_LEN:
||||||| .r361
#if (MIO_SIZEOF_STRUCT_SOCKADDR_IN > 0)
case MIO_IP4ADDR_LEN:
=======
#if (MIO_SIZEOF_STRUCT_SOCKADDR_IN > 0)
case MIO_IP4AD_LEN:
>>>>>>> .r366
{
struct sockaddr_in* sin = (struct sockaddr_in*)skad;
HIO_MEMSET (sin, 0, HIO_SIZEOF(*sin));
@ -1462,16 +1409,8 @@ void hio_skad_init_for_ip_with_bytes (hio_skad_t* skad, hio_uint16_t port, const
break;
}
#endif
<<<<<<< .mine
#if (HIO_SIZEOF_STRUCT_SOCKADDR_IN6 > 0)
case HIO_IP6AD_LEN:
||||||| .r361
#if (MIO_SIZEOF_STRUCT_SOCKADDR_IN6 > 0)
case MIO_IP6ADDR_LEN:
=======
#if (MIO_SIZEOF_STRUCT_SOCKADDR_IN6 > 0)
case MIO_IP6AD_LEN:
>>>>>>> .r366
{
struct sockaddr_in6* sin = (struct sockaddr_in6*)skad;
HIO_MEMSET (sin, 0, HIO_SIZEOF(*sin));
@ -1487,13 +1426,7 @@ void hio_skad_init_for_ip_with_bytes (hio_skad_t* skad, hio_uint16_t port, const
}
<<<<<<< .mine
void hio_skad_init_for_eth (hio_skad_t* skad, int ifindex, hio_ethad_t* ethad)
||||||| .r361
void mio_skad_init_for_eth (mio_skad_t* skad, int ifindex, mio_ethaddr_t* ethaddr)
=======
void mio_skad_init_for_eth (mio_skad_t* skad, int ifindex, mio_ethad_t* ethad)
>>>>>>> .r366
{
#if defined(AF_PACKET) && (HIO_SIZEOF_STRUCT_SOCKADDR_LL > 0)
struct sockaddr_ll* sll = (struct sockaddr_ll*)skad;
@ -1502,16 +1435,8 @@ void mio_skad_init_for_eth (mio_skad_t* skad, int ifindex, mio_ethad_t* ethad)
sll->sll_ifindex = ifindex;
if (ethad)
{
<<<<<<< .mine
sll->sll_halen = HIO_ETHAD_LEN;
HIO_MEMCPY (sll->sll_addr, ethad, HIO_ETHAD_LEN);
||||||| .r361
sll->sll_halen = MIO_ETHADDR_LEN;
MIO_MEMCPY (sll->sll_addr, ethaddr, MIO_ETHADDR_LEN);
=======
sll->sll_halen = MIO_ETHAD_LEN;
MIO_MEMCPY (sll->sll_addr, ethad, MIO_ETHAD_LEN);
>>>>>>> .r366
}
#elif defined(AF_LINK) && (HIO_SIZEOF_STRUCT_SOCKADDR_DL > 0)
@ -1521,16 +1446,8 @@ void mio_skad_init_for_eth (mio_skad_t* skad, int ifindex, mio_ethad_t* ethad)
sll->sdl_index = ifindex;
if (ethad)
{
<<<<<<< .mine
sll->sdl_alen = HIO_ETHAD_LEN;
HIO_MEMCPY (sll->sdl_data, ethad, HIO_ETHAD_LEN);
||||||| .r361
sll->sdl_alen = MIO_ETHADDR_LEN;
MIO_MEMCPY (sll->sdl_data, ethaddr, MIO_ETHADDR_LEN);
=======
sll->sdl_alen = MIO_ETHAD_LEN;
MIO_MEMCPY (sll->sdl_data, ethad, MIO_ETHAD_LEN);
>>>>>>> .r366
}
#else
# error UNSUPPORTED DATALINK SOCKET ADDRESS
@ -1592,26 +1509,14 @@ hio_oow_t hio_ipad_bytes_to_ucstr (const hio_uint8_t* iptr, hio_oow_t ilen, hio_
{
switch (ilen)
{
<<<<<<< .mine
case HIO_IP4AD_LEN:
||||||| .r361
case MIO_IP4ADDR_LEN:
=======
case MIO_IP4AD_LEN:
>>>>>>> .r366
{
struct in_addr ip4ad;
HIO_MEMCPY (&ip4ad.s_addr, iptr, ilen);
return ip4ad_to_ucstr(&ip4ad, buf, blen);
}
<<<<<<< .mine
case HIO_IP6AD_LEN:
||||||| .r361
case MIO_IP6ADDR_LEN:
=======
case MIO_IP6AD_LEN:
>>>>>>> .r366
{
struct in6_addr ip6ad;
HIO_MEMCPY (&ip6ad.s6_addr, iptr, ilen);
@ -1628,26 +1533,14 @@ hio_oow_t hio_ipad_bytes_to_bcstr (const hio_uint8_t* iptr, hio_oow_t ilen, hio_
{
switch (ilen)
{
<<<<<<< .mine
case HIO_IP4AD_LEN:
||||||| .r361
case MIO_IP4ADDR_LEN:
=======
case MIO_IP4AD_LEN:
>>>>>>> .r366
{
struct in_addr ip4ad;
HIO_MEMCPY (&ip4ad.s_addr, iptr, ilen);
return ip4ad_to_bcstr(&ip4ad, buf, blen);
}
<<<<<<< .mine
case HIO_IP6AD_LEN:
||||||| .r361
case MIO_IP6ADDR_LEN:
=======
case MIO_IP6AD_LEN:
>>>>>>> .r366
{
struct in6_addr ip6ad;
HIO_MEMCPY (&ip6ad.s6_addr, iptr, ilen);
@ -1662,48 +1555,20 @@ hio_oow_t hio_ipad_bytes_to_bcstr (const hio_uint8_t* iptr, hio_oow_t ilen, hio_
int hio_uchars_to_ipad_bytes (const hio_uch_t* str, hio_oow_t slen, hio_uint8_t* buf, hio_oow_t blen)
{
<<<<<<< .mine
if (blen >= HIO_IP6AD_LEN)
||||||| .r361
if (blen >= MIO_IP6ADDR_LEN)
=======
if (blen >= MIO_IP6AD_LEN)
>>>>>>> .r366
{
struct in6_addr i6;
if (uchars_to_ipv6(str, slen, &i6) <= -1) goto ipv4;
<<<<<<< .mine
HIO_MEMCPY (buf, i6.s6_addr, 16);
return HIO_IP6AD_LEN;
||||||| .r361
MIO_MEMCPY (buf, i6.s6_addr, 16);
return MIO_IP6ADDR_LEN;
=======
MIO_MEMCPY (buf, i6.s6_addr, 16);
return MIO_IP6AD_LEN;
>>>>>>> .r366
}
<<<<<<< .mine
else if (blen >= HIO_IP4AD_LEN)
||||||| .r361
else if (blen >= MIO_IP4ADDR_LEN)
=======
else if (blen >= MIO_IP4AD_LEN)
>>>>>>> .r366
{
struct in_addr i4;
ipv4:
if (uchars_to_ipv4(str, slen, &i4) <= -1) return -1;
<<<<<<< .mine
HIO_MEMCPY (buf, &i4.s_addr, 4);
return HIO_IP4AD_LEN;
||||||| .r361
MIO_MEMCPY (buf, &i4.s_addr, 4);
return MIO_IP4ADDR_LEN;
=======
MIO_MEMCPY (buf, &i4.s_addr, 4);
return MIO_IP4AD_LEN;
>>>>>>> .r366
}
return -1;
@ -1711,48 +1576,20 @@ int hio_uchars_to_ipad_bytes (const hio_uch_t* str, hio_oow_t slen, hio_uint8_t*
int hio_bchars_to_ipad_bytes (const hio_bch_t* str, hio_oow_t slen, hio_uint8_t* buf, hio_oow_t blen)
{
<<<<<<< .mine
if (blen >= HIO_IP6AD_LEN)
||||||| .r361
if (blen >= MIO_IP6ADDR_LEN)
=======
if (blen >= MIO_IP6AD_LEN)
>>>>>>> .r366
{
struct in6_addr i6;
if (bchars_to_ipv6(str, slen, &i6) <= -1) goto ipv4;
<<<<<<< .mine
HIO_MEMCPY (buf, i6.s6_addr, 16);
return HIO_IP6AD_LEN;
||||||| .r361
MIO_MEMCPY (buf, i6.s6_addr, 16);
return MIO_IP6ADDR_LEN;
=======
MIO_MEMCPY (buf, i6.s6_addr, 16);
return MIO_IP6AD_LEN;
>>>>>>> .r366
}
<<<<<<< .mine
else if (blen >= HIO_IP4AD_LEN)
||||||| .r361
else if (blen >= MIO_IP4ADDR_LEN)
=======
else if (blen >= MIO_IP4AD_LEN)
>>>>>>> .r366
{
struct in_addr i4;
ipv4:
if (bchars_to_ipv4(str, slen, &i4) <= -1) return -1;
<<<<<<< .mine
HIO_MEMCPY (buf, &i4.s_addr, 4);
return HIO_IP4AD_LEN;
||||||| .r361
MIO_MEMCPY (buf, &i4.s_addr, 4);
return MIO_IP4ADDR_LEN;
=======
MIO_MEMCPY (buf, &i4.s_addr, 4);
return MIO_IP4AD_LEN;
>>>>>>> .r366
}
return -1;