diff --git a/mio/lib/Makefile.am b/mio/lib/Makefile.am index ca485f9..b315b32 100644 --- a/mio/lib/Makefile.am +++ b/mio/lib/Makefile.am @@ -27,6 +27,7 @@ include_HEADERS = \ mio-ecs.h \ mio-fmt.h \ mio-htb.h \ + mio-htrd.h \ mio-htre.h \ mio-http.h \ mio-nwif.h \ diff --git a/mio/lib/Makefile.in b/mio/lib/Makefile.in index ee01552..a4d79a3 100644 --- a/mio/lib/Makefile.in +++ b/mio/lib/Makefile.in @@ -407,6 +407,7 @@ include_HEADERS = \ mio-ecs.h \ mio-fmt.h \ mio-htb.h \ + mio-htrd.h \ mio-htre.h \ mio-http.h \ mio-nwif.h \ diff --git a/mio/lib/htrd.c b/mio/lib/htrd.c index a498808..2ed8851 100644 --- a/mio/lib/htrd.c +++ b/mio/lib/htrd.c @@ -22,10 +22,9 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include -#include -#include -#include "../cmn/mem-prv.h" +#include "mio-htrd.h" +#include "mio-chr.h" +#include "mio-prv.h" static const mio_bch_t NUL = '\0'; @@ -78,19 +77,17 @@ static MIO_INLINE int is_xdigit_octet (mio_bch_t c) static MIO_INLINE int digit_to_num (mio_bch_t c) { - if (c >= '0' && c <= '9') return c - '0'; - return -1; + return MIO_DIGIT_TO_NUM(c); } static MIO_INLINE int xdigit_to_num (mio_bch_t c) { - return MIO_MXDIGITTONUM (c); + return MIO_XDIGIT_TO_NUM(c); } - 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_oow_t)-1) + if (mio_becs_ncat (octb, ptr, len) == (mio_oow_t)-1) { htrd->errnum = MIO_HTRD_ENOMEM; return -1; @@ -100,7 +97,7 @@ static MIO_INLINE int push_to_buffer (mio_htrd_t* htrd, mio_htob_t* octb, const static MIO_INLINE int push_content (mio_htrd_t* htrd, const mio_bch_t* ptr, mio_oow_t len) { - MIO_ASSERT (len > 0); + MIO_ASSERT (htrd->mio, len > 0); if (mio_htre_addcontent(&htrd->re, ptr, len) <= -1) { @@ -120,8 +117,8 @@ static MIO_INLINE void clear_feed (mio_htrd_t* htrd) htrd->clean = 1; mio_htre_clear (&htrd->re); - mio_mbs_clear (&htrd->fed.b.tra); - mio_mbs_clear (&htrd->fed.b.raw); + mio_becs_clear (&htrd->fed.b.tra); + mio_becs_clear (&htrd->fed.b.raw); MIO_MEMSET (&htrd->fed.s, 0, MIO_SIZEOF(htrd->fed.s)); } @@ -138,7 +135,7 @@ mio_htrd_t* mio_htrd_open (mio_t* mio, mio_oow_t xtnsize) mio_freemem (mio, htrd); return MIO_NULL; } - else MIO_MEMSET (MIO_XTN(htrd), 0, xtnsize); + else MIO_MEMSET (htrd + 1, 0, xtnsize); } return htrd; } @@ -179,17 +176,17 @@ void mio_htrd_fini (mio_htrd_t* htrd) { mio_htre_fini (&htrd->re); - mio_mbs_fini (&htrd->fed.b.tra); - mio_mbs_fini (&htrd->fed.b.raw); + mio_becs_fini (&htrd->fed.b.tra); + mio_becs_fini (&htrd->fed.b.raw); #if 0 - mio_mbs_fini (&htrd->tmp.qparam); + mio_becs_fini (&htrd->tmp.qparam); #endif } static mio_bch_t* parse_initial_line (mio_htrd_t* htrd, mio_bch_t* line) { mio_bch_t* p = line; - mio_mcstr_t tmp; + mio_bcs_t tmp; #if 0 /* ignore leading spaces excluding crlf */ @@ -212,11 +209,10 @@ static mio_bch_t* parse_initial_line (mio_htrd_t* htrd, mio_bch_t* line) *p = '\0'; /* null-terminate the method name */ - htrd->re.u.q.method.type = mio_mcstrtohttpmethod (&tmp); + htrd->re.u.q.method.type = mio_bchars_to_http_method(tmp.ptr, tmp.len); htrd->re.u.q.method.name = tmp.ptr; } - else if ((htrd->option & MIO_HTRD_RESPONSE) && - mio_mbsxcmp (tmp.ptr, tmp.len, "HTTP") == 0) + else if ((htrd->option & MIO_HTRD_RESPONSE) && mio_comp_bchars_bcstr(tmp.ptr, tmp.len, "HTTP", 1) == 0) { /* it begins with HTTP. it may be a response */ htrd->re.type = MIO_HTRE_S; @@ -296,7 +292,7 @@ static mio_bch_t* parse_initial_line (mio_htrd_t* htrd, mio_bch_t* line) #if 0 mio_bch_t* out; #endif - mio_mcstr_t param; + mio_bcs_t param; /* skip spaces */ do p++; while (is_space_octet(*p)); @@ -412,16 +408,16 @@ static mio_bch_t* parse_initial_line (mio_htrd_t* htrd, mio_bch_t* line) /* if the url begins with xxx://, * skip xxx:/ and canonicalize from the second slash */ while (is_alpha_octet(*qpath)) qpath++; - if (mio_mbszcmp (qpath, "://", 3) == 0) + if (mio_comp_bcstr_limited(qpath, "://", 3, 1) == 0) { qpath = qpath + 2; /* set the position to the second / in :// */ - htrd->re.u.q.path.len = mio_canonmbspath (qpath, qpath, 0); + htrd->re.u.q.path.len = mio_canon_bcstr_path(qpath, qpath, 0); htrd->re.u.q.path.len += qpath - htrd->re.u.q.path.ptr; } else { qpath = htrd->re.u.q.path.ptr; - htrd->re.u.q.path.len = mio_canonmbspath (qpath, qpath, 0); + htrd->re.u.q.path.len = mio_canon_bcstr_path(qpath, qpath, 0); } } @@ -481,12 +477,6 @@ void mio_htrd_clear (mio_htrd_t* htrd) htrd->flags = 0; } -void* mio_htrd_getxtn (mio_htrd_t* htrd) -{ - return MIO_XTN (htrd); -} - - mio_htrd_errnum_t mio_htrd_geterrnum (mio_htrd_t* htrd) { return htrd->errnum; @@ -520,15 +510,15 @@ static int capture_connection (mio_htrd_t* htrd, mio_htb_pair_t* pair) while (val->next) val = val->next; /* The value for Connection: may get comma-separated. - * so use mio_mbscaseword() instead of mio_mbscmp(). */ + * so use mio_find_bcstr_word_in_bcstr() instead of mio_comp_bcstr(). */ - if (mio_mbscaseword (val->ptr, "close", ',')) + if (mio_find_bcstr_word_in_bcstr(val->ptr, "close", ',', 1)) { htrd->re.flags &= ~MIO_HTRE_ATTR_KEEPALIVE; return 0; } - if (mio_mbscaseword (val->ptr, "keep-alive", ',')) + if (mio_find_bcstr_word_in_bcstr(val->ptr, "keep-alive", ',', 1)) { htrd->re.flags |= MIO_HTRE_ATTR_KEEPALIVE; return 0; @@ -543,8 +533,7 @@ static int capture_connection (mio_htrd_t* htrd, mio_htb_pair_t* pair) * For the second Keep-Alive, this function sees 'Keep-Alive,Keep-Alive' * That's because values of the same keys are concatenated. */ - if (htrd->re.version.major < 1 || - (htrd->re.version.major == 1 && htrd->re.version.minor <= 0)) + if (htrd->re.version.major < 1 || (htrd->re.version.major == 1 && htrd->re.version.minor <= 0)) { htrd->re.flags &= ~MIO_HTRE_ATTR_KEEPALIVE; } @@ -615,7 +604,7 @@ static int capture_expect (mio_htrd_t* htrd, mio_htb_pair_t* pair) while (val) { /* Expect: 100-continue is included */ - if (mio_mbscasecmp(val->ptr, "100-continue") == 0) htrd->re.flags |= MIO_HTRE_ATTR_EXPECT100; + if (mio_comp_bcstr(val->ptr, "100-continue", 1) == 0) htrd->re.flags |= MIO_HTRE_ATTR_EXPECT100; val = val->next; } @@ -641,7 +630,7 @@ static int capture_transfer_encoding (mio_htrd_t* htrd, mio_htb_pair_t* pair) val = MIO_HTB_VPTR(pair); while (val->next) val = val->next; - n = mio_mbscasecmp(val->ptr, "chunked"); + n = mio_comp_bcstr(val->ptr, "chunked", 1); if (n == 0) { /* if (htrd->re.attr.content_length > 0) */ @@ -685,15 +674,11 @@ static MIO_INLINE int capture_key_header (mio_htrd_t* htrd, mio_htb_pair_t* pair { mid = base + count / 2; - n = mio_mbsxncasecmp ( - MIO_HTB_KPTR(pair), MIO_HTB_KLEN(pair), - hdrtab[mid].ptr, hdrtab[mid].len - ); - + n = mio_comp_bchars(MIO_HTB_KPTR(pair), MIO_HTB_KLEN(pair), hdrtab[mid].ptr, hdrtab[mid].len, 1); if (n == 0) { /* bingo! */ - return hdrtab[mid].handler (htrd, pair); + return hdrtab[mid].handler(htrd, pair); } if (n > 0) { base = mid + 1; count--; } @@ -723,7 +708,7 @@ static mio_htb_pair_t* hdr_cbserter ( mio_htre_hdrval_t *val; val = mio_allocmem(htb->mio, MIO_SIZEOF(*val)); - if (HAWK_UNLIKELY(!val)) + if (MIO_UNLIKELY(!val)) { tx->htrd->errnum = MIO_HTRD_ENOMEM; return MIO_NULL; @@ -787,7 +772,7 @@ static mio_htb_pair_t* hdr_cbserter ( mio_htre_hdrval_t* tmp; val = (mio_htre_hdrval_t*)mio_allocmem(tx->htrd->mio, MIO_SIZEOF(*val)); - if (HAWK_UNLIKELY(!val)) + if (MIO_UNLIKELY(!val)) { tx->htrd->errnum = MIO_HTRD_ENOMEM; return MIO_NULL; @@ -800,7 +785,7 @@ static mio_htb_pair_t* hdr_cbserter ( /* TODO: doubly linked list for speed-up??? */ tmp = MIO_HTB_VPTR(pair); - MIO_ASSERT (tmp != MIO_NULL); + MIO_ASSERT (tx->htrd->mio, tmp != MIO_NULL); /* find the tail */ while (tmp->next) tmp = tmp->next; @@ -826,7 +811,7 @@ mio_bch_t* parse_header_field (mio_htrd_t* htrd, mio_bch_t* line, mio_htb_t* tab while (is_space_octet(*p)) p++; #endif - MIO_ASSERT (!is_whspace_octet(*p)); + MIO_ASSERT (htrd->mio, !is_whspace_octet(*p)); /* check the field name */ name.ptr = last = p; @@ -932,7 +917,7 @@ static MIO_INLINE int parse_initial_line_and_headers ( /* add the terminating null for easier parsing */ if (push_to_buffer (htrd, &htrd->fed.b.raw, &NUL, 1) <= -1) return -1; - p = MIO_MBS_PTR(&htrd->fed.b.raw); + p = MIO_BECS_PTR(&htrd->fed.b.raw); #if 0 if (htrd->option & MIO_HTRD_SKIPEMPTYLINES) @@ -941,7 +926,7 @@ static MIO_INLINE int parse_initial_line_and_headers ( #endif while (is_space_octet(*p)) p++; - MIO_ASSERT (*p != '\0'); + MIO_ASSERT (htrd->mio, *p != '\0'); /* parse the initial line */ if (!(htrd->option & MIO_HTRD_SKIPINITIALLINE)) @@ -979,7 +964,7 @@ static const mio_bch_t* getchunklen (mio_htrd_t* htrd, const mio_bch_t* ptr, mio const mio_bch_t* end = ptr + len; /* this function must be called in the GET_CHUNK_LEN context */ - MIO_ASSERT (htrd->fed.s.chunk.phase == GET_CHUNK_LEN); + MIO_ASSERT (htrd->mio, htrd->fed.s.chunk.phase == GET_CHUNK_LEN); if (htrd->fed.s.chunk.count <= 0) { @@ -1063,7 +1048,7 @@ static const mio_bch_t* get_trailing_headers ( { mio_bch_t* p; - MIO_ASSERT (htrd->fed.s.crlf <= 3); + MIO_ASSERT (htrd->mio, htrd->fed.s.crlf <= 3); htrd->fed.s.crlf = 0; if (push_to_buffer ( @@ -1073,7 +1058,7 @@ static const mio_bch_t* get_trailing_headers ( htrd, &htrd->fed.b.tra, &NUL, 1) <= -1) return MIO_NULL; - p = MIO_MBS_PTR(&htrd->fed.b.tra); + p = MIO_BECS_PTR(&htrd->fed.b.tra); do { @@ -1123,7 +1108,7 @@ int mio_htrd_feed (mio_htrd_t* htrd, const mio_bch_t* req, mio_oow_t len) int header_completed_during_this_feed = 0; mio_oow_t avail; - MIO_ASSERT (len > 0); + MIO_ASSERT (htrd->mio, len > 0); if (htrd->flags & FEEDING_SUSPENDED) { @@ -1212,7 +1197,7 @@ int mio_htrd_feed (mio_htrd_t* htrd, const mio_bch_t* req, mio_oow_t len) */ /* we got a complete request header. */ - MIO_ASSERT (htrd->fed.s.crlf <= 3); + MIO_ASSERT (htrd->mio, htrd->fed.s.crlf <= 3); /* reset the crlf state */ htrd->fed.s.crlf = 0; @@ -1260,7 +1245,7 @@ int mio_htrd_feed (mio_htrd_t* htrd, const mio_bch_t* req, mio_oow_t len) if (htrd->re.flags & MIO_HTRE_ATTR_CHUNKED) { /* transfer-encoding: chunked */ - MIO_ASSERT (!(htrd->re.flags & MIO_HTRE_ATTR_LENGTH)); + MIO_ASSERT (htrd->mio, !(htrd->re.flags & MIO_HTRE_ATTR_LENGTH)); dechunk_start: htrd->fed.s.chunk.phase = GET_CHUNK_LEN; @@ -1411,7 +1396,7 @@ XXXXXXXX if (htrd->fed.s.chunk.phase == GET_CHUNK_DATA) { - MIO_ASSERT (htrd->fed.s.need == 0); + MIO_ASSERT (htrd->mio, htrd->fed.s.need == 0); htrd->fed.s.chunk.phase = GET_CHUNK_CRLF; dechunk_crlf: @@ -1495,8 +1480,8 @@ XXXXXXXX #if 0 mio_printf (MIO_T("CONTENT_LENGTH %d, RAW HEADER LENGTH %d\n"), - (int)MIO_MBS_LEN(&htrd->re.content), - (int)MIO_MBS_LEN(&htrd->fed.b.raw)); + (int)MIO_BECS_LEN(&htrd->re.content), + (int)MIO_BECS_LEN(&htrd->fed.b.raw)); #endif clear_feed (htrd); @@ -1621,9 +1606,9 @@ void mio_htrd_undummify (mio_htrd_t* htrd) } #if 0 -int mio_htrd_scanqparam (mio_htrd_t* htrd, const mio_mcstr_t* cstr) +int mio_htrd_scanqparam (mio_htrd_t* htrd, const mio_bcs_t* cstr) { - mio_mcstr_t key, val; + mio_bcs_t key, val; const mio_bch_t* p, * end; mio_bch_t* out; @@ -1637,11 +1622,11 @@ int mio_htrd_scanqparam (mio_htrd_t* htrd, const mio_mcstr_t* cstr) /* a key and a value pair including two terminating null * can't exceed the the qparamstrlen + 2. only +1 below as there is * one more space for an internal terminating null */ - mio_mbs_setlen (&htrd->tmp.qparam, cstr->len + 1); + mio_becs_setlen (&htrd->tmp.qparam, cstr->len + 1); /* let out point to the beginning of the qparam buffer. * the loop below emits percent-decode key and value to this buffer. */ - out = MIO_MBS_PTR(&htrd->tmp.qparam); + out = MIO_BECS_PTR(&htrd->tmp.qparam); key.ptr = out; key.len = 0; val.ptr = MIO_NULL; val.len = 0; @@ -1650,7 +1635,7 @@ int mio_htrd_scanqparam (mio_htrd_t* htrd, const mio_mcstr_t* cstr) { if (p >= end || *p == '&' || *p == ';') { - MIO_ASSERT (key.ptr != MIO_NULL); + MIO_ASSERT (htrd->mio, key.ptr != MIO_NULL); *out++ = '\0'; if (val.ptr == MIO_NULL) @@ -1664,13 +1649,11 @@ int mio_htrd_scanqparam (mio_htrd_t* htrd, const mio_mcstr_t* cstr) val.ptr = out; *out++ = '\0'; - MIO_ASSERT (val.len == 0); + MIO_ASSERT (htrd->mio, val.len == 0); } - MIO_ASSERTX ( - htrd->recbs->qparamstr != MIO_NULL, - "set request parameter string callback before scanning" - ); + /* set request parameter string callback before scanning */ + MIO_ASSERT (htrd->mio, htrd->recbs->qparamstr != MIO_NULL); htrd->errnum = MIO_HTRD_ENOERR; if (htrd->recbs->qparamstr (htrd, &key, &val) <= -1) @@ -1684,7 +1667,7 @@ int mio_htrd_scanqparam (mio_htrd_t* htrd, const mio_mcstr_t* cstr) if (p >= end) break; p++; - out = MIO_MBS_PTR(&htrd->tmp.qparam); + out = MIO_BECS_PTR(&htrd->tmp.qparam); key.ptr = out; key.len = 0; val.ptr = MIO_NULL; val.len = 0; } @@ -1723,7 +1706,7 @@ int mio_htrd_scanqparam (mio_htrd_t* htrd, const mio_mcstr_t* cstr) } while (1); - mio_mbs_clear (&htrd->tmp.qparam); + mio_becs_clear (&htrd->tmp.qparam); return 0; } #endif diff --git a/mio/lib/http.c b/mio/lib/http.c index cfdb256..d32468d 100644 --- a/mio/lib/http.c +++ b/mio/lib/http.c @@ -395,11 +395,6 @@ mio_bch_t* mio_fmt_http_time_to_bcstr (const mio_ntime_t* nt, mio_bch_t* buf, mi return buf; } -#define XDIGIT_TO_NUM(c) \ - (((c) >= '0' && (c) <= '9')? ((c) - '0'): \ - ((c) >= 'A' && (c) <= 'F')? ((c) - 'A' + 10): \ - ((c) >= 'a' && (c) <= 'f')? ((c) - 'a' + 10): -1) - int mio_is_perenced_http_bcstr (const mio_bch_t* str) { const mio_bch_t* p = str; @@ -408,11 +403,11 @@ int mio_is_perenced_http_bcstr (const mio_bch_t* str) { if (*p == '%' && *(p + 1) != '\0' && *(p + 2) != '\0') { - int q = XDIGIT_TO_NUM(*(p + 1)); + int q = MIO_XDIGIT_TO_NUM(*(p + 1)); if (q >= 0) { /* return true if the first valid percent-encoded sequence is found */ - int w = XDIGIT_TO_NUM(*(p + 2)); + int w = MIO_XDIGIT_TO_NUM(*(p + 2)); if (w >= 0) return 1; } } @@ -433,10 +428,10 @@ mio_oow_t mio_perdechttpstr (const mio_bch_t* str, mio_bch_t* buf, mio_oow_t* nd { if (*p == '%' && *(p + 1) != '\0' && *(p + 2) != '\0') { - int q = XDIGIT_TO_NUM(*(p + 1)); + int q = MIO_XDIGIT_TO_NUM(*(p + 1)); if (q >= 0) { - int w = XDIGIT_TO_NUM(*(p + 2)); + int w = MIO_XDIGIT_TO_NUM(*(p + 2)); if (w >= 0) { /* we don't care if it contains a null character */ diff --git a/mio/lib/mio-chr.h b/mio/lib/mio-chr.h index d0f7734..43cce22 100644 --- a/mio/lib/mio-chr.h +++ b/mio/lib/mio-chr.h @@ -84,6 +84,13 @@ typedef enum mio_ooch_prop_t mio_ooch_prop_t; typedef enum mio_ooch_prop_t mio_uch_prop_t; typedef enum mio_ooch_prop_t mio_bch_prop_t; +#define MIO_DIGIT_TO_NUM(c) (((c) >= '0' && (c) <= '9')? ((c) - '0'): -1) + +#define MIO_XDIGIT_TO_NUM(c) \ + (((c) >= '0' && (c) <= '9')? ((c) - '0'): \ + ((c) >= 'A' && (c) <= 'F')? ((c) - 'A' + 10): \ + ((c) >= 'a' && (c) <= 'f')? ((c) - 'a' + 10): -1) + #if defined(__cplusplus) extern "C" { #endif diff --git a/mio/lib/mio-htrd.h b/mio/lib/mio-htrd.h index 43f514c..da185ec 100644 --- a/mio/lib/mio-htrd.h +++ b/mio/lib/mio-htrd.h @@ -76,7 +76,7 @@ struct mio_htrd_recbs_t struct mio_htrd_t { - mio_mmgr_t* mmgr; + mio_t* mio; mio_htrd_errnum_t errnum; int option; int flags; @@ -90,13 +90,13 @@ struct mio_htrd_t int flags; int crlf; /* crlf status */ - mio_size_t plen; /* raw request length excluding crlf */ - mio_size_t need; /* number of octets needed for contents */ + mio_oow_t plen; /* raw request length excluding crlf */ + mio_oow_t need; /* number of octets needed for contents */ struct { - mio_size_t len; - mio_size_t count; + mio_oow_t len; + mio_oow_t count; int phase; } chunk; } s; /* state */ @@ -104,8 +104,8 @@ struct mio_htrd_t /* buffers needed for processing a request */ struct { - mio_htob_t raw; /* buffer to hold raw octets */ - mio_htob_t tra; /* buffer for handling trailers */ + mio_becs_t raw; /* buffer to hold raw octets */ + mio_becs_t tra; /* buffer for handling trailers */ } b; } fed; @@ -121,8 +121,8 @@ extern "C" { * The mio_htrd_open() function creates a htrd processor. */ MIO_EXPORT mio_htrd_t* mio_htrd_open ( - mio_mmgr_t* mmgr, /**< memory manager */ - mio_size_t xtnsize /**< extension size in bytes */ + mio_t* mio, /**< memory manager */ + mio_oow_t xtnsize /**< extension size in bytes */ ); /** @@ -134,20 +134,18 @@ MIO_EXPORT void mio_htrd_close ( MIO_EXPORT int mio_htrd_init ( mio_htrd_t* htrd, - mio_mmgr_t* mmgr + mio_t* mio ); MIO_EXPORT void mio_htrd_fini ( mio_htrd_t* htrd ); -MIO_EXPORT mio_mmgr_t* mio_htrd_getmmgr ( - mio_htrd_t* htrd -); - -MIO_EXPORT void* mio_htrd_getxtn ( - mio_htrd_t* htrd -); +#if defined(MIO_HAVE_INLINE) +static MIO_INLINE void* mio_htrd_getxtn (mio_htrd_t* htrd) { return (void*)(htrd + 1); } +#else +#define mio_htrd_getxtn(htrd) ((void*)((mio_htrd_t*)(htrd) + 1)) +#endif MIO_EXPORT mio_htrd_errnum_t mio_htrd_geterrnum ( mio_htrd_t* htrd @@ -181,8 +179,8 @@ MIO_EXPORT void mio_htrd_setrecbs ( */ MIO_EXPORT int mio_htrd_feed ( mio_htrd_t* htrd, /**< htrd */ - const mio_mchar_t* req, /**< request octets */ - mio_size_t len /**< number of octets */ + const mio_bch_t* req, /**< request octets */ + mio_oow_t len /**< number of octets */ ); /** @@ -210,10 +208,12 @@ MIO_EXPORT void mio_htrd_undummify ( mio_htrd_t* htrd ); +/* MIO_EXPORT int mio_htrd_scanqparam ( - mio_htrd_t* http, - const mio_mcstr_t* cstr + mio_htrd_t* http, + const mio_bcs_t* cstr ); +*/ #if defined(__cplusplus) } diff --git a/mio/lib/mio-htre.h b/mio/lib/mio-htre.h index f76c036..921d79a 100644 --- a/mio/lib/mio-htre.h +++ b/mio/lib/mio-htre.h @@ -130,7 +130,7 @@ struct mio_htre_t mio_htb_t trailers; /* content octets */ - mio_htob_t content; + mio_becs_t content; /* content callback */ mio_htre_concb_t concb; diff --git a/mio/lib/mio-http.h b/mio/lib/mio-http.h index 565f0b4..3508177 100644 --- a/mio/lib/mio-http.h +++ b/mio/lib/mio-http.h @@ -31,12 +31,6 @@ * This file provides basic data types and functions for the http protocol. */ -/* octet buffer */ -typedef mio_becs_t mio_htob_t; - -/* octet string */ -typedef mio_bcs_t mio_htos_t; - /** * The mio_http_version_t type defines http version. */ diff --git a/mio/lib/mio-utl.h b/mio/lib/mio-utl.h index 94c7328..5c1983b 100644 --- a/mio/lib/mio-utl.h +++ b/mio/lib/mio-utl.h @@ -274,6 +274,20 @@ MIO_EXPORT int mio_comp_bcstr ( int ignorecase ); +MIO_EXPORT int mio_comp_ucstr_limited ( + const mio_uch_t* str1, + const mio_uch_t* str2, + mio_oow_t maxlen, + int ignorecase +); + +MIO_EXPORT int mio_comp_bcstr_limited ( + const mio_bch_t* str1, + const mio_bch_t* str2, + mio_oow_t maxlen, + int ignorecase +); + MIO_EXPORT int mio_comp_ucstr_bcstr ( const mio_uch_t* str1, const mio_bch_t* str2, @@ -391,6 +405,20 @@ MIO_EXPORT void mio_fill_bchars ( mio_oow_t len ); +MIO_EXPORT const mio_bch_t* mio_find_bcstr_word_in_bcstr ( + const mio_bch_t* str, + const mio_bch_t* word, + mio_bch_t extra_delim, + int ignorecase +); + +MIO_EXPORT const mio_uch_t* mio_find_ucstr_word_in_ucstr ( + const mio_uch_t* str, + const mio_uch_t* word, + mio_uch_t extra_delim, + int ignorecase +); + MIO_EXPORT mio_uch_t* mio_find_uchar ( const mio_uch_t* ptr, mio_oow_t len, @@ -469,10 +497,11 @@ MIO_EXPORT mio_oow_t mio_count_bcstr ( # define mio_copy_oocstr mio_copy_ucstr # define mio_copy_oocstr_unlimited mio_copy_ucstr_unlimited -# define mio_fill_oochars(dst,ch,len) mio_fill_uchars(dst,ch,len) -# define mio_find_oochar(ptr,len,c) mio_find_uchar(ptr,len,c) -# define mio_rfind_oochar(ptr,len,c) mio_rfind_uchar(ptr,len,c) -# define mio_find_oochar_in_oocstr(ptr,c) mio_find_uchar_in_ucstr(ptr,c) +# define mio_fill_oochars mio_fill_uchars +# define mio_find_oocstr_word_in_oocstr mio_find_ucstr_word_in_ucstr +# define mio_find_oochar mio_find_uchar +# define mio_rfind_oochar mio_rfind_uchar +# define mio_find_oochar_in_oocstr mio_find_uchar_in_ucstr # define mio_split_oocstr mio_split_ucstr # define mio_count_oocstr mio_count_ucstr @@ -496,10 +525,11 @@ MIO_EXPORT mio_oow_t mio_count_bcstr ( # define mio_copy_oocstr mio_copy_bcstr # define mio_copy_oocstr_unlimited mio_copy_bcstr_unlimited -# define mio_fill_oochars(dst,ch,len) mio_fill_bchars(dst,ch,len) -# define mio_find_oochar(ptr,len,c) mio_find_bchar(ptr,len,c) -# define mio_rfind_oochar(ptr,len,c) mio_rfind_bchar(ptr,len,c) -# define mio_find_oochar_in_oocstr(ptr,c) mio_find_bchar_in_bcstr(ptr,c) +# define mio_fill_oochars mio_fill_bchars +# define mio_find_oocstr_word_in_oocstr mio_find_bcstr_word_in_bcstr +# define mio_find_oochar mio_find_bchar +# define mio_rfind_oochar mio_rfind_bchar +# define mio_find_oochar_in_oocstr mio_find_bchar_in_bcstr # define mio_split_oocstr mio_split_bcstr # define mio_count_oocstr mio_count_bcstr diff --git a/mio/lib/mio.c b/mio/lib/mio.c index 9f9f1a6..bf244c3 100644 --- a/mio/lib/mio.c +++ b/mio/lib/mio.c @@ -1606,7 +1606,7 @@ static int fmt_put_bchars_to_uch_buf (mio_fmtout_t* fmtout, const mio_bch_t* ptr } else { - if (b->mio) mio_seterrnum (b->mio, MIO_EECERR); + mio_seterrnum (b->mio, MIO_EECERR); return -1; } } @@ -1717,7 +1717,7 @@ static int fmt_put_uchars_to_bch_buf (mio_fmtout_t* fmtout, const mio_uch_t* ptr } else { - if (b->mio) mio_seterrnum (b->mio, MIO_EECERR); + mio_seterrnum (b->mio, MIO_EECERR); return -1; } } diff --git a/mio/lib/pro.c b/mio/lib/pro.c index 180ae84..cfd2ce0 100644 --- a/mio/lib/pro.c +++ b/mio/lib/pro.c @@ -32,6 +32,7 @@ #include #include #include +#include /* ========================================================================= */ diff --git a/mio/lib/utl.c b/mio/lib/utl.c index f396eb4..17641fb 100644 --- a/mio/lib/utl.c +++ b/mio/lib/utl.c @@ -25,7 +25,7 @@ */ #include "mio-prv.h" -#include +#include "mio-chr.h" /* ========================================================================= */ @@ -173,7 +173,7 @@ int mio_comp_bcstr (const mio_bch_t* str1, const mio_bch_t* str2, int ignorecase str1++; str2++; } - return ((mio_bchu_t)mio_to_bch_lower(*str1) > (mio_bchu_t)mio_to_bch_lower(*str2))? 1: -1; + return ((mio_bchu_t)mio_to_bch_lower(*str1) > (mio_bchu_t)mio_to_bch_lower(*str2))? 1: -1; } else { @@ -187,6 +187,58 @@ int mio_comp_bcstr (const mio_bch_t* str1, const mio_bch_t* str2, int ignorecase } } +int mio_comp_ucstr_limited (const mio_uch_t* str1, const mio_uch_t* str2, mio_oow_t maxlen, int ignorecase) +{ + if (maxlen == 0) return 0; + + if (ignorecase) + { + while (mio_to_uch_lower(*str1) == mio_to_uch_lower(*str2)) + { + if (*str1 == '\0' || maxlen == 1) return 0; + str1++; str2++; maxlen--; + } + + return ((mio_uchu_t)mio_to_uch_lower(*str1) > (mio_uchu_t)mio_to_uch_lower(*str2))? 1: -1; + } + else + { + while (*str1 == *str2) + { + if (*str1 == '\0' || maxlen == 1) return 0; + str1++; str2++; maxlen--; + } + + return ((mio_uchu_t)*str1 > (mio_uchu_t)*str2)? 1: -1; + } +} + +int mio_comp_bcstr_limited (const mio_bch_t* str1, const mio_bch_t* str2, mio_oow_t maxlen, int ignorecase) +{ + if (maxlen == 0) return 0; + + if (ignorecase) + { + while (mio_to_uch_lower(*str1) == mio_to_uch_lower(*str2)) + { + if (*str1 == '\0' || maxlen == 1) return 0; + str1++; str2++; maxlen--; + } + + return ((mio_bchu_t)mio_to_uch_lower(*str1) > (mio_bchu_t)mio_to_uch_lower(*str2))? 1: -1; + } + else + { + while (*str1 == *str2) + { + if (*str1 == '\0' || maxlen == 1) return 0; + str1++; str2++; maxlen--; + } + + return ((mio_bchu_t)*str1 > (mio_bchu_t)*str2)? 1: -1; + } +} + int mio_comp_ucstr_bcstr (const mio_uch_t* str1, const mio_bch_t* str2, int ignorecase) { while (*str1 == *str2) @@ -204,46 +256,114 @@ int mio_comp_uchars_ucstr (const mio_uch_t* str1, mio_oow_t len, const mio_uch_t * of the first string is equal to the terminating null of * the second string. the first string is still considered * bigger */ - const mio_uch_t* end = str1 + len; - while (str1 < end && *str2 != '\0') + if (ignorecase) { - if (*str1 != *str2) return ((mio_uchu_t)*str1 > (mio_uchu_t)*str2)? 1: -1; - str1++; str2++; + const mio_uch_t* end = str1 + len; + while (str1 < end && *str2 != '\0') + { + if (*str1 != *str2) return ((mio_uchu_t)*str1 > (mio_uchu_t)*str2)? 1: -1; + str1++; str2++; + } + return (str1 < end)? 1: (*str2 == '\0'? 0: -1); + } + else + { + const mio_uch_t* end = str1 + len; + mio_uch_t c1; + mio_uch_t c2; + while (str1 < end && *str2 != '\0') + { + c1 = mio_to_uch_lower(*str1); + c2 = mio_to_uch_lower(*str2); + if (c1 != c2) return ((mio_uchu_t)c1 > (mio_uchu_t)c2)? 1: -1; + str1++; str2++; + } + return (str1 < end)? 1: (*str2 == '\0'? 0: -1); } - return (str1 < end)? 1: (*str2 == '\0'? 0: -1); } int mio_comp_uchars_bcstr (const mio_uch_t* str1, mio_oow_t len, const mio_bch_t* str2, int ignorecase) { - const mio_uch_t* end = str1 + len; - while (str1 < end && *str2 != '\0') + if (ignorecase) { - if (*str1 != *str2) return ((mio_uchu_t)*str1 > (mio_bchu_t)*str2)? 1: -1; - str1++; str2++; + const mio_uch_t* end = str1 + len; + while (str1 < end && *str2 != '\0') + { + if (*str1 != *str2) return ((mio_uchu_t)*str1 > (mio_bchu_t)*str2)? 1: -1; + str1++; str2++; + } + return (str1 < end)? 1: (*str2 == '\0'? 0: -1); + } + else + { + const mio_uch_t* end = str1 + len; + mio_uch_t c1; + mio_bch_t c2; + while (str1 < end && *str2 != '\0') + { + c1 = mio_to_uch_lower(*str1); + c2 = mio_to_bch_lower(*str2); + if (c1 != c2) return ((mio_uchu_t)c1 > (mio_bchu_t)c2)? 1: -1; + str1++; str2++; + } + return (str1 < end)? 1: (*str2 == '\0'? 0: -1); } - return (str1 < end)? 1: (*str2 == '\0'? 0: -1); } int mio_comp_bchars_bcstr (const mio_bch_t* str1, mio_oow_t len, const mio_bch_t* str2, int ignorecase) { - const mio_bch_t* end = str1 + len; - while (str1 < end && *str2 != '\0') + if (ignorecase) { - if (*str1 != *str2) return ((mio_bchu_t)*str1 > (mio_bchu_t)*str2)? 1: -1; - str1++; str2++; + const mio_bch_t* end = str1 + len; + while (str1 < end && *str2 != '\0') + { + if (*str1 != *str2) return ((mio_bchu_t)*str1 > (mio_bchu_t)*str2)? 1: -1; + str1++; str2++; + } + return (str1 < end)? 1: (*str2 == '\0'? 0: -1); + } + else + { + const mio_bch_t* end = str1 + len; + mio_bch_t c1; + mio_bch_t c2; + while (str1 < end && *str2 != '\0') + { + c1 = mio_to_bch_lower(*str1); + c2 = mio_to_bch_lower(*str2); + if (c1 != c2) return ((mio_bchu_t)c1 > (mio_bchu_t)c2)? 1: -1; + str1++; str2++; + } + return (str1 < end)? 1: (*str2 == '\0'? 0: -1); } - return (str1 < end)? 1: (*str2 == '\0'? 0: -1); } int mio_comp_bchars_ucstr (const mio_bch_t* str1, mio_oow_t len, const mio_uch_t* str2, int ignorecase) { - const mio_bch_t* end = str1 + len; - while (str1 < end && *str2 != '\0') + if (ignorecase) { - if (*str1 != *str2) return ((mio_bchu_t)*str1 > (mio_uchu_t)*str2)? 1: -1; - str1++; str2++; + const mio_bch_t* end = str1 + len; + while (str1 < end && *str2 != '\0') + { + if (*str1 != *str2) return ((mio_bchu_t)*str1 > (mio_uchu_t)*str2)? 1: -1; + str1++; str2++; + } + return (str1 < end)? 1: (*str2 == '\0'? 0: -1); + } + else + { + const mio_bch_t* end = str1 + len; + mio_bch_t c1; + mio_uch_t c2; + while (str1 < end && *str2 != '\0') + { + c1 = mio_to_bch_lower(*str1); + c2 = mio_to_uch_lower(*str2); + if (c1 != c2) return ((mio_bchu_t)c1 > (mio_uchu_t)c2)? 1: -1; + str1++; str2++; + } + return (str1 < end)? 1: (*str2 == '\0'? 0: -1); } - return (str1 < end)? 1: (*str2 == '\0'? 0: -1); } /* ========================================================================= */ @@ -466,6 +586,57 @@ mio_bch_t* mio_find_bchar_in_bcstr (const mio_bch_t* ptr, mio_bch_t c) return MIO_NULL; } +#define IS_BCH_WORD_DELIM(x,delim) (mio_is_bch_space(x) || (x) == delim) +#define IS_UCH_WORD_DELIM(x,delim) (mio_is_uch_space(x) || (x) == delim) + +const mio_bch_t* mio_find_bcstr_word_in_bcstr (const mio_bch_t* str, const mio_bch_t* word, mio_bch_t extra_delim, int ignorecase) +{ + /* find a full word in a string */ + + const mio_bch_t* ptr = str; + + if (extra_delim == '\0') extra_delim = ' '; + do + { + const mio_bch_t* s; + + while (IS_BCH_WORD_DELIM(*ptr,extra_delim)) ptr++; + if (*ptr == '\0') return MIO_NULL; + + s = ptr; + while (*ptr != '\0' && !IS_BCH_WORD_DELIM(*ptr,extra_delim)) ptr++; + + if (mio_comp_bchars_bcstr(s, ptr - s, word, ignorecase) == 0) return s; + } + while (*ptr != '\0'); + + return MIO_NULL; +} + +const mio_uch_t* mio_find_ucstr_word_in_ucstr (const mio_uch_t* str, const mio_uch_t* word, mio_uch_t extra_delim, int ignorecase) +{ + /* find a full word in a string */ + + const mio_uch_t* ptr = str; + + if (extra_delim == '\0') extra_delim = ' '; + do + { + const mio_uch_t* s; + + while (IS_UCH_WORD_DELIM(*ptr,extra_delim)) ptr++; + if (*ptr == '\0') return MIO_NULL; + + s = ptr; + while (*ptr != '\0' && !IS_UCH_WORD_DELIM(*ptr,extra_delim)) ptr++; + + if (mio_comp_uchars_ucstr(s, ptr - s, word, ignorecase) == 0) return s; + } + while (*ptr != '\0'); + + return MIO_NULL; +} + /* ========================================================================= */ #define IS_UCH_SPACE(x) ((x) ==' ' || (x) == '\t' || (x) == '\n' || (x) == '\r') #define IS_BCH_SPACE(x) ((x) ==' ' || (x) == '\t' || (x) == '\n' || (x) == '\r')