added ecs and htb
This commit is contained in:
parent
26b720099c
commit
f1aa019091
@ -23,7 +23,11 @@ include_HEADERS = \
|
||||
mio-cfg.h \
|
||||
mio-cmn.h \
|
||||
mio-dns.h \
|
||||
mio-ecs.h \
|
||||
mio-fmt.h \
|
||||
mio-htb.h \
|
||||
mio-htre.h \
|
||||
mio-http.h \
|
||||
mio-nwif.h \
|
||||
mio-pac1.h \
|
||||
mio-pro.h \
|
||||
@ -37,9 +41,12 @@ lib_LTLIBRARIES = libmio.la
|
||||
libmio_la_SOURCES = \
|
||||
dns.c \
|
||||
dns-cli.c \
|
||||
ecs.c \
|
||||
ecs-imp.h \
|
||||
err.c \
|
||||
fmt.c \
|
||||
fmt-imp.h \
|
||||
htb.c \
|
||||
mio-prv.h \
|
||||
mio.c \
|
||||
nwif.c \
|
||||
|
@ -139,12 +139,12 @@ am__DEPENDENCIES_2 = $(am__DEPENDENCIES_1)
|
||||
libmio_la_DEPENDENCIES = $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_1) \
|
||||
$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)
|
||||
am_libmio_la_OBJECTS = libmio_la-dns.lo libmio_la-dns-cli.lo \
|
||||
libmio_la-err.lo libmio_la-fmt.lo libmio_la-mio.lo \
|
||||
libmio_la-nwif.lo libmio_la-pro.lo libmio_la-sck.lo \
|
||||
libmio_la-skad.lo libmio_la-sys.lo libmio_la-sys-ass.lo \
|
||||
libmio_la-sys-err.lo libmio_la-sys-log.lo libmio_la-sys-mux.lo \
|
||||
libmio_la-sys-tim.lo libmio_la-tmr.lo libmio_la-utf8.lo \
|
||||
libmio_la-utl.lo
|
||||
libmio_la-ecs.lo libmio_la-err.lo libmio_la-fmt.lo \
|
||||
libmio_la-htb.lo libmio_la-mio.lo libmio_la-nwif.lo \
|
||||
libmio_la-pro.lo libmio_la-sck.lo libmio_la-skad.lo \
|
||||
libmio_la-sys.lo libmio_la-sys-ass.lo libmio_la-sys-err.lo \
|
||||
libmio_la-sys-log.lo libmio_la-sys-mux.lo libmio_la-sys-tim.lo \
|
||||
libmio_la-tmr.lo libmio_la-utf8.lo libmio_la-utl.lo
|
||||
libmio_la_OBJECTS = $(am_libmio_la_OBJECTS)
|
||||
AM_V_lt = $(am__v_lt_@AM_V@)
|
||||
am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
|
||||
@ -169,8 +169,9 @@ DEFAULT_INCLUDES =
|
||||
depcomp = $(SHELL) $(top_srcdir)/ac/depcomp
|
||||
am__maybe_remake_depfiles = depfiles
|
||||
am__depfiles_remade = ./$(DEPDIR)/libmio_la-dns-cli.Plo \
|
||||
./$(DEPDIR)/libmio_la-dns.Plo ./$(DEPDIR)/libmio_la-err.Plo \
|
||||
./$(DEPDIR)/libmio_la-fmt.Plo ./$(DEPDIR)/libmio_la-mio.Plo \
|
||||
./$(DEPDIR)/libmio_la-dns.Plo ./$(DEPDIR)/libmio_la-ecs.Plo \
|
||||
./$(DEPDIR)/libmio_la-err.Plo ./$(DEPDIR)/libmio_la-fmt.Plo \
|
||||
./$(DEPDIR)/libmio_la-htb.Plo ./$(DEPDIR)/libmio_la-mio.Plo \
|
||||
./$(DEPDIR)/libmio_la-nwif.Plo ./$(DEPDIR)/libmio_la-pro.Plo \
|
||||
./$(DEPDIR)/libmio_la-sck.Plo ./$(DEPDIR)/libmio_la-skad.Plo \
|
||||
./$(DEPDIR)/libmio_la-sys-ass.Plo \
|
||||
@ -399,7 +400,11 @@ include_HEADERS = \
|
||||
mio-cfg.h \
|
||||
mio-cmn.h \
|
||||
mio-dns.h \
|
||||
mio-ecs.h \
|
||||
mio-fmt.h \
|
||||
mio-htb.h \
|
||||
mio-htre.h \
|
||||
mio-http.h \
|
||||
mio-nwif.h \
|
||||
mio-pac1.h \
|
||||
mio-pro.h \
|
||||
@ -413,9 +418,12 @@ lib_LTLIBRARIES = libmio.la
|
||||
libmio_la_SOURCES = \
|
||||
dns.c \
|
||||
dns-cli.c \
|
||||
ecs.c \
|
||||
ecs-imp.h \
|
||||
err.c \
|
||||
fmt.c \
|
||||
fmt-imp.h \
|
||||
htb.c \
|
||||
mio-prv.h \
|
||||
mio.c \
|
||||
nwif.c \
|
||||
@ -532,8 +540,10 @@ distclean-compile:
|
||||
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmio_la-dns-cli.Plo@am__quote@ # am--include-marker
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmio_la-dns.Plo@am__quote@ # am--include-marker
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmio_la-ecs.Plo@am__quote@ # am--include-marker
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmio_la-err.Plo@am__quote@ # am--include-marker
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmio_la-fmt.Plo@am__quote@ # am--include-marker
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmio_la-htb.Plo@am__quote@ # am--include-marker
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmio_la-mio.Plo@am__quote@ # am--include-marker
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmio_la-nwif.Plo@am__quote@ # am--include-marker
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmio_la-pro.Plo@am__quote@ # am--include-marker
|
||||
@ -593,6 +603,13 @@ libmio_la-dns-cli.lo: dns-cli.c
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libmio_la-dns-cli.lo `test -f 'dns-cli.c' || echo '$(srcdir)/'`dns-cli.c
|
||||
|
||||
libmio_la-ecs.lo: ecs.c
|
||||
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libmio_la-ecs.lo -MD -MP -MF $(DEPDIR)/libmio_la-ecs.Tpo -c -o libmio_la-ecs.lo `test -f 'ecs.c' || echo '$(srcdir)/'`ecs.c
|
||||
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libmio_la-ecs.Tpo $(DEPDIR)/libmio_la-ecs.Plo
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ecs.c' object='libmio_la-ecs.lo' libtool=yes @AMDEPBACKSLASH@
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libmio_la-ecs.lo `test -f 'ecs.c' || echo '$(srcdir)/'`ecs.c
|
||||
|
||||
libmio_la-err.lo: err.c
|
||||
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libmio_la-err.lo -MD -MP -MF $(DEPDIR)/libmio_la-err.Tpo -c -o libmio_la-err.lo `test -f 'err.c' || echo '$(srcdir)/'`err.c
|
||||
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libmio_la-err.Tpo $(DEPDIR)/libmio_la-err.Plo
|
||||
@ -607,6 +624,13 @@ libmio_la-fmt.lo: fmt.c
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libmio_la-fmt.lo `test -f 'fmt.c' || echo '$(srcdir)/'`fmt.c
|
||||
|
||||
libmio_la-htb.lo: htb.c
|
||||
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libmio_la-htb.lo -MD -MP -MF $(DEPDIR)/libmio_la-htb.Tpo -c -o libmio_la-htb.lo `test -f 'htb.c' || echo '$(srcdir)/'`htb.c
|
||||
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libmio_la-htb.Tpo $(DEPDIR)/libmio_la-htb.Plo
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='htb.c' object='libmio_la-htb.lo' libtool=yes @AMDEPBACKSLASH@
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libmio_la-htb.lo `test -f 'htb.c' || echo '$(srcdir)/'`htb.c
|
||||
|
||||
libmio_la-mio.lo: mio.c
|
||||
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libmio_la-mio.lo -MD -MP -MF $(DEPDIR)/libmio_la-mio.Tpo -c -o libmio_la-mio.lo `test -f 'mio.c' || echo '$(srcdir)/'`mio.c
|
||||
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libmio_la-mio.Tpo $(DEPDIR)/libmio_la-mio.Plo
|
||||
@ -862,8 +886,10 @@ clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \
|
||||
distclean: distclean-am
|
||||
-rm -f ./$(DEPDIR)/libmio_la-dns-cli.Plo
|
||||
-rm -f ./$(DEPDIR)/libmio_la-dns.Plo
|
||||
-rm -f ./$(DEPDIR)/libmio_la-ecs.Plo
|
||||
-rm -f ./$(DEPDIR)/libmio_la-err.Plo
|
||||
-rm -f ./$(DEPDIR)/libmio_la-fmt.Plo
|
||||
-rm -f ./$(DEPDIR)/libmio_la-htb.Plo
|
||||
-rm -f ./$(DEPDIR)/libmio_la-mio.Plo
|
||||
-rm -f ./$(DEPDIR)/libmio_la-nwif.Plo
|
||||
-rm -f ./$(DEPDIR)/libmio_la-pro.Plo
|
||||
@ -926,8 +952,10 @@ installcheck-am:
|
||||
maintainer-clean: maintainer-clean-am
|
||||
-rm -f ./$(DEPDIR)/libmio_la-dns-cli.Plo
|
||||
-rm -f ./$(DEPDIR)/libmio_la-dns.Plo
|
||||
-rm -f ./$(DEPDIR)/libmio_la-ecs.Plo
|
||||
-rm -f ./$(DEPDIR)/libmio_la-err.Plo
|
||||
-rm -f ./$(DEPDIR)/libmio_la-fmt.Plo
|
||||
-rm -f ./$(DEPDIR)/libmio_la-htb.Plo
|
||||
-rm -f ./$(DEPDIR)/libmio_la-mio.Plo
|
||||
-rm -f ./$(DEPDIR)/libmio_la-nwif.Plo
|
||||
-rm -f ./$(DEPDIR)/libmio_la-pro.Plo
|
||||
|
453
mio/lib/ecs-imp.h
Normal file
453
mio/lib/ecs-imp.h
Normal file
@ -0,0 +1,453 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
Copyright (c) 2006-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.
|
||||
*/
|
||||
|
||||
|
||||
str_t* FN(open) (mio_t* gem, mio_oow_t xtnsize, mio_oow_t capa)
|
||||
{
|
||||
str_t* str;
|
||||
|
||||
str = (str_t*)mio_allocmem(gem, MIO_SIZEOF(str_t) + xtnsize);
|
||||
if (str)
|
||||
{
|
||||
if (FN(init)(str, gem, capa) <= -1)
|
||||
{
|
||||
mio_freemem (gem, str);
|
||||
str = MIO_NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
MIO_MEMSET (str + 1, 0, xtnsize);
|
||||
}
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
void FN(close) (str_t* str)
|
||||
{
|
||||
FN(fini) (str);
|
||||
mio_freemem (str->gem, str);
|
||||
}
|
||||
|
||||
int FN(init) (str_t* str, mio_t* gem, mio_oow_t capa)
|
||||
{
|
||||
MIO_MEMSET (str, 0, MIO_SIZEOF(str_t));
|
||||
|
||||
str->gem = gem;
|
||||
str->sizer = MIO_NULL;
|
||||
|
||||
if (capa == 0) str->val.ptr = MIO_NULL;
|
||||
else
|
||||
{
|
||||
str->val.ptr = (char_t*)mio_allocmem(gem, MIO_SIZEOF(char_t) * (capa + 1));
|
||||
if (!str->val.ptr) return -1;
|
||||
str->val.ptr[0] = '\0';
|
||||
}
|
||||
|
||||
str->val.len = 0;
|
||||
str->capa = capa;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void FN(fini) (str_t* str)
|
||||
{
|
||||
if (str->val.ptr) mio_freemem (str->gem, str->val.ptr);
|
||||
}
|
||||
|
||||
int FN(yield) (str_t* str, cstr_t* buf, mio_oow_t newcapa)
|
||||
{
|
||||
char_t* tmp;
|
||||
|
||||
if (newcapa == 0) tmp = MIO_NULL;
|
||||
else
|
||||
{
|
||||
tmp = (char_t*)mio_allocmem(str->gem, MIO_SIZEOF(char_t) * (newcapa + 1));
|
||||
if (!tmp) return -1;
|
||||
tmp[0] = '\0';
|
||||
}
|
||||
|
||||
if (buf) *buf = str->val;
|
||||
|
||||
str->val.ptr = tmp;
|
||||
str->val.len = 0;
|
||||
str->capa = newcapa;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
char_t* FN(yieldptr) (str_t* str, mio_oow_t newcapa)
|
||||
{
|
||||
cstr_t mx;
|
||||
if (FN(yield)(str, &mx, newcapa) <= -1) return MIO_NULL;
|
||||
return mx.ptr;
|
||||
}
|
||||
|
||||
|
||||
mio_oow_t FN(setcapa) (str_t* str, mio_oow_t capa)
|
||||
{
|
||||
char_t* tmp;
|
||||
|
||||
if (capa == str->capa) return capa;
|
||||
|
||||
tmp = (char_t*)mio_reallocmem(str->gem, str->val.ptr, MIO_SIZEOF(char_t) * (capa+1));
|
||||
if (!tmp) return (mio_oow_t)-1;
|
||||
|
||||
if (capa < str->val.len)
|
||||
{
|
||||
str->val.len = capa;
|
||||
tmp[capa] = '\0';
|
||||
}
|
||||
|
||||
str->capa = capa;
|
||||
str->val.ptr = tmp;
|
||||
|
||||
return str->capa;
|
||||
}
|
||||
|
||||
mio_oow_t FN(setlen) (str_t* str, mio_oow_t len)
|
||||
{
|
||||
if (len == str->val.len) return len;
|
||||
if (len < str->val.len)
|
||||
{
|
||||
str->val.len = len;
|
||||
str->val.ptr[len] = '\0';
|
||||
return len;
|
||||
}
|
||||
|
||||
if (len > str->capa)
|
||||
{
|
||||
if (FN(setcapa)(str, len) == (mio_oow_t)-1) return (mio_oow_t)-1;
|
||||
}
|
||||
|
||||
while (str->val.len < len) str->val.ptr[str->val.len++] = ' ';
|
||||
str->val.ptr[str->val.len] = '\0';
|
||||
return str->val.len;
|
||||
}
|
||||
|
||||
void FN(clear) (str_t* str)
|
||||
{
|
||||
str->val.len = 0;
|
||||
if (str->val.ptr)
|
||||
{
|
||||
MIO_ASSERT (str->gem, str->capa >= 1);
|
||||
str->val.ptr[0] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
void FN(swap) (str_t* str, str_t* str1)
|
||||
{
|
||||
str_t tmp;
|
||||
|
||||
tmp.val.ptr = str->val.ptr;
|
||||
tmp.val.len = str->val.len;
|
||||
tmp.capa = str->capa;
|
||||
tmp.gem = str->gem;
|
||||
|
||||
str->val.ptr = str1->val.ptr;
|
||||
str->val.len = str1->val.len;
|
||||
str->capa = str1->capa;
|
||||
str->gem = str1->gem;
|
||||
|
||||
str1->val.ptr = tmp.val.ptr;
|
||||
str1->val.len = tmp.val.len;
|
||||
str1->capa = tmp.capa;
|
||||
str1->gem = tmp.gem;
|
||||
}
|
||||
|
||||
|
||||
mio_oow_t FN(cpy) (str_t* str, const char_t* s)
|
||||
{
|
||||
/* TODO: improve it */
|
||||
return FN(ncpy)(str, s, count_chars(s));
|
||||
}
|
||||
|
||||
mio_oow_t FN(ncpy) (str_t* str, const char_t* s, mio_oow_t len)
|
||||
{
|
||||
if (len > str->capa || str->capa <= 0)
|
||||
{
|
||||
mio_oow_t tmp;
|
||||
|
||||
/* if the current capacity is 0 and the string len to copy is 0
|
||||
* we can't simply pass 'len' as the new capapcity.
|
||||
* ecs_setcapa() won't do anything the current capacity of 0
|
||||
* is the same as new capacity required. note that when str->capa
|
||||
* is 0, str->val.ptr is MIO_NULL. However, this is copying operation.
|
||||
* Copying a zero-length string may indicate that str->val.ptr must
|
||||
* not be MIO_NULL. so I simply pass 1 as the new capacity */
|
||||
tmp = FN(setcapa)(str, ((str->capa <= 0 && len <= 0)? 1: len));
|
||||
if (tmp == (mio_oow_t)-1) return (mio_oow_t)-1;
|
||||
}
|
||||
|
||||
MIO_MEMCPY (&str->val.ptr[0], s, len * MIO_SIZEOF(*s));
|
||||
str->val.ptr[len] = '\0';
|
||||
str->val.len = len;
|
||||
return len;
|
||||
}
|
||||
|
||||
mio_oow_t FN(cat) (str_t* str, const char_t* s)
|
||||
{
|
||||
/* TODO: improve it. no counting */
|
||||
return FN(ncat)(str, s, count_chars(s));
|
||||
}
|
||||
|
||||
static int FN(resize_for_ncat) (str_t* str, mio_oow_t len)
|
||||
{
|
||||
if (len > str->capa - str->val.len)
|
||||
{
|
||||
mio_oow_t ncapa, mincapa;
|
||||
|
||||
/* let the minimum capacity be as large as
|
||||
* to fit in the new substring */
|
||||
mincapa = str->val.len + len;
|
||||
|
||||
if (!str->sizer)
|
||||
{
|
||||
/* increase the capacity by the length to add */
|
||||
ncapa = mincapa;
|
||||
/* if the new capacity is less than the double,
|
||||
* just double it */
|
||||
if (ncapa < str->capa * 2) ncapa = str->capa * 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* let the user determine the new capacity.
|
||||
* pass the minimum capacity required as a hint */
|
||||
ncapa = str->sizer(str, mincapa);
|
||||
/* if no change in capacity, return current length */
|
||||
if (ncapa == str->capa) return 0;
|
||||
}
|
||||
|
||||
/* change the capacity */
|
||||
do
|
||||
{
|
||||
if (FN(setcapa)(str, ncapa) != (mio_oow_t)-1) break;
|
||||
if (ncapa <= mincapa) return -1;
|
||||
ncapa--;
|
||||
}
|
||||
while (1);
|
||||
}
|
||||
else if (str->capa <= 0 && len <= 0)
|
||||
{
|
||||
MIO_ASSERT (str->gem, str->val.ptr == MIO_NULL);
|
||||
MIO_ASSERT (str->gem, str->val.len <= 0);
|
||||
if (FN(setcapa)(str, 1) == (mio_oow_t)-1) return -1;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
mio_oow_t FN(ncat) (str_t* str, const char_t* s, mio_oow_t len)
|
||||
{
|
||||
int n;
|
||||
mio_oow_t i, j;
|
||||
|
||||
n = FN(resize_for_ncat)(str, len);
|
||||
if (n <= -1) return (mio_oow_t)-1;
|
||||
if (n == 0) return str->val.len;
|
||||
|
||||
if (len > str->capa - str->val.len)
|
||||
{
|
||||
/* copy as many characters as the number of cells available.
|
||||
* if the capacity has been decreased, len is adjusted here */
|
||||
len = str->capa - str->val.len;
|
||||
}
|
||||
|
||||
/*
|
||||
MIO_MEMCPY (&str->val.ptr[str->val.len], s, len*MIO_SIZEOF(*s));
|
||||
str->val.len += len;
|
||||
str->val.ptr[str->val.len] = T('\0');
|
||||
*/
|
||||
for (i = 0, j = str->val.len ; i < len; j++, i++) str->val.ptr[j] = s[i];
|
||||
str->val.ptr[j] = '\0';
|
||||
str->val.len = j;
|
||||
|
||||
return str->val.len;
|
||||
}
|
||||
|
||||
mio_oow_t FN(nrcat) (str_t* str, const char_t* s, mio_oow_t len)
|
||||
{
|
||||
int n;
|
||||
mio_oow_t i, j;
|
||||
|
||||
n = FN(resize_for_ncat)(str, len);
|
||||
if (n <= -1) return (mio_oow_t)-1;
|
||||
if (n == 0) return str->val.len;
|
||||
|
||||
if (len > str->capa - str->val.len) len = str->capa - str->val.len;
|
||||
|
||||
for (i = len, j = str->val.len ; i > 0; j++) str->val.ptr[j] = s[--i];
|
||||
str->val.ptr[j] = '\0';
|
||||
str->val.len = j;
|
||||
|
||||
return str->val.len;
|
||||
}
|
||||
|
||||
mio_oow_t FN(ccat) (str_t* str, char_t c)
|
||||
{
|
||||
return FN(ncat)(str, &c, 1);
|
||||
}
|
||||
|
||||
mio_oow_t FN(nccat) (str_t* str, char_t c, mio_oow_t len)
|
||||
{
|
||||
while (len > 0)
|
||||
{
|
||||
if (FN(ncat)(str, &c, 1) == (mio_oow_t)-1) return (mio_oow_t)-1;
|
||||
len--;
|
||||
}
|
||||
return str->val.len;
|
||||
}
|
||||
|
||||
mio_oow_t FN(del) (str_t* str, mio_oow_t index, mio_oow_t size)
|
||||
{
|
||||
if (str->val.ptr && index < str->val.len && size > 0)
|
||||
{
|
||||
mio_oow_t nidx = index + size;
|
||||
if (nidx >= str->val.len)
|
||||
{
|
||||
str->val.ptr[index] = '\0';
|
||||
str->val.len = index;
|
||||
}
|
||||
else
|
||||
{
|
||||
MIO_MEMMOVE (&str->val.ptr[index], &str->val.ptr[nidx], MIO_SIZEOF(*str->val.ptr) * (str->val.len - nidx + 1));
|
||||
str->val.len -= size;
|
||||
}
|
||||
}
|
||||
|
||||
return str->val.len;
|
||||
}
|
||||
|
||||
mio_oow_t FN(amend) (str_t* str, mio_oow_t pos, mio_oow_t len, const char_t* repl)
|
||||
{
|
||||
mio_oow_t max_len;
|
||||
mio_oow_t repl_len = count_chars(repl);
|
||||
|
||||
if (pos >= str->val.len) pos = str->val.len;
|
||||
max_len = str->val.len - pos;
|
||||
if (len > max_len) len = max_len;
|
||||
|
||||
if (len > repl_len)
|
||||
{
|
||||
FN(del) (str, pos, len - repl_len);
|
||||
}
|
||||
else if (len < repl_len)
|
||||
{
|
||||
mio_oow_t old_ecs_len = str->val.len;
|
||||
if (FN(setlen)(str, str->val.len + repl_len - len) == (mio_oow_t)-1) return (mio_oow_t)-1;
|
||||
MIO_MEMMOVE (&str->val.ptr[pos + repl_len], &str->val.ptr[pos + len], MIO_SIZEOF(*repl) * (old_ecs_len - (pos + len)));
|
||||
}
|
||||
|
||||
if (repl_len > 0) MIO_MEMMOVE (&str->val.ptr[pos], repl, MIO_SIZEOF(*repl) * repl_len);
|
||||
return str->val.len;
|
||||
}
|
||||
|
||||
#if 0
|
||||
static int FN(put_bchars) (mio_fmtout_t* fmtout, const mio_bch_t* ptr, mio_oow_t len)
|
||||
{
|
||||
#if defined(BUILD_UECS)
|
||||
mio_uecs_t* uecs = (mio_uecs_t*)fmtout->ctx;
|
||||
if (mio_uecs_ncatbchars(uecs, ptr, len, uecs->gem->cmgr, 1) == (mio_oow_t)-1) return -1;
|
||||
#else
|
||||
mio_becs_t* becs = (mio_becs_t*)fmtout->ctx;
|
||||
if (mio_becs_ncat(becs, ptr, len) == (mio_oow_t)-1) return -1;
|
||||
#endif
|
||||
return 1; /* success. carry on */
|
||||
}
|
||||
|
||||
static int FN(put_uchars) (mio_fmtout_t* fmtout, const mio_uch_t* ptr, mio_oow_t len)
|
||||
{
|
||||
#if defined(BUILD_UECS)
|
||||
mio_uecs_t* uecs = (mio_uecs_t*)fmtout->ctx;
|
||||
if (mio_uecs_ncat(uecs, ptr, len) == (mio_oow_t)-1) return -1;
|
||||
#else
|
||||
mio_becs_t* becs = (mio_becs_t*)fmtout->ctx;
|
||||
if (mio_becs_ncatuchars(becs, ptr, len, becs->gem->cmgr) == (mio_oow_t)-1) return -1;
|
||||
#endif
|
||||
return 1; /* success. carry on */
|
||||
}
|
||||
|
||||
mio_oow_t FN(vfcat) (str_t* str, const char_t* fmt, va_list ap)
|
||||
{
|
||||
mio_fmtout_t fo;
|
||||
|
||||
MIO_MEMSET (&fo, 0, MIO_SIZEOF(fo));
|
||||
fo.mmgr = str->gem->mmgr;
|
||||
fo.putbchars = FN(put_bchars);
|
||||
fo.putuchars = FN(put_uchars);
|
||||
fo.ctx = str;
|
||||
|
||||
#if defined(BUILD_UECS)
|
||||
if (mio_ufmt_outv(&fo, fmt, ap) <= -1) return -1;
|
||||
#else
|
||||
if (mio_bfmt_outv(&fo, fmt, ap) <= -1) return -1;
|
||||
#endif
|
||||
return str->val.len;
|
||||
}
|
||||
|
||||
mio_oow_t FN(fcat) (str_t* str, const char_t* fmt, ...)
|
||||
{
|
||||
mio_oow_t x;
|
||||
va_list ap;
|
||||
|
||||
va_start (ap, fmt);
|
||||
x = FN(vfcat)(str, fmt, ap);
|
||||
va_end (ap);
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
mio_oow_t FN(vfmt) (str_t* str, const char_t* fmt, va_list ap)
|
||||
{
|
||||
mio_fmtout_t fo;
|
||||
|
||||
MIO_MEMSET (&fo, 0, MIO_SIZEOF(fo));
|
||||
fo.mmgr = str->gem->mmgr;
|
||||
fo.putbchars = FN(put_bchars);
|
||||
fo.putuchars = FN(put_uchars);
|
||||
fo.ctx = str;
|
||||
|
||||
FN(clear) (str);
|
||||
|
||||
#if defined(BUILD_UECS)
|
||||
if (mio_ufmt_outv(&fo, fmt, ap) <= -1) return -1;
|
||||
#else
|
||||
if (mio_bfmt_outv(&fo, fmt, ap) <= -1) return -1;
|
||||
#endif
|
||||
return str->val.len;
|
||||
}
|
||||
|
||||
mio_oow_t FN(fmt) (str_t* str, const char_t* fmt, ...)
|
||||
{
|
||||
mio_oow_t x;
|
||||
va_list ap;
|
||||
|
||||
va_start (ap, fmt);
|
||||
x = FN(vfmt)(str, fmt, ap);
|
||||
va_end (ap);
|
||||
|
||||
return x;
|
||||
}
|
||||
#endif
|
103
mio/lib/ecs.c
Normal file
103
mio/lib/ecs.c
Normal file
@ -0,0 +1,103 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
Copyright (c) 2006-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.
|
||||
*/
|
||||
|
||||
#include "mio-ecs.h"
|
||||
#include "mio-prv.h"
|
||||
|
||||
#define _FN(type,verb) mio_ ## type ## _ ## verb
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
#undef FN
|
||||
#undef T
|
||||
#undef str_t
|
||||
#undef char_t
|
||||
#undef cstr_t
|
||||
#undef count_chars
|
||||
#define FN(verb) _FN(becs,verb)
|
||||
#define T(x) MIO_BT(x)
|
||||
#define str_t mio_becs_t
|
||||
#define char_t mio_bch_t
|
||||
#define cstr_t mio_bcs_t
|
||||
#define count_chars(x) mio_count_bcstr(x)
|
||||
#define BUILD_BECS
|
||||
#include "ecs-imp.h"
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
#undef FN
|
||||
#undef T
|
||||
#undef str_t
|
||||
#undef char_t
|
||||
#undef cstr_t
|
||||
#undef count_chars
|
||||
#define FN(verb) _FN(uecs,verb)
|
||||
#define T(x) MIO_UT(x)
|
||||
#define str_t mio_uecs_t
|
||||
#define char_t mio_uch_t
|
||||
#define cstr_t mio_ucs_t
|
||||
#define count_chars(x) mio_count_ucstr(x)
|
||||
#define BUILD_UECS
|
||||
#include "ecs-imp.h"
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
mio_oow_t mio_becs_ncatuchars (mio_becs_t* str, const mio_uch_t* s, mio_oow_t len, mio_cmgr_t* cmgr)
|
||||
{
|
||||
mio_oow_t bcslen, ucslen;
|
||||
|
||||
ucslen = len;
|
||||
if (mio_conv_uchars_to_bchars_with_cmgr(s, &ucslen, MIO_NULL, &bcslen, cmgr) <= -1) return (mio_oow_t)-1;
|
||||
|
||||
if (mio_becs_resize_for_ncat(str, bcslen) <= 0) return -1;
|
||||
|
||||
ucslen = len;
|
||||
bcslen = str->capa - str->val.len;
|
||||
mio_conv_uchars_to_bchars_with_cmgr (s, &ucslen, &str->val.ptr[str->val.len], &bcslen, cmgr);
|
||||
str->val.len += bcslen;
|
||||
str->val.ptr[str->val.len] = '\0';
|
||||
|
||||
return str->val.len;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
mio_oow_t bcslen, ucslen;
|
||||
|
||||
bcslen = len;
|
||||
if (mio_conv_bchars_to_uchars_with_cmgr(s, &bcslen, MIO_NULL, &ucslen, cmgr, all) <= -1) return (mio_oow_t)-1;
|
||||
|
||||
if (mio_uecs_resize_for_ncat(str, ucslen) <= 0) return -1;
|
||||
|
||||
bcslen = len;
|
||||
ucslen = str->capa - str->val.len;
|
||||
mio_conv_bchars_to_uchars_with_cmgr (s, &bcslen, &str->val.ptr[str->val.len], &ucslen, cmgr, all);
|
||||
str->val.len += ucslen;
|
||||
str->val.ptr[str->val.len] = '\0';
|
||||
|
||||
return str->val.len;
|
||||
}
|
732
mio/lib/htb.c
Normal file
732
mio/lib/htb.c
Normal file
@ -0,0 +1,732 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
Copyright (c) 2006-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.
|
||||
*/
|
||||
|
||||
#include <mio-htb.h>
|
||||
#include "mio-prv.h"
|
||||
|
||||
#define pair_t mio_htb_pair_t
|
||||
#define copier_t mio_htb_copier_t
|
||||
#define freeer_t mio_htb_freeer_t
|
||||
#define hasher_t mio_htb_hasher_t
|
||||
#define comper_t mio_htb_comper_t
|
||||
#define keeper_t mio_htb_keeper_t
|
||||
#define sizer_t mio_htb_sizer_t
|
||||
#define walker_t mio_htb_walker_t
|
||||
#define cbserter_t mio_htb_cbserter_t
|
||||
#define style_t mio_htb_style_t
|
||||
#define style_kind_t mio_htb_style_kind_t
|
||||
|
||||
#define KPTR(p) MIO_HTB_KPTR(p)
|
||||
#define KLEN(p) MIO_HTB_KLEN(p)
|
||||
#define VPTR(p) MIO_HTB_VPTR(p)
|
||||
#define VLEN(p) MIO_HTB_VLEN(p)
|
||||
#define NEXT(p) MIO_HTB_NEXT(p)
|
||||
|
||||
#define KTOB(htb,len) ((len)*(htb)->scale[MIO_HTB_KEY])
|
||||
#define VTOB(htb,len) ((len)*(htb)->scale[MIO_HTB_VAL])
|
||||
|
||||
MIO_INLINE pair_t* mio_htb_allocpair (mio_htb_t* htb, void* kptr, mio_oow_t klen, void* vptr, mio_oow_t vlen)
|
||||
{
|
||||
pair_t* n;
|
||||
copier_t kcop, vcop;
|
||||
mio_oow_t as;
|
||||
|
||||
kcop = htb->style->copier[MIO_HTB_KEY];
|
||||
vcop = htb->style->copier[MIO_HTB_VAL];
|
||||
|
||||
as = MIO_SIZEOF(pair_t);
|
||||
if (kcop == MIO_HTB_COPIER_INLINE) as += MIO_ALIGN_POW2(KTOB(htb,klen), MIO_SIZEOF_VOID_P);
|
||||
if (vcop == MIO_HTB_COPIER_INLINE) as += VTOB(htb,vlen);
|
||||
|
||||
n = (pair_t*) mio_allocmem(htb->mio, as);
|
||||
if (MIO_UNLIKELY(!n)) return MIO_NULL;
|
||||
|
||||
NEXT(n) = MIO_NULL;
|
||||
|
||||
KLEN(n) = klen;
|
||||
if (kcop == MIO_HTB_COPIER_SIMPLE)
|
||||
{
|
||||
KPTR(n) = kptr;
|
||||
}
|
||||
else if (kcop == MIO_HTB_COPIER_INLINE)
|
||||
{
|
||||
KPTR(n) = n + 1;
|
||||
/* if kptr is MIO_NULL, the inline copier does not fill
|
||||
* the actual key area */
|
||||
if (kptr) MIO_MEMCPY (KPTR(n), kptr, KTOB(htb,klen));
|
||||
}
|
||||
else
|
||||
{
|
||||
KPTR(n) = kcop(htb, kptr, klen);
|
||||
if (KPTR(n) == MIO_NULL)
|
||||
{
|
||||
mio_freemem (htb->mio, n);
|
||||
return MIO_NULL;
|
||||
}
|
||||
}
|
||||
|
||||
VLEN(n) = vlen;
|
||||
if (vcop == MIO_HTB_COPIER_SIMPLE)
|
||||
{
|
||||
VPTR(n) = vptr;
|
||||
}
|
||||
else if (vcop == MIO_HTB_COPIER_INLINE)
|
||||
{
|
||||
VPTR(n) = n + 1;
|
||||
if (kcop == MIO_HTB_COPIER_INLINE)
|
||||
VPTR(n) = (mio_uint8_t*)VPTR(n) + MIO_ALIGN_POW2(KTOB(htb,klen), MIO_SIZEOF_VOID_P);
|
||||
/* if vptr is MIO_NULL, the inline copier does not fill
|
||||
* the actual value area */
|
||||
if (vptr) MIO_MEMCPY (VPTR(n), vptr, VTOB(htb,vlen));
|
||||
}
|
||||
else
|
||||
{
|
||||
VPTR(n) = vcop (htb, vptr, vlen);
|
||||
if (VPTR(n) != MIO_NULL)
|
||||
{
|
||||
if (htb->style->freeer[MIO_HTB_KEY] != MIO_NULL)
|
||||
htb->style->freeer[MIO_HTB_KEY] (htb, KPTR(n), KLEN(n));
|
||||
mio_freemem (htb->mio, n);
|
||||
return MIO_NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
MIO_INLINE void mio_htb_freepair (mio_htb_t* htb, pair_t* pair)
|
||||
{
|
||||
if (htb->style->freeer[MIO_HTB_KEY] != MIO_NULL)
|
||||
htb->style->freeer[MIO_HTB_KEY] (htb, KPTR(pair), KLEN(pair));
|
||||
if (htb->style->freeer[MIO_HTB_VAL] != MIO_NULL)
|
||||
htb->style->freeer[MIO_HTB_VAL] (htb, VPTR(pair), VLEN(pair));
|
||||
mio_freemem (htb->mio, pair);
|
||||
}
|
||||
|
||||
static MIO_INLINE pair_t* change_pair_val (mio_htb_t* htb, pair_t* pair, void* vptr, mio_oow_t vlen)
|
||||
{
|
||||
if (VPTR(pair) == vptr && VLEN(pair) == vlen)
|
||||
{
|
||||
/* if the old value and the new value are the same,
|
||||
* it just calls the handler for this condition.
|
||||
* No value replacement occurs. */
|
||||
if (htb->style->keeper != MIO_NULL)
|
||||
{
|
||||
htb->style->keeper (htb, vptr, vlen);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
copier_t vcop = htb->style->copier[MIO_HTB_VAL];
|
||||
void* ovptr = VPTR(pair);
|
||||
mio_oow_t ovlen = VLEN(pair);
|
||||
|
||||
/* place the new value according to the copier */
|
||||
if (vcop == MIO_HTB_COPIER_SIMPLE)
|
||||
{
|
||||
VPTR(pair) = vptr;
|
||||
VLEN(pair) = vlen;
|
||||
}
|
||||
else if (vcop == MIO_HTB_COPIER_INLINE)
|
||||
{
|
||||
if (ovlen == vlen)
|
||||
{
|
||||
if (vptr) MIO_MEMCPY (VPTR(pair), vptr, VTOB(htb,vlen));
|
||||
}
|
||||
else
|
||||
{
|
||||
/* need to reconstruct the pair */
|
||||
pair_t* p = mio_htb_allocpair(htb, KPTR(pair), KLEN(pair), vptr, vlen);
|
||||
if (MIO_UNLIKELY(!p)) return MIO_NULL;
|
||||
mio_htb_freepair (htb, pair);
|
||||
return p;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
void* nvptr = vcop(htb, vptr, vlen);
|
||||
if (MIO_UNLIKELY(!nvptr)) return MIO_NULL;
|
||||
VPTR(pair) = nvptr;
|
||||
VLEN(pair) = vlen;
|
||||
}
|
||||
|
||||
/* free up the old value */
|
||||
if (htb->style->freeer[MIO_HTB_VAL] != MIO_NULL)
|
||||
{
|
||||
htb->style->freeer[MIO_HTB_VAL] (htb, ovptr, ovlen);
|
||||
}
|
||||
}
|
||||
|
||||
return pair;
|
||||
}
|
||||
|
||||
static style_t style[] =
|
||||
{
|
||||
/* == MIO_HTB_STYLE_DEFAULT == */
|
||||
{
|
||||
{
|
||||
MIO_HTB_COPIER_DEFAULT,
|
||||
MIO_HTB_COPIER_DEFAULT
|
||||
},
|
||||
{
|
||||
MIO_HTB_FREEER_DEFAULT,
|
||||
MIO_HTB_FREEER_DEFAULT
|
||||
},
|
||||
MIO_HTB_COMPER_DEFAULT,
|
||||
MIO_HTB_KEEPER_DEFAULT,
|
||||
MIO_HTB_SIZER_DEFAULT,
|
||||
MIO_HTB_HASHER_DEFAULT
|
||||
},
|
||||
|
||||
/* == MIO_HTB_STYLE_INLINE_COPIERS == */
|
||||
{
|
||||
{
|
||||
MIO_HTB_COPIER_INLINE,
|
||||
MIO_HTB_COPIER_INLINE
|
||||
},
|
||||
{
|
||||
MIO_HTB_FREEER_DEFAULT,
|
||||
MIO_HTB_FREEER_DEFAULT
|
||||
},
|
||||
MIO_HTB_COMPER_DEFAULT,
|
||||
MIO_HTB_KEEPER_DEFAULT,
|
||||
MIO_HTB_SIZER_DEFAULT,
|
||||
MIO_HTB_HASHER_DEFAULT
|
||||
},
|
||||
|
||||
/* == MIO_HTB_STYLE_INLINE_KEY_COPIER == */
|
||||
{
|
||||
{
|
||||
MIO_HTB_COPIER_INLINE,
|
||||
MIO_HTB_COPIER_DEFAULT
|
||||
},
|
||||
{
|
||||
MIO_HTB_FREEER_DEFAULT,
|
||||
MIO_HTB_FREEER_DEFAULT
|
||||
},
|
||||
MIO_HTB_COMPER_DEFAULT,
|
||||
MIO_HTB_KEEPER_DEFAULT,
|
||||
MIO_HTB_SIZER_DEFAULT,
|
||||
MIO_HTB_HASHER_DEFAULT
|
||||
},
|
||||
|
||||
/* == MIO_HTB_STYLE_INLINE_VALUE_COPIER == */
|
||||
{
|
||||
{
|
||||
MIO_HTB_COPIER_DEFAULT,
|
||||
MIO_HTB_COPIER_INLINE
|
||||
},
|
||||
{
|
||||
MIO_HTB_FREEER_DEFAULT,
|
||||
MIO_HTB_FREEER_DEFAULT
|
||||
},
|
||||
MIO_HTB_COMPER_DEFAULT,
|
||||
MIO_HTB_KEEPER_DEFAULT,
|
||||
MIO_HTB_SIZER_DEFAULT,
|
||||
MIO_HTB_HASHER_DEFAULT
|
||||
}
|
||||
};
|
||||
|
||||
const style_t* mio_get_htb_style (style_kind_t kind)
|
||||
{
|
||||
return &style[kind];
|
||||
}
|
||||
|
||||
mio_htb_t* mio_htb_open (mio_t* mio, mio_oow_t xtnsize, mio_oow_t capa, int factor, int kscale, int vscale)
|
||||
{
|
||||
mio_htb_t* htb;
|
||||
|
||||
htb = (mio_htb_t*)mio_allocmem(mio, MIO_SIZEOF(mio_htb_t) + xtnsize);
|
||||
if (MIO_UNLIKELY(!htb)) return MIO_NULL;
|
||||
|
||||
if (mio_htb_init(htb, mio, capa, factor, kscale, vscale) <= -1)
|
||||
{
|
||||
mio_freemem (mio, htb);
|
||||
return MIO_NULL;
|
||||
}
|
||||
|
||||
MIO_MEMSET (htb + 1, 0, xtnsize);
|
||||
return htb;
|
||||
}
|
||||
|
||||
void mio_htb_close (mio_htb_t* htb)
|
||||
{
|
||||
mio_htb_fini (htb);
|
||||
mio_freemem (htb->mio, htb);
|
||||
}
|
||||
|
||||
int mio_htb_init (mio_htb_t* htb, mio_t* mio, mio_oow_t capa, int factor, int kscale, int vscale)
|
||||
{
|
||||
/* The initial capacity should be greater than 0.
|
||||
* Otherwise, it is adjusted to 1 in the release mode */
|
||||
MIO_ASSERT (mio, capa > 0);
|
||||
|
||||
/* The load factor should be between 0 and 100 inclusive.
|
||||
* In the release mode, a value out of the range is adjusted to 100 */
|
||||
MIO_ASSERT (mio, factor >= 0 && factor <= 100);
|
||||
|
||||
MIO_ASSERT (mio, kscale >= 0 && kscale <= MIO_TYPE_MAX(mio_uint8_t));
|
||||
MIO_ASSERT (mio, vscale >= 0 && vscale <= MIO_TYPE_MAX(mio_uint8_t));
|
||||
|
||||
/* some initial adjustment */
|
||||
if (capa <= 0) capa = 1;
|
||||
if (factor > 100) factor = 100;
|
||||
|
||||
/* do not zero out the extension */
|
||||
MIO_MEMSET (htb, 0, MIO_SIZEOF(*htb));
|
||||
htb->mio = mio;
|
||||
|
||||
htb->bucket = mio_allocmem(mio, capa * MIO_SIZEOF(pair_t*));
|
||||
if (MIO_UNLIKELY(!htb->bucket)) return -1;
|
||||
|
||||
/*for (i = 0; i < capa; i++) htb->bucket[i] = MIO_NULL;*/
|
||||
MIO_MEMSET (htb->bucket, 0, capa * MIO_SIZEOF(pair_t*));
|
||||
|
||||
htb->factor = factor;
|
||||
htb->scale[MIO_HTB_KEY] = (kscale < 1)? 1: kscale;
|
||||
htb->scale[MIO_HTB_VAL] = (vscale < 1)? 1: vscale;
|
||||
|
||||
htb->size = 0;
|
||||
htb->capa = capa;
|
||||
htb->threshold = htb->capa * htb->factor / 100;
|
||||
if (htb->capa > 0 && htb->threshold <= 0) htb->threshold = 1;
|
||||
|
||||
htb->style = &style[0];
|
||||
return 0;
|
||||
}
|
||||
|
||||
void mio_htb_fini (mio_htb_t* htb)
|
||||
{
|
||||
mio_htb_clear (htb);
|
||||
mio_freemem (htb->mio, htb->bucket);
|
||||
}
|
||||
|
||||
const style_t* mio_htb_getstyle (const mio_htb_t* htb)
|
||||
{
|
||||
return htb->style;
|
||||
}
|
||||
|
||||
void mio_htb_setstyle (mio_htb_t* htb, const style_t* style)
|
||||
{
|
||||
MIO_ASSERT (htb->mio, style != MIO_NULL);
|
||||
htb->style = style;
|
||||
}
|
||||
|
||||
mio_oow_t mio_htb_getsize (const mio_htb_t* htb)
|
||||
{
|
||||
return htb->size;
|
||||
}
|
||||
|
||||
mio_oow_t mio_htb_getcapa (const mio_htb_t* htb)
|
||||
{
|
||||
return htb->capa;
|
||||
}
|
||||
|
||||
pair_t* mio_htb_search (const mio_htb_t* htb, const void* kptr, mio_oow_t klen)
|
||||
{
|
||||
pair_t* pair;
|
||||
mio_oow_t hc;
|
||||
|
||||
hc = htb->style->hasher(htb,kptr,klen) % htb->capa;
|
||||
pair = htb->bucket[hc];
|
||||
|
||||
while (pair != MIO_NULL)
|
||||
{
|
||||
if (htb->style->comper(htb, KPTR(pair), KLEN(pair), kptr, klen) == 0)
|
||||
{
|
||||
return pair;
|
||||
}
|
||||
|
||||
pair = NEXT(pair);
|
||||
}
|
||||
|
||||
mio_seterrnum (htb->mio, MIO_ENOENT);
|
||||
return MIO_NULL;
|
||||
}
|
||||
|
||||
static MIO_INLINE int reorganize (mio_htb_t* htb)
|
||||
{
|
||||
mio_oow_t i, hc, new_capa;
|
||||
pair_t** new_buck;
|
||||
|
||||
if (htb->style->sizer)
|
||||
{
|
||||
new_capa = htb->style->sizer (htb, htb->capa + 1);
|
||||
|
||||
/* if no change in capacity, return success
|
||||
* without reorganization */
|
||||
if (new_capa == htb->capa) return 0;
|
||||
|
||||
/* adjust to 1 if the new capacity is not reasonable */
|
||||
if (new_capa <= 0) new_capa = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* the bucket is doubled until it grows up to 65536 slots.
|
||||
* once it has reached it, it grows by 65536 slots */
|
||||
new_capa = (htb->capa >= 65536)? (htb->capa + 65536): (htb->capa << 1);
|
||||
}
|
||||
|
||||
new_buck = (pair_t**)mio_allocmem(htb->mio, new_capa * MIO_SIZEOF(pair_t*));
|
||||
if (MIO_UNLIKELY(!new_buck))
|
||||
{
|
||||
/* reorganization is disabled once it fails */
|
||||
htb->threshold = 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*for (i = 0; i < new_capa; i++) new_buck[i] = MIO_NULL;*/
|
||||
MIO_MEMSET (new_buck, 0, new_capa * MIO_SIZEOF(pair_t*));
|
||||
|
||||
for (i = 0; i < htb->capa; i++)
|
||||
{
|
||||
pair_t* pair = htb->bucket[i];
|
||||
|
||||
while (pair != MIO_NULL)
|
||||
{
|
||||
pair_t* next = NEXT(pair);
|
||||
|
||||
hc = htb->style->hasher(htb, KPTR(pair), KLEN(pair)) % new_capa;
|
||||
|
||||
NEXT(pair) = new_buck[hc];
|
||||
new_buck[hc] = pair;
|
||||
|
||||
pair = next;
|
||||
}
|
||||
}
|
||||
|
||||
mio_freemem (htb->mio, htb->bucket);
|
||||
htb->bucket = new_buck;
|
||||
htb->capa = new_capa;
|
||||
htb->threshold = htb->capa * htb->factor / 100;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* insert options */
|
||||
#define UPSERT 1
|
||||
#define UPDATE 2
|
||||
#define ENSERT 3
|
||||
#define INSERT 4
|
||||
|
||||
static MIO_INLINE pair_t* insert (mio_htb_t* htb, void* kptr, mio_oow_t klen, void* vptr, mio_oow_t vlen, int opt)
|
||||
{
|
||||
pair_t* pair, * p, * prev, * next;
|
||||
mio_oow_t hc;
|
||||
|
||||
hc = htb->style->hasher(htb,kptr,klen) % htb->capa;
|
||||
pair = htb->bucket[hc];
|
||||
prev = MIO_NULL;
|
||||
|
||||
while (pair != MIO_NULL)
|
||||
{
|
||||
next = NEXT(pair);
|
||||
|
||||
if (htb->style->comper (htb, KPTR(pair), KLEN(pair), kptr, klen) == 0)
|
||||
{
|
||||
/* found a pair with a matching key */
|
||||
switch (opt)
|
||||
{
|
||||
case UPSERT:
|
||||
case UPDATE:
|
||||
p = change_pair_val (htb, pair, vptr, vlen);
|
||||
if (p == MIO_NULL)
|
||||
{
|
||||
/* error in changing the value */
|
||||
return MIO_NULL;
|
||||
}
|
||||
if (p != pair)
|
||||
{
|
||||
/* old pair destroyed. new pair reallocated.
|
||||
* relink to include the new pair but to drop
|
||||
* the old pair. */
|
||||
if (prev == MIO_NULL) htb->bucket[hc] = p;
|
||||
else NEXT(prev) = p;
|
||||
NEXT(p) = next;
|
||||
}
|
||||
return p;
|
||||
|
||||
case ENSERT:
|
||||
/* return existing pair */
|
||||
return pair;
|
||||
|
||||
case INSERT:
|
||||
/* return failure */
|
||||
mio_seterrnum (htb->mio, MIO_EEXIST);
|
||||
return MIO_NULL;
|
||||
}
|
||||
}
|
||||
|
||||
prev = pair;
|
||||
pair = next;
|
||||
}
|
||||
|
||||
if (opt == UPDATE)
|
||||
{
|
||||
mio_seterrnum (htb->mio, MIO_ENOENT);
|
||||
return MIO_NULL;
|
||||
}
|
||||
|
||||
if (htb->threshold > 0 && htb->size >= htb->threshold)
|
||||
{
|
||||
/* ingore reorganization error as it simply means
|
||||
* more bucket collision and performance penalty. */
|
||||
if (reorganize(htb) == 0)
|
||||
{
|
||||
hc = htb->style->hasher(htb,kptr,klen) % htb->capa;
|
||||
}
|
||||
}
|
||||
|
||||
MIO_ASSERT (htb->mio, pair == MIO_NULL);
|
||||
|
||||
pair = mio_htb_allocpair (htb, kptr, klen, vptr, vlen);
|
||||
if (MIO_UNLIKELY(!pair)) return MIO_NULL; /* error */
|
||||
|
||||
NEXT(pair) = htb->bucket[hc];
|
||||
htb->bucket[hc] = pair;
|
||||
htb->size++;
|
||||
|
||||
return pair; /* new key added */
|
||||
}
|
||||
|
||||
pair_t* mio_htb_upsert (mio_htb_t* htb, void* kptr, mio_oow_t klen, void* vptr, mio_oow_t vlen)
|
||||
{
|
||||
return insert (htb, kptr, klen, vptr, vlen, UPSERT);
|
||||
}
|
||||
|
||||
pair_t* mio_htb_ensert (mio_htb_t* htb, void* kptr, mio_oow_t klen, void* vptr, mio_oow_t vlen)
|
||||
{
|
||||
return insert (htb, kptr, klen, vptr, vlen, ENSERT);
|
||||
}
|
||||
|
||||
pair_t* mio_htb_insert (mio_htb_t* htb, void* kptr, mio_oow_t klen, void* vptr, mio_oow_t vlen)
|
||||
{
|
||||
return insert (htb, kptr, klen, vptr, vlen, INSERT);
|
||||
}
|
||||
|
||||
|
||||
pair_t* mio_htb_update (mio_htb_t* htb, void* kptr, mio_oow_t klen, void* vptr, mio_oow_t vlen)
|
||||
{
|
||||
return insert (htb, kptr, klen, vptr, vlen, UPDATE);
|
||||
}
|
||||
|
||||
pair_t* mio_htb_cbsert (mio_htb_t* htb, void* kptr, mio_oow_t klen, cbserter_t cbserter, void* ctx)
|
||||
{
|
||||
pair_t* pair, * p, * prev, * next;
|
||||
mio_oow_t hc;
|
||||
|
||||
hc = htb->style->hasher(htb,kptr,klen) % htb->capa;
|
||||
pair = htb->bucket[hc];
|
||||
prev = MIO_NULL;
|
||||
|
||||
while (pair != MIO_NULL)
|
||||
{
|
||||
next = NEXT(pair);
|
||||
|
||||
if (htb->style->comper(htb, KPTR(pair), KLEN(pair), kptr, klen) == 0)
|
||||
{
|
||||
/* found a pair with a matching key */
|
||||
p = cbserter(htb, pair, kptr, klen, ctx);
|
||||
if (p == MIO_NULL)
|
||||
{
|
||||
/* error returned by the callback function */
|
||||
return MIO_NULL;
|
||||
}
|
||||
if (p != pair)
|
||||
{
|
||||
/* old pair destroyed. new pair reallocated.
|
||||
* relink to include the new pair but to drop
|
||||
* the old pair. */
|
||||
if (prev == MIO_NULL) htb->bucket[hc] = p;
|
||||
else NEXT(prev) = p;
|
||||
NEXT(p) = next;
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
prev = pair;
|
||||
pair = next;
|
||||
}
|
||||
|
||||
if (htb->threshold > 0 && htb->size >= htb->threshold)
|
||||
{
|
||||
/* ingore reorganization error as it simply means
|
||||
* more bucket collision and performance penalty. */
|
||||
if (reorganize(htb) == 0)
|
||||
{
|
||||
hc = htb->style->hasher(htb,kptr,klen) % htb->capa;
|
||||
}
|
||||
}
|
||||
|
||||
MIO_ASSERT (htb->mio, pair == MIO_NULL);
|
||||
|
||||
pair = cbserter(htb, MIO_NULL, kptr, klen, ctx);
|
||||
if (MIO_UNLIKELY(!pair)) return MIO_NULL; /* error */
|
||||
|
||||
NEXT(pair) = htb->bucket[hc];
|
||||
htb->bucket[hc] = pair;
|
||||
htb->size++;
|
||||
|
||||
return pair; /* new key added */
|
||||
}
|
||||
|
||||
int mio_htb_delete (mio_htb_t* htb, const void* kptr, mio_oow_t klen)
|
||||
{
|
||||
pair_t* pair, * prev;
|
||||
mio_oow_t hc;
|
||||
|
||||
hc = htb->style->hasher(htb,kptr,klen) % htb->capa;
|
||||
pair = htb->bucket[hc];
|
||||
prev = MIO_NULL;
|
||||
|
||||
while (pair != MIO_NULL)
|
||||
{
|
||||
if (htb->style->comper(htb, KPTR(pair), KLEN(pair), kptr, klen) == 0)
|
||||
{
|
||||
if (prev == MIO_NULL)
|
||||
htb->bucket[hc] = NEXT(pair);
|
||||
else NEXT(prev) = NEXT(pair);
|
||||
|
||||
mio_htb_freepair (htb, pair);
|
||||
htb->size--;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
prev = pair;
|
||||
pair = NEXT(pair);
|
||||
}
|
||||
|
||||
mio_seterrnum (htb->mio, MIO_ENOENT);
|
||||
return -1;
|
||||
}
|
||||
|
||||
void mio_htb_clear (mio_htb_t* htb)
|
||||
{
|
||||
mio_oow_t i;
|
||||
pair_t* pair, * next;
|
||||
|
||||
for (i = 0; i < htb->capa; i++)
|
||||
{
|
||||
pair = htb->bucket[i];
|
||||
|
||||
while (pair != MIO_NULL)
|
||||
{
|
||||
next = NEXT(pair);
|
||||
mio_htb_freepair (htb, pair);
|
||||
htb->size--;
|
||||
pair = next;
|
||||
}
|
||||
|
||||
htb->bucket[i] = MIO_NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void mio_htb_walk (mio_htb_t* htb, walker_t walker, void* ctx)
|
||||
{
|
||||
mio_oow_t i;
|
||||
pair_t* pair, * next;
|
||||
|
||||
for (i = 0; i < htb->capa; i++)
|
||||
{
|
||||
pair = htb->bucket[i];
|
||||
|
||||
while (pair != MIO_NULL)
|
||||
{
|
||||
next = NEXT(pair);
|
||||
if (walker(htb, pair, ctx) == MIO_HTB_WALK_STOP) return;
|
||||
pair = next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void mio_init_htb_itr (mio_htb_itr_t* itr)
|
||||
{
|
||||
itr->pair = MIO_NULL;
|
||||
itr->buckno = 0;
|
||||
}
|
||||
|
||||
pair_t* mio_htb_getfirstpair (mio_htb_t* htb, mio_htb_itr_t* itr)
|
||||
{
|
||||
mio_oow_t i;
|
||||
pair_t* pair;
|
||||
|
||||
for (i = 0; i < htb->capa; i++)
|
||||
{
|
||||
pair = htb->bucket[i];
|
||||
if (pair)
|
||||
{
|
||||
itr->buckno = i;
|
||||
itr->pair = pair;
|
||||
return pair;
|
||||
}
|
||||
}
|
||||
|
||||
return MIO_NULL;
|
||||
}
|
||||
|
||||
pair_t* mio_htb_getnextpair (mio_htb_t* htb, mio_htb_itr_t* itr)
|
||||
{
|
||||
mio_oow_t i;
|
||||
pair_t* pair;
|
||||
|
||||
pair = NEXT(itr->pair);
|
||||
if (pair)
|
||||
{
|
||||
/* no change in bucket number */
|
||||
itr->pair = pair;
|
||||
return pair;
|
||||
}
|
||||
|
||||
for (i = itr->buckno + 1; i < htb->capa; i++)
|
||||
{
|
||||
pair = htb->bucket[i];
|
||||
if (pair)
|
||||
{
|
||||
itr->buckno = i;
|
||||
itr->pair = pair;
|
||||
return pair;
|
||||
}
|
||||
}
|
||||
|
||||
return MIO_NULL;
|
||||
}
|
||||
|
||||
mio_oow_t mio_htb_dflhash (const mio_htb_t* htb, const void* kptr, mio_oow_t klen)
|
||||
{
|
||||
mio_oow_t h;
|
||||
MIO_HASH_BYTES (h, kptr, klen);
|
||||
return h ;
|
||||
}
|
||||
|
||||
int mio_htb_dflcomp (const mio_htb_t* htb, const void* kptr1, mio_oow_t klen1, const void* kptr2, mio_oow_t klen2)
|
||||
{
|
||||
if (klen1 == klen2) return MIO_MEMCMP (kptr1, kptr2, KTOB(htb,klen1));
|
||||
/* it just returns 1 to indicate that they are different. */
|
||||
return 1;
|
||||
}
|
||||
|
@ -88,9 +88,9 @@ static MIO_INLINE int xdigit_to_num (mio_bch_t c)
|
||||
}
|
||||
|
||||
|
||||
static MIO_INLINE int push_to_buffer (mio_htrd_t* htrd, mio_htob_t* octb, const mio_bch_t* ptr, mio_size_t len)
|
||||
static MIO_INLINE int push_to_buffer (mio_htrd_t* htrd, mio_htob_t* octb, const mio_bch_t* ptr, mio_oow_t len)
|
||||
{
|
||||
if (mio_mbs_ncat (octb, ptr, len) == (mio_size_t)-1)
|
||||
if (mio_mbs_ncat (octb, ptr, len) == (mio_oow_t)-1)
|
||||
{
|
||||
htrd->errnum = MIO_HTRD_ENOMEM;
|
||||
return -1;
|
||||
@ -98,7 +98,7 @@ static MIO_INLINE int push_to_buffer (mio_htrd_t* htrd, mio_htob_t* octb, const
|
||||
return 0;
|
||||
}
|
||||
|
||||
static MIO_INLINE int push_content (mio_htrd_t* htrd, const mio_bch_t* ptr, mio_size_t len)
|
||||
static MIO_INLINE int push_content (mio_htrd_t* htrd, const mio_bch_t* ptr, mio_oow_t len)
|
||||
{
|
||||
MIO_ASSERT (len > 0);
|
||||
|
||||
@ -126,7 +126,7 @@ static MIO_INLINE void clear_feed (mio_htrd_t* htrd)
|
||||
MIO_MEMSET (&htrd->fed.s, 0, MIO_SIZEOF(htrd->fed.s));
|
||||
}
|
||||
|
||||
mio_htrd_t* mio_htrd_open (mio_mmgr_t* mmgr, mio_size_t xtnsize)
|
||||
mio_htrd_t* mio_htrd_open (mio_mmgr_t* mmgr, mio_oow_t xtnsize)
|
||||
{
|
||||
mio_htrd_t* htrd;
|
||||
|
||||
@ -558,7 +558,7 @@ static int capture_connection (mio_htrd_t* htrd, mio_htb_pair_t* pair)
|
||||
|
||||
static int capture_content_length (mio_htrd_t* htrd, mio_htb_pair_t* pair)
|
||||
{
|
||||
mio_size_t len = 0, off = 0, tmp;
|
||||
mio_oow_t len = 0, off = 0, tmp;
|
||||
const mio_bch_t* ptr;
|
||||
mio_htre_hdrval_t* val;
|
||||
|
||||
@ -671,7 +671,7 @@ static MIO_INLINE int capture_key_header (mio_htrd_t* htrd, mio_htb_pair_t* pair
|
||||
static struct
|
||||
{
|
||||
const mio_bch_t* ptr;
|
||||
mio_size_t len;
|
||||
mio_oow_t len;
|
||||
int (*handler) (mio_htrd_t*, mio_htb_pair_t*);
|
||||
} hdrtab[] =
|
||||
{
|
||||
@ -683,7 +683,7 @@ static MIO_INLINE int capture_key_header (mio_htrd_t* htrd, mio_htb_pair_t* pair
|
||||
};
|
||||
|
||||
int n;
|
||||
mio_size_t mid, count, base = 0;
|
||||
mio_oow_t mid, count, base = 0;
|
||||
|
||||
/* perform binary search */
|
||||
for (count = MIO_COUNTOF(hdrtab); count > 0; count /= 2)
|
||||
@ -712,12 +712,12 @@ struct hdr_cbserter_ctx_t
|
||||
{
|
||||
mio_htrd_t* htrd;
|
||||
void* vptr;
|
||||
mio_size_t vlen;
|
||||
mio_oow_t vlen;
|
||||
};
|
||||
|
||||
static mio_htb_pair_t* hdr_cbserter (
|
||||
mio_htb_t* htb, mio_htb_pair_t* pair,
|
||||
void* kptr, mio_size_t klen, void* ctx)
|
||||
void* kptr, mio_oow_t klen, void* ctx)
|
||||
{
|
||||
struct hdr_cbserter_ctx_t* tx = (struct hdr_cbserter_ctx_t*)ctx;
|
||||
|
||||
@ -824,7 +824,7 @@ mio_bch_t* parse_header_field (mio_htrd_t* htrd, mio_bch_t* line, mio_htb_t* tab
|
||||
struct
|
||||
{
|
||||
mio_bch_t* ptr;
|
||||
mio_size_t len;
|
||||
mio_oow_t len;
|
||||
} name, value;
|
||||
|
||||
#if 0
|
||||
@ -928,7 +928,7 @@ badhdr:
|
||||
}
|
||||
|
||||
static MIO_INLINE int parse_initial_line_and_headers (
|
||||
mio_htrd_t* htrd, const mio_bch_t* req, mio_size_t rlen)
|
||||
mio_htrd_t* htrd, const mio_bch_t* req, mio_oow_t rlen)
|
||||
{
|
||||
mio_bch_t* p;
|
||||
|
||||
@ -980,7 +980,7 @@ static MIO_INLINE int parse_initial_line_and_headers (
|
||||
#define GET_CHUNK_CRLF 3
|
||||
#define GET_CHUNK_TRAILERS 4
|
||||
|
||||
static const mio_bch_t* getchunklen (mio_htrd_t* htrd, const mio_bch_t* ptr, mio_size_t len)
|
||||
static const mio_bch_t* getchunklen (mio_htrd_t* htrd, const mio_bch_t* ptr, mio_oow_t len)
|
||||
{
|
||||
const mio_bch_t* end = ptr + len;
|
||||
|
||||
@ -1122,12 +1122,12 @@ done:
|
||||
}
|
||||
|
||||
/* feed the percent encoded string */
|
||||
int mio_htrd_feed (mio_htrd_t* htrd, const mio_bch_t* req, mio_size_t len)
|
||||
int mio_htrd_feed (mio_htrd_t* htrd, const mio_bch_t* req, mio_oow_t len)
|
||||
{
|
||||
const mio_bch_t* end = req + len;
|
||||
const mio_bch_t* ptr = req;
|
||||
int header_completed_during_this_feed = 0;
|
||||
mio_size_t avail;
|
||||
mio_oow_t avail;
|
||||
|
||||
MIO_ASSERT (len > 0);
|
||||
|
||||
|
@ -27,7 +27,7 @@
|
||||
#include <mio-htre.h>
|
||||
#include "mio-prv.h"
|
||||
|
||||
static void free_hdrval (mio_htb_t* htb, void* vptr, mio_size_t vlen)
|
||||
static void free_hdrval (mio_htb_t* htb, void* vptr, mio_oow_t vlen)
|
||||
{
|
||||
mio_htre_hdrval_t* val;
|
||||
mio_htre_hdrval_t* tmp;
|
||||
@ -37,11 +37,11 @@ static void free_hdrval (mio_htb_t* htb, void* vptr, mio_size_t vlen)
|
||||
{
|
||||
tmp = val;
|
||||
val = val->next;
|
||||
MIO_MMGR_FREE (htb->mmgr, tmp);
|
||||
mio_freemem (htb->mio, tmp);
|
||||
}
|
||||
}
|
||||
|
||||
int mio_htre_init (mio_htre_t* re, mio_mmgr_t* mmgr)
|
||||
int mio_htre_init (mio_htre_t* re, mio_t* mio)
|
||||
{
|
||||
static mio_htb_style_t style =
|
||||
{
|
||||
@ -60,17 +60,17 @@ int mio_htre_init (mio_htre_t* re, mio_mmgr_t* mmgr)
|
||||
};
|
||||
|
||||
MIO_MEMSET (re, 0, MIO_SIZEOF(*re));
|
||||
re->mmgr = mmgr;
|
||||
re->mio = mio;
|
||||
|
||||
if (mio_htb_init (&re->hdrtab, mmgr, 60, 70, 1, 1) <= -1) return -1;
|
||||
if (mio_htb_init (&re->trailers, mmgr, 20, 70, 1, 1) <= -1) return -1;
|
||||
if (mio_htb_init(&re->hdrtab, mio, 60, 70, 1, 1) <= -1) return -1;
|
||||
if (mio_htb_init(&re->trailers, mio, 20, 70, 1, 1) <= -1) return -1;
|
||||
|
||||
mio_htb_setstyle (&re->hdrtab, &style);
|
||||
mio_htb_setstyle (&re->trailers, &style);
|
||||
|
||||
mio_mbs_init (&re->content, mmgr, 0);
|
||||
mio_becs_init (&re->content, mio, 0);
|
||||
#if 0
|
||||
mio_mbs_init (&re->iniline, mmgr, 0);
|
||||
mio_becs_init (&re->iniline, mio, 0);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
@ -79,14 +79,13 @@ int mio_htre_init (mio_htre_t* re, mio_mmgr_t* mmgr)
|
||||
void mio_htre_fini (mio_htre_t* re)
|
||||
{
|
||||
#if 0
|
||||
mio_mbs_fini (&re->iniline);
|
||||
mio_becs_fini (&re->iniline);
|
||||
#endif
|
||||
mio_mbs_fini (&re->content);
|
||||
mio_becs_fini (&re->content);
|
||||
mio_htb_fini (&re->trailers);
|
||||
mio_htb_fini (&re->hdrtab);
|
||||
|
||||
if (re->orgqpath.buf)
|
||||
MIO_MMGR_FREE (re->mmgr, re->orgqpath.buf);
|
||||
if (re->orgqpath.buf) mio_freemem (re->mio, re->orgqpath.buf);
|
||||
}
|
||||
|
||||
void mio_htre_clear (mio_htre_t* re)
|
||||
@ -113,26 +112,24 @@ void mio_htre_clear (mio_htre_t* re)
|
||||
mio_htb_clear (&re->hdrtab);
|
||||
mio_htb_clear (&re->trailers);
|
||||
|
||||
mio_mbs_clear (&re->content);
|
||||
mio_becs_clear (&re->content);
|
||||
#if 0
|
||||
mio_mbs_clear (&re->iniline);
|
||||
mio_becs_clear (&re->iniline);
|
||||
#endif
|
||||
}
|
||||
|
||||
const mio_htre_hdrval_t* mio_htre_getheaderval (
|
||||
const mio_htre_t* re, const mio_mchar_t* name)
|
||||
const mio_htre_hdrval_t* mio_htre_getheaderval (const mio_htre_t* re, const mio_bch_t* name)
|
||||
{
|
||||
mio_htb_pair_t* pair;
|
||||
pair = mio_htb_search (&re->hdrtab, name, mio_mbslen(name));
|
||||
pair = mio_htb_search(&re->hdrtab, name, mio_count_bcstr(name));
|
||||
if (pair == MIO_NULL) return MIO_NULL;
|
||||
return MIO_HTB_VPTR(pair);
|
||||
}
|
||||
|
||||
const mio_htre_hdrval_t* mio_htre_gettrailerval (
|
||||
const mio_htre_t* re, const mio_mchar_t* name)
|
||||
const mio_htre_hdrval_t* mio_htre_gettrailerval (const mio_htre_t* re, const mio_bch_t* name)
|
||||
{
|
||||
mio_htb_pair_t* pair;
|
||||
pair = mio_htb_search (&re->trailers, name, mio_mbslen(name));
|
||||
pair = mio_htb_search(&re->trailers, name, mio_count_bcstr(name));
|
||||
if (pair == MIO_NULL) return MIO_NULL;
|
||||
return MIO_HTB_VPTR(pair);
|
||||
}
|
||||
@ -145,8 +142,7 @@ struct header_walker_ctx_t
|
||||
int ret;
|
||||
};
|
||||
|
||||
static mio_htb_walk_t walk_headers (
|
||||
mio_htb_t* htb, mio_htb_pair_t* pair, void* ctx)
|
||||
static mio_htb_walk_t walk_headers (mio_htb_t* htb, mio_htb_pair_t* pair, void* ctx)
|
||||
{
|
||||
struct header_walker_ctx_t* hwctx = (struct header_walker_ctx_t*)ctx;
|
||||
if (hwctx->walker (hwctx->re, MIO_HTB_KPTR(pair), MIO_HTB_VPTR(pair), hwctx->ctx) <= -1)
|
||||
@ -157,8 +153,7 @@ static mio_htb_walk_t walk_headers (
|
||||
return MIO_HTB_WALK_FORWARD;
|
||||
}
|
||||
|
||||
int mio_htre_walkheaders (
|
||||
mio_htre_t* re, mio_htre_header_walker_t walker, void* ctx)
|
||||
int mio_htre_walkheaders (mio_htre_t* re, mio_htre_header_walker_t walker, void* ctx)
|
||||
{
|
||||
struct header_walker_ctx_t hwctx;
|
||||
hwctx.re = re;
|
||||
@ -169,8 +164,7 @@ int mio_htre_walkheaders (
|
||||
return hwctx.ret;
|
||||
}
|
||||
|
||||
int mio_htre_walktrailers (
|
||||
mio_htre_t* re, mio_htre_header_walker_t walker, void* ctx)
|
||||
int mio_htre_walktrailers (mio_htre_t* re, mio_htre_header_walker_t walker, void* ctx)
|
||||
{
|
||||
struct header_walker_ctx_t hwctx;
|
||||
hwctx.re = re;
|
||||
@ -181,8 +175,7 @@ int mio_htre_walktrailers (
|
||||
return hwctx.ret;
|
||||
}
|
||||
|
||||
int mio_htre_addcontent (
|
||||
mio_htre_t* re, const mio_mchar_t* ptr, mio_size_t len)
|
||||
int mio_htre_addcontent (mio_htre_t* re, const mio_bch_t* ptr, mio_oow_t len)
|
||||
{
|
||||
/* see comments in mio_htre_discardcontent() */
|
||||
|
||||
@ -191,12 +184,12 @@ int mio_htre_addcontent (
|
||||
if (re->concb)
|
||||
{
|
||||
/* if the callback is set, the content goes to the callback. */
|
||||
if (re->concb (re, ptr, len, re->concb_ctx) <= -1) return -1;
|
||||
if (re->concb(re, ptr, len, re->concb_ctx) <= -1) return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* if the callback is not set, the contents goes to the internal buffer */
|
||||
if (mio_mbs_ncat (&re->content, ptr, len) == (mio_size_t)-1) return -1;
|
||||
if (mio_becs_ncat(&re->content, ptr, len) == (mio_oow_t)-1) return -1;
|
||||
}
|
||||
|
||||
return 1; /* added successfully */
|
||||
@ -225,8 +218,7 @@ void mio_htre_discardcontent (mio_htre_t* re)
|
||||
* you can't add contents to this if it's completed or discarded
|
||||
*/
|
||||
|
||||
if (!(re->state & MIO_HTRE_COMPLETED) &&
|
||||
!(re->state & MIO_HTRE_DISCARDED))
|
||||
if (!(re->state & MIO_HTRE_COMPLETED) && !(re->state & MIO_HTRE_DISCARDED))
|
||||
{
|
||||
re->state |= MIO_HTRE_DISCARDED;
|
||||
|
||||
@ -243,7 +235,7 @@ void mio_htre_discardcontent (mio_htre_t* re)
|
||||
* designed to serve a certain usage pattern not including
|
||||
* weird combinations.
|
||||
*/
|
||||
mio_mbs_clear (&re->content);
|
||||
mio_becs_clear (&re->content);
|
||||
if (re->concb)
|
||||
{
|
||||
/* indicate end of content */
|
||||
@ -266,34 +258,34 @@ void mio_htre_setconcb (mio_htre_t* re, mio_htre_concb_t concb, void* ctx)
|
||||
|
||||
int mio_htre_perdecqpath (mio_htre_t* re)
|
||||
{
|
||||
mio_size_t dec_count;
|
||||
mio_oow_t dec_count;
|
||||
|
||||
/* percent decode the query path*/
|
||||
|
||||
if (re->type != MIO_HTRE_Q || (re->flags & MIO_HTRE_QPATH_PERDEC)) return -1;
|
||||
|
||||
MIO_ASSERT (re->orgqpath.len <= 0);
|
||||
MIO_ASSERT (re->orgqpath.ptr == MIO_NULL);
|
||||
MIO_ASSERT (re->mio, re->orgqpath.len <= 0);
|
||||
MIO_ASSERT (re->mio, re->orgqpath.ptr == MIO_NULL);
|
||||
|
||||
if (mio_isperencedhttpstr(re->u.q.path.ptr))
|
||||
if (mio_is_perenced_http_bcstr(re->u.q.path.ptr))
|
||||
{
|
||||
/* the string is percent-encoded. keep the original request
|
||||
* in a separately allocated buffer */
|
||||
|
||||
if (re->orgqpath.buf && re->u.q.path.len <= re->orgqpath.capa)
|
||||
{
|
||||
re->orgqpath.len = mio_mbscpy (re->orgqpath.buf, re->u.q.path.ptr);
|
||||
re->orgqpath.len = mio_copy_bcstr_unlimited(re->orgqpath.buf, re->u.q.path.ptr);
|
||||
re->orgqpath.ptr = re->orgqpath.buf;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (re->orgqpath.buf)
|
||||
{
|
||||
MIO_MMGR_FREE (re->mmgr, re->orgqpath.buf);
|
||||
mio_freemem (re->mio, re->orgqpath.buf);
|
||||
re->orgqpath.capa = 0;
|
||||
}
|
||||
|
||||
re->orgqpath.buf = mio_mbsxdup (re->u.q.path.ptr, re->u.q.path.len, re->mmgr);
|
||||
re->orgqpath.buf = mio_mbsxdup(re->u.q.path.ptr, re->u.q.path.len, re->mio);
|
||||
if (!re->orgqpath.buf) return -1;
|
||||
re->orgqpath.capa = re->u.q.path.len;
|
||||
|
||||
@ -309,10 +301,10 @@ int mio_htre_perdecqpath (mio_htre_t* re)
|
||||
re->u.q.path.len = mio_perdechttpstr (re->u.q.path.ptr, re->u.q.path.ptr, &dec_count);
|
||||
if (dec_count > 0)
|
||||
{
|
||||
/* this assertion is to ensure that mio_isperencedhttpstr()
|
||||
/* this assertion is to ensure that mio_is_perenced_http_bstr()
|
||||
* returned true when dec_count is greater than 0 */
|
||||
MIO_ASSERT (re->orgqpath.buf != MIO_NULL);
|
||||
MIO_ASSERT (re->orgqpath.ptr != MIO_NULL);
|
||||
MIO_ASSERT (re->mio, re->orgqpath.buf != MIO_NULL);
|
||||
MIO_ASSERT (re->mio, re->orgqpath.ptr != MIO_NULL);
|
||||
re->flags |= MIO_HTRE_QPATH_PERDEC;
|
||||
}
|
||||
|
||||
|
@ -33,9 +33,9 @@ int mio_comparehttpversions (
|
||||
return v1->major - v2->major;
|
||||
}
|
||||
|
||||
const mio_mchar_t* mio_httpstatustombs (int code)
|
||||
const mio_bch_t* mio_httpstatustombs (int code)
|
||||
{
|
||||
const mio_mchar_t* msg;
|
||||
const mio_bch_t* msg;
|
||||
|
||||
switch (code)
|
||||
{
|
||||
@ -95,10 +95,10 @@ const mio_mchar_t* mio_httpstatustombs (int code)
|
||||
return msg;
|
||||
}
|
||||
|
||||
const mio_mchar_t* mio_httpmethodtombs (mio_http_method_t type)
|
||||
const mio_bch_t* mio_httpmethodtombs (mio_http_method_t type)
|
||||
{
|
||||
/* keep this table in the same order as mio_httpd_method_t enumerators */
|
||||
static mio_mchar_t* names[] =
|
||||
static mio_bch_t* names[] =
|
||||
{
|
||||
"OTHER",
|
||||
|
||||
@ -117,7 +117,7 @@ const mio_mchar_t* mio_httpmethodtombs (mio_http_method_t type)
|
||||
|
||||
struct mtab_t
|
||||
{
|
||||
const mio_mchar_t* name;
|
||||
const mio_bch_t* name;
|
||||
mio_http_method_t type;
|
||||
};
|
||||
|
||||
@ -134,7 +134,7 @@ static struct mtab_t mtab[] =
|
||||
{ "TRACE", MIO_HTTP_TRACE }
|
||||
};
|
||||
|
||||
mio_http_method_t mio_mbstohttpmethod (const mio_mchar_t* name)
|
||||
mio_http_method_t mio_bcstr_to_http_method (const mio_bch_t* name)
|
||||
{
|
||||
/* perform binary search */
|
||||
|
||||
@ -151,10 +151,10 @@ mio_http_method_t mio_mbstohttpmethod (const mio_mchar_t* name)
|
||||
mid = left + (right - left) / 2;
|
||||
entry = &mtab[mid];
|
||||
|
||||
n = mio_mbscmp (name, entry->name);
|
||||
n = mio_comp_bcstr(name, entry->name);
|
||||
if (n < 0)
|
||||
{
|
||||
/* if left, right, mid were of mio_size_t,
|
||||
/* if left, right, mid were of mio_oow_t,
|
||||
* you would need the following line.
|
||||
if (mid == 0) break;
|
||||
*/
|
||||
@ -167,7 +167,7 @@ mio_http_method_t mio_mbstohttpmethod (const mio_mchar_t* name)
|
||||
return MIO_HTTP_OTHER;
|
||||
}
|
||||
|
||||
mio_http_method_t mio_mcstrtohttpmethod (const mio_mcstr_t* name)
|
||||
mio_http_method_t mio_bchars_to_http_method (const mio_bch_t* nameptr, mio_oow_t namelen)
|
||||
{
|
||||
/* perform binary search */
|
||||
|
||||
@ -184,10 +184,10 @@ mio_http_method_t mio_mcstrtohttpmethod (const mio_mcstr_t* name)
|
||||
mid = left + (right - left) / 2;
|
||||
entry = &mtab[mid];
|
||||
|
||||
n = mio_mbsxcmp (name->ptr, name->len, entry->name);
|
||||
n = mio_mbsxcmp(nameptr, namelen, entry->name);
|
||||
if (n < 0)
|
||||
{
|
||||
/* if left, right, mid were of mio_size_t,
|
||||
/* if left, right, mid were of mio_oow_t,
|
||||
* you would need the following line.
|
||||
if (mid == 0) break;
|
||||
*/
|
||||
@ -200,7 +200,7 @@ mio_http_method_t mio_mcstrtohttpmethod (const mio_mcstr_t* name)
|
||||
return MIO_HTTP_OTHER;
|
||||
}
|
||||
|
||||
int mio_parsehttprange (const mio_mchar_t* str, mio_http_range_t* range)
|
||||
int mio_parse_http_range_bcstr (const mio_bch_t* str, mio_http_range_t* range)
|
||||
{
|
||||
/* NOTE: this function does not support a range set
|
||||
* like bytes=1-20,30-50 */
|
||||
@ -255,8 +255,8 @@ int mio_parsehttprange (const mio_mchar_t* str, mio_http_range_t* range)
|
||||
typedef struct mname_t mname_t;
|
||||
struct mname_t
|
||||
{
|
||||
const mio_mchar_t* s;
|
||||
const mio_mchar_t* l;
|
||||
const mio_bch_t* s;
|
||||
const mio_bch_t* l;
|
||||
};
|
||||
|
||||
static mname_t wday_name[] =
|
||||
@ -286,11 +286,11 @@ static mname_t mon_name[] =
|
||||
{ "Dec", "December" }
|
||||
};
|
||||
|
||||
int mio_parsehttptime (const mio_mchar_t* str, mio_ntime_t* nt)
|
||||
int mio_parse_http_time_bcstr (const mio_bch_t* str, mio_ntime_t* nt)
|
||||
{
|
||||
mio_btime_t bt;
|
||||
const mio_mchar_t* word;
|
||||
mio_size_t wlen, i;
|
||||
const mio_bch_t* word;
|
||||
mio_oow_t wlen, i;
|
||||
|
||||
/* TODO: support more formats */
|
||||
|
||||
@ -302,7 +302,7 @@ int mio_parsehttptime (const mio_mchar_t* str, mio_ntime_t* nt)
|
||||
wlen = str - word;
|
||||
for (i = 0; i < MIO_COUNTOF(wday_name); i++)
|
||||
{
|
||||
if (mio_mbsxcmp (word, wlen, wday_name[i].s) == 0)
|
||||
if (mio_mbsxcmp(word, wlen, wday_name[i].s) == 0)
|
||||
{
|
||||
bt.wday = i;
|
||||
break;
|
||||
@ -325,7 +325,7 @@ int mio_parsehttptime (const mio_mchar_t* str, mio_ntime_t* nt)
|
||||
wlen = str - word;
|
||||
for (i = 0; i < MIO_COUNTOF(mon_name); i++)
|
||||
{
|
||||
if (mio_mbsxcmp (word, wlen, mon_name[i].s) == 0)
|
||||
if (mio_mbsxcmp(word, wlen, mon_name[i].s) == 0)
|
||||
{
|
||||
bt.mon = i;
|
||||
break;
|
||||
@ -362,15 +362,15 @@ int mio_parsehttptime (const mio_mchar_t* str, mio_ntime_t* nt)
|
||||
while (MIO_ISMSPACE(*str)) str++;
|
||||
for (word = str; MIO_ISMALPHA(*str); str++);
|
||||
wlen = str - word;
|
||||
if (mio_mbsxcmp (word, wlen, "GMT" != 0) return -1;
|
||||
if (mio_mbsxcmp(word, wlen, "GMT") != 0) return -1;
|
||||
|
||||
while (MIO_ISMSPACE(*str)) str++;
|
||||
if (*str != '\0') return -1;
|
||||
|
||||
return mio_timegm (&bt, nt);
|
||||
return mio_timegm(&bt, nt);
|
||||
}
|
||||
|
||||
mio_mchar_t* mio_fmthttptime (const mio_ntime_t* nt, mio_mchar_t* buf, mio_size_t bufsz)
|
||||
mio_bch_t* mio_fmthttptime (const mio_ntime_t* nt, mio_bch_t* buf, mio_oow_t bufsz)
|
||||
{
|
||||
mio_btime_t bt;
|
||||
|
||||
@ -389,9 +389,9 @@ mio_mchar_t* mio_fmthttptime (const mio_ntime_t* nt, mio_mchar_t* buf, mio_size_
|
||||
return buf;
|
||||
}
|
||||
|
||||
int mio_isperencedhttpstr (const mio_mchar_t* str)
|
||||
int mio_is_perenced_http_bcstr (const mio_bch_t* str)
|
||||
{
|
||||
const mio_mchar_t* p = str;
|
||||
const mio_bch_t* p = str;
|
||||
|
||||
while (*p != '\0')
|
||||
{
|
||||
@ -412,11 +412,11 @@ int mio_isperencedhttpstr (const mio_mchar_t* str)
|
||||
return 1;
|
||||
}
|
||||
|
||||
mio_size_t mio_perdechttpstr (const mio_mchar_t* str, mio_mchar_t* buf, mio_size_t* ndecs)
|
||||
mio_oow_t mio_perdechttpstr (const mio_bch_t* str, mio_bch_t* buf, mio_oow_t* ndecs)
|
||||
{
|
||||
const mio_mchar_t* p = str;
|
||||
mio_mchar_t* out = buf;
|
||||
mio_size_t dec_count = 0;
|
||||
const mio_bch_t* p = str;
|
||||
mio_bch_t* out = buf;
|
||||
mio_oow_t dec_count = 0;
|
||||
|
||||
while (*p != '\0')
|
||||
{
|
||||
@ -454,11 +454,11 @@ mio_size_t mio_perdechttpstr (const mio_mchar_t* str, mio_mchar_t* buf, mio_size
|
||||
|
||||
#define TO_HEX(v) ("0123456789ABCDEF"[(v) & 15])
|
||||
|
||||
mio_size_t mio_perenchttpstr (int opt, const mio_mchar_t* str, mio_mchar_t* buf, mio_size_t* nencs)
|
||||
mio_oow_t mio_perenchttpstr (int opt, const mio_bch_t* str, mio_bch_t* buf, mio_oow_t* nencs)
|
||||
{
|
||||
const mio_mchar_t* p = str;
|
||||
mio_mchar_t* out = buf;
|
||||
mio_size_t enc_count = 0;
|
||||
const mio_bch_t* p = str;
|
||||
mio_bch_t* out = buf;
|
||||
mio_oow_t enc_count = 0;
|
||||
|
||||
/* this function doesn't accept the size of the buffer. the caller must
|
||||
* ensure that the buffer is large enough */
|
||||
@ -498,11 +498,11 @@ mio_size_t mio_perenchttpstr (int opt, const mio_mchar_t* str, mio_mchar_t* buf,
|
||||
return out - buf;
|
||||
}
|
||||
|
||||
mio_mchar_t* mio_perenchttpstrdup (int opt, const mio_mchar_t* str, mio_mmgr_t* mmgr)
|
||||
mio_bch_t* mio_perenchttpstrdup (int opt, const mio_bch_t* str, mio_mmgr_t* mmgr)
|
||||
{
|
||||
mio_mchar_t* buf;
|
||||
mio_size_t len = 0;
|
||||
mio_size_t count = 0;
|
||||
mio_bch_t* buf;
|
||||
mio_oow_t len = 0;
|
||||
mio_oow_t count = 0;
|
||||
|
||||
/* count the number of characters that should be encoded */
|
||||
if (opt & MIO_PERENCHTTPSTR_KEEP_SLASH)
|
||||
@ -521,7 +521,7 @@ mio_mchar_t* mio_perenchttpstrdup (int opt, const mio_mchar_t* str, mio_mmgr_t*
|
||||
}
|
||||
|
||||
/* if there are no characters to escape, just return the original string */
|
||||
if (count <= 0) return (mio_mchar_t*)str;
|
||||
if (count <= 0) return (mio_bch_t*)str;
|
||||
|
||||
/* allocate a buffer of an optimal size for escaping, otherwise */
|
||||
buf = MIO_MMGR_ALLOC (mmgr, (len + (count * 2) + 1) * MIO_SIZEOF(*buf));
|
||||
|
@ -430,6 +430,13 @@ typedef struct mio_bcs_t mio_bcs_t;
|
||||
|
||||
typedef unsigned int mio_bitmask_t;
|
||||
|
||||
typedef struct mio_ptl_t mio_ptl_t;
|
||||
struct mio_ptl_t
|
||||
{
|
||||
void* ptr;
|
||||
mio_oow_t len;
|
||||
};
|
||||
|
||||
/* =========================================================================
|
||||
* TIME-RELATED TYPES
|
||||
* =========================================================================*/
|
||||
|
640
mio/lib/mio-ecs.h
Normal file
640
mio/lib/mio-ecs.h
Normal file
@ -0,0 +1,640 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
Copyright (c) 2006-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* gem;
|
||||
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* gem;
|
||||
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* gem,
|
||||
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* gem,
|
||||
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* gem,
|
||||
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* gem,
|
||||
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
|
||||
);
|
||||
|
||||
#if 0
|
||||
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,
|
||||
...
|
||||
);
|
||||
#endif
|
||||
|
||||
#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
|
||||
#if 0
|
||||
# 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
|
||||
#endif
|
||||
#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
|
||||
|
||||
#if 0
|
||||
# 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
|
||||
|
||||
#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
|
682
mio/lib/mio-htb.h
Normal file
682
mio/lib/mio-htb.h
Normal file
@ -0,0 +1,682 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
Copyright (c) 2006-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
|
@ -49,21 +49,21 @@ typedef enum mio_htre_state_t mio_htre_state_t;
|
||||
|
||||
typedef int (*mio_htre_concb_t) (
|
||||
mio_htre_t* re,
|
||||
const mio_mchar_t* ptr,
|
||||
mio_size_t len,
|
||||
const mio_bch_t* ptr,
|
||||
mio_oow_t len,
|
||||
void* ctx
|
||||
);
|
||||
|
||||
struct mio_htre_hdrval_t
|
||||
{
|
||||
const mio_mchar_t* ptr;
|
||||
mio_size_t len;
|
||||
const mio_bch_t* ptr;
|
||||
mio_oow_t len;
|
||||
mio_htre_hdrval_t* next;
|
||||
};
|
||||
|
||||
struct mio_htre_t
|
||||
{
|
||||
mio_mmgr_t* mmgr;
|
||||
mio_t* mio;
|
||||
|
||||
enum
|
||||
{
|
||||
@ -73,7 +73,7 @@ struct mio_htre_t
|
||||
|
||||
/* version */
|
||||
mio_http_version_t version;
|
||||
const mio_mchar_t* verstr; /* version string include HTTP/ */
|
||||
const mio_bch_t* verstr; /* version string include HTTP/ */
|
||||
|
||||
union
|
||||
{
|
||||
@ -82,19 +82,19 @@ struct mio_htre_t
|
||||
struct
|
||||
{
|
||||
mio_http_method_t type;
|
||||
const mio_mchar_t* name;
|
||||
const mio_bch_t* name;
|
||||
} method;
|
||||
mio_mcstr_t path;
|
||||
mio_mcstr_t param;
|
||||
mio_bcs_t path;
|
||||
mio_bcs_t param;
|
||||
} q;
|
||||
struct
|
||||
{
|
||||
struct
|
||||
{
|
||||
int val;
|
||||
mio_mchar_t* str;
|
||||
mio_bch_t* str;
|
||||
} code;
|
||||
mio_mchar_t* mesg;
|
||||
mio_bch_t* mesg;
|
||||
} s;
|
||||
} u;
|
||||
|
||||
@ -111,18 +111,18 @@ struct mio_htre_t
|
||||
* meaningful if MIO_HTRE_QPATH_PERDEC is set in the flags */
|
||||
struct
|
||||
{
|
||||
mio_mchar_t* buf; /* buffer pointer */
|
||||
mio_size_t capa; /* buffer capacity */
|
||||
mio_bch_t* buf; /* buffer pointer */
|
||||
mio_oow_t capa; /* buffer capacity */
|
||||
|
||||
mio_mchar_t* ptr;
|
||||
mio_size_t len;
|
||||
mio_bch_t* ptr;
|
||||
mio_oow_t len;
|
||||
} orgqpath;
|
||||
|
||||
/* special attributes derived from the header */
|
||||
struct
|
||||
{
|
||||
mio_size_t content_length;
|
||||
const mio_mchar_t* status; /* for cgi */
|
||||
mio_oow_t content_length;
|
||||
const mio_bch_t* status; /* for cgi */
|
||||
} attr;
|
||||
|
||||
/* header table */
|
||||
@ -130,7 +130,7 @@ struct mio_htre_t
|
||||
mio_htb_t trailers;
|
||||
|
||||
/* content octets */
|
||||
mio_mbs_t content;
|
||||
mio_htob_t content;
|
||||
|
||||
/* content callback */
|
||||
mio_htre_concb_t concb;
|
||||
@ -164,7 +164,7 @@ struct mio_htre_t
|
||||
|
||||
typedef int (*mio_htre_header_walker_t) (
|
||||
mio_htre_t* re,
|
||||
const mio_mchar_t* key,
|
||||
const mio_bch_t* key,
|
||||
const mio_htre_hdrval_t* val,
|
||||
void* ctx
|
||||
);
|
||||
@ -175,7 +175,7 @@ extern "C" {
|
||||
|
||||
MIO_EXPORT int mio_htre_init (
|
||||
mio_htre_t* re,
|
||||
mio_mmgr_t* mmgr
|
||||
mio_t* mio
|
||||
);
|
||||
|
||||
MIO_EXPORT void mio_htre_fini (
|
||||
@ -188,12 +188,12 @@ MIO_EXPORT void mio_htre_clear (
|
||||
|
||||
MIO_EXPORT const mio_htre_hdrval_t* mio_htre_getheaderval (
|
||||
const mio_htre_t* re,
|
||||
const mio_mchar_t* key
|
||||
const mio_bch_t* key
|
||||
);
|
||||
|
||||
MIO_EXPORT const mio_htre_hdrval_t* mio_htre_gettrailerval (
|
||||
const mio_htre_t* re,
|
||||
const mio_mchar_t* key
|
||||
const mio_bch_t* key
|
||||
);
|
||||
|
||||
MIO_EXPORT int mio_htre_walkheaders (
|
||||
@ -217,8 +217,8 @@ MIO_EXPORT int mio_htre_walktrailers (
|
||||
*/
|
||||
MIO_EXPORT int mio_htre_addcontent (
|
||||
mio_htre_t* re,
|
||||
const mio_mchar_t* ptr,
|
||||
mio_size_t len
|
||||
const mio_bch_t* ptr,
|
||||
mio_oow_t len
|
||||
);
|
||||
|
||||
MIO_EXPORT void mio_htre_completecontent (
|
||||
|
@ -25,17 +25,17 @@
|
||||
#ifndef _MIO_HTTP_H_
|
||||
#define _MIO_HTTP_H_
|
||||
|
||||
#include <mio-cmn.h>
|
||||
#include <mio-ecs.h>
|
||||
|
||||
/** \file
|
||||
* This file provides basic data types and functions for the http protocol.
|
||||
*/
|
||||
|
||||
/* octet buffer */
|
||||
typedef mio_mbs_t mio_htob_t;
|
||||
typedef mio_becs_t mio_htob_t;
|
||||
|
||||
/* octet string */
|
||||
typedef mio_mcstr_t mio_htos_t;
|
||||
typedef mio_bcs_t mio_htos_t;
|
||||
|
||||
/**
|
||||
* The mio_http_version_t type defines http version.
|
||||
@ -176,22 +176,23 @@ MIO_EXPORT const mio_bch_t* mio_httpmethodtombs (
|
||||
mio_http_method_t type
|
||||
);
|
||||
|
||||
MIO_EXPORT mio_http_method_t mio_mbstohttpmethod (
|
||||
MIO_EXPORT mio_http_method_t mio_bcstr_to_http_method (
|
||||
const mio_bch_t* name
|
||||
);
|
||||
|
||||
MIO_EXPORT mio_http_method_t mio_mcstrtohttpmethod (
|
||||
const mio_mcstr_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_parsehttprange (
|
||||
const mio_bch_t* str,
|
||||
MIO_EXPORT int mio_parse_http_range_bcstr (
|
||||
const mio_bch_t* str,
|
||||
mio_http_range_t* range
|
||||
);
|
||||
|
||||
MIO_EXPORT int mio_parsehttptime (
|
||||
MIO_EXPORT int mio_parse_http_time_bcstr (
|
||||
const mio_bch_t* str,
|
||||
mio_ntime_t* nt
|
||||
mio_ntime_t* nt
|
||||
);
|
||||
|
||||
MIO_EXPORT mio_bch_t* mio_fmthttptime (
|
||||
@ -201,10 +202,10 @@ MIO_EXPORT mio_bch_t* mio_fmthttptime (
|
||||
);
|
||||
|
||||
/**
|
||||
* The mio_isperencedhttpstr() function determines if the given string
|
||||
* The mio_is_perenced_http_bcstr() function determines if the given string
|
||||
* contains a valid percent-encoded sequence.
|
||||
*/
|
||||
MIO_EXPORT int mio_isperencedhttpstr (
|
||||
MIO_EXPORT int mio_is_perenced_http_bcstr (
|
||||
const mio_bch_t* str
|
||||
);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user