fixing conflicts caused during renaming
This commit is contained in:
@ -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++)
|
||||
{
|
||||
|
@ -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
382
hio/lib/hio-chr.h
Normal 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
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
609
hio/lib/hio-dns.h
Normal 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
635
hio/lib/hio-ecs.h
Normal 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
391
hio/lib/hio-fmt.h
Normal 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
682
hio/lib/hio-htb.h
Normal 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
214
hio/lib/hio-htrd.h
Normal 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
324
hio/lib/hio-htre.h
Normal 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
346
hio/lib/hio-http.h
Normal 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
396
hio/lib/hio-json.h
Normal 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
288
hio/lib/hio-mar.h
Normal 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
|
@ -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)
|
@ -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)
|
@ -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
160
hio/lib/hio-pipe.h
Normal 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
212
hio/lib/hio-pro.h
Normal 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
|
@ -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
618
hio/lib/hio-sck.h
Normal 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
236
hio/lib/hio-skad.h
Normal 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
184
hio/lib/hio-thr.h
Normal 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
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
2170
hio/lib/hio.c
Normal file
File diff suppressed because it is too large
Load Diff
1416
hio/lib/hio.h
Normal file
1416
hio/lib/hio.h
Normal file
File diff suppressed because it is too large
Load Diff
@ -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
|
1028
hio/lib/mio-cmn.h
1028
hio/lib/mio-cmn.h
File diff suppressed because it is too large
Load Diff
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
1051
hio/lib/mio-utl.h
1051
hio/lib/mio-utl.h
File diff suppressed because it is too large
Load Diff
2170
hio/lib/mio.c
2170
hio/lib/mio.c
File diff suppressed because it is too large
Load Diff
1416
hio/lib/mio.h
1416
hio/lib/mio.h
File diff suppressed because it is too large
Load Diff
163
hio/lib/skad.c
163
hio/lib/skad.c
@ -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;
|
||||
|
Reference in New Issue
Block a user