diff --git a/qse/lib/awk/rec.c b/qse/lib/awk/rec.c index 43cae14d..7fcdd002 100644 --- a/qse/lib/awk/rec.c +++ b/qse/lib/awk/rec.c @@ -1,5 +1,5 @@ /* - * $Id: rec.c 292 2009-09-23 10:19:30Z hyunghwan.chung $ + * $Id: rec.c 368 2010-11-03 14:24:29Z hyunghwan.chung $ * Copyright 2006-2009 Chung, Hyung-Hwan. This file is part of QSE. @@ -299,11 +299,15 @@ static int split_record (qse_awk_rtx_t* rtx) #if 1 if (rtx->inrec.nflds >= rtx->inrec.maxflds) { + void* tmp; + if (rtx->inrec.nflds < 16) nflds = 32; else nflds = rtx->inrec.nflds * 2; - void* tmp = QSE_AWK_ALLOC ( - rtx->awk, QSE_SIZEOF(*rtx->inrec.flds) * nflds); + tmp = QSE_AWK_ALLOC ( + rtx->awk, + QSE_SIZEOF(*rtx->inrec.flds) * nflds + ); if (tmp == QSE_NULL) { if (fs_free != QSE_NULL) QSE_AWK_FREE (rtx->awk, fs_free); diff --git a/qse/lib/cmn/pio.c b/qse/lib/cmn/pio.c index 58daa6fb..86d7752a 100644 --- a/qse/lib/cmn/pio.c +++ b/qse/lib/cmn/pio.c @@ -1,5 +1,5 @@ /* - * $Id: pio.c 348 2010-08-26 06:26:28Z hyunghwan.chung $ + * $Id: pio.c 368 2010-11-03 14:24:29Z hyunghwan.chung $ * Copyright 2006-2009 Chung, Hyung-Hwan. This file is part of QSE. @@ -91,7 +91,6 @@ qse_pio_t* qse_pio_init ( int i, minidx = -1, maxidx = -1; - if (mmgr == QSE_NULL) mmgr = QSE_MMGR_GETDFL(); #ifdef _WIN32 SECURITY_ATTRIBUTES secattr; @@ -104,6 +103,8 @@ qse_pio_t* qse_pio_init ( qse_pio_pid_t pid; #endif + if (mmgr == QSE_NULL) mmgr = QSE_MMGR_GETDFL(); + QSE_MEMSET (pio, 0, QSE_SIZEOF(*pio)); pio->mmgr = mmgr; diff --git a/qse/lib/cmn/rex.c b/qse/lib/cmn/rex.c index 9dcbad53..24b7d1b2 100644 --- a/qse/lib/cmn/rex.c +++ b/qse/lib/cmn/rex.c @@ -1,5 +1,5 @@ /* - * $Id: rex.c 348 2010-08-26 06:26:28Z hyunghwan.chung $ + * $Id: rex.c 368 2010-11-03 14:24:29Z hyunghwan.chung $ * Copyright 2006-2009 Chung, Hyung-Hwan. This file is part of QSE. @@ -1349,6 +1349,8 @@ static int addsimplecand ( exec_t* e, group_t* group, qse_rex_node_t* node, qse_size_t occ, const qse_char_t* mptr) { + cand_t cand; + QSE_ASSERT ( node->id == QSE_REX_NODE_NOP || node->id == QSE_REX_NODE_BOL || @@ -1358,8 +1360,6 @@ static int addsimplecand ( node->id == QSE_REX_NODE_CSET ); - cand_t cand; - cand.node = node; cand.occ = occ; cand.group = group; diff --git a/qse/lib/cmn/xma.c b/qse/lib/cmn/xma.c index 8681ea74..dfc7e74d 100644 --- a/qse/lib/cmn/xma.c +++ b/qse/lib/cmn/xma.c @@ -252,9 +252,11 @@ static qse_xma_blk_t* alloc_from_freelist ( { if (free->size >= size) { + qse_size_t rem; + detach_from_freelist (xma, free); - qse_size_t rem = free->size - size; + rem = free->size - size; if (rem >= MINBLKLEN) { qse_xma_blk_t* tmp; diff --git a/qse/lib/utl/http.c b/qse/lib/utl/http.c index eda95c2c..d9a9334e 100644 --- a/qse/lib/utl/http.c +++ b/qse/lib/utl/http.c @@ -543,42 +543,132 @@ qse_printf (QSE_T("BADREQ\n")); return QSE_NULL; } -struct cbserter_ctx_t +#define octet_tolower(c) (((c) >= 'A' && (c) <= 'Z') ? ((c) | 0x20) : (c)) +#define octet_toupper(c) (((c) >= 'a' && (c) <= 'z') ? ((c) & ~0x20) : (c)) + +static QSE_INLINE int compare_octets ( + const qse_byte_t* s1, qse_size_t len1, + const qse_byte_t* s2, qse_size_t len2) +{ + qse_char_t c1, c2; + const qse_byte_t* end1 = s1 + len1; + const qse_byte_t* end2 = s2 + len2; + + while (s1 < end1) + { + c1 = octet_toupper (*s1); + if (s2 < end2) + { + c2 = octet_toupper (*s2); + if (c1 > c2) return 1; + if (c1 < c2) return -1; + } + else return 1; + s1++; s2++; + } + + return (s2 < end2)? -1: 0; +} + + +static QSE_INLINE void capture_content_length ( + qse_http_t* http, qse_htb_pair_t* pair) +{ + qse_printf (QSE_T("content length %.*S\n"), (int)pair->vlen, pair->vptr); +} + +static QSE_INLINE void capture_content_type ( + qse_http_t* http, qse_htb_pair_t* pair) +{ + qse_printf (QSE_T("content type %.*S\n"), (int)pair->vlen, pair->vptr); +} + +static QSE_INLINE void capture_host ( + qse_http_t* http, qse_htb_pair_t* pair) +{ + qse_printf (QSE_T("host capture => %.*S\n"), (int)pair->vlen, pair->vptr); +} + +static QSE_INLINE void capture_key_header ( + qse_http_t* http, qse_htb_pair_t* pair) +{ + static struct + { + const qse_byte_t* ptr; + qse_size_t len; + void (*handler) (qse_http_t*, qse_htb_pair_t*); + } hdrtab[] = + { + { "Content-Length", 14, capture_content_length }, + { "Content-Type", 12, capture_content_type }, + { "Host", 4, capture_host } + }; + + int n; + qse_size_t mid, count, base = 0; + + /* perform binary search */ + for (count = QSE_COUNTOF(hdrtab); count > 0; count /= 2) + { + mid = base + count / 2; + + n = compare_octets ( + pair->kptr, pair->klen, + hdrtab[mid].ptr, hdrtab[mid].len + ); + + if (n == 0) + { + /* bingo! */ + hdrtab[mid].handler (http, pair); + break; + } + if (n > 0) { base = mid + 1; count--; } + } +} + +struct hdr_cbserter_ctx_t { qse_http_t* http; void* vptr; qse_size_t vlen; }; -static qse_htb_pair_t* cbserter ( +static qse_htb_pair_t* hdr_cbserter ( qse_htb_t* htb, qse_htb_pair_t* pair, void* kptr, qse_size_t klen, void* ctx) { - struct cbserter_ctx_t* tx = (struct cbserter_ctx_t*)ctx; + struct hdr_cbserter_ctx_t* tx = (struct hdr_cbserter_ctx_t*)ctx; if (pair == QSE_NULL) { - /* the key is new. create a new pair with the key and the value */ + /* the key is new. let's create a new pair. */ qse_htb_pair_t* p; + p = qse_htb_allocpair (htb, kptr, klen, tx->vptr, tx->vlen); + if (p == QSE_NULL) tx->http->errnum = QSE_HTTP_ENOMEM; + else capture_key_header (tx->http, p); + return p; } else { - /* the key exists. let's combine values, each separated by a comma */ + /* the key exists. let's combine values, each separated + * by a comma */ struct hdr_cmb_t* cmb; qse_byte_t* ptr; qse_size_t len; - /* TODO: reduce waste in case the same key appears again and again. + /* TODO: reduce waste in case the same key appears again. * - * the current implementation is not space nor performance efficient. - * it allocates a new buffer again whenever it encounters the - * same key. memory is wasted and performance is sacrificed. - * - * hopefully, a http header does not include a lot of duplicate - * fields and this implmentation can afford wastage. + * the current implementation is not space nor performance + * efficient. it allocates a new buffer again whenever it + * encounters the same key. memory is wasted and performance + * is sacrificed. + + * hopefully, a http header does not include a lot of + * duplicate fields and this implmentation can afford wastage. */ /* allocate a block to combine the existing value and the new value */ @@ -632,6 +722,8 @@ Change it to doubly linked for this? cmb->next = tx->http->req.hdr.combined; tx->http->req.hdr.combined = cmb; + capture_key_header (tx->http, pair); + return pair; } } @@ -703,7 +795,7 @@ qse_byte_t* parse_http_header (qse_http_t* http, qse_byte_t* line) *last = '\0'; { - struct cbserter_ctx_t ctx; + struct hdr_cbserter_ctx_t ctx; ctx.http = http; ctx.vptr = value.ptr; @@ -711,7 +803,8 @@ qse_byte_t* parse_http_header (qse_http_t* http, qse_byte_t* line) http->errnum = QSE_HTTP_ENOERR; if (qse_htb_cbsert ( - &http->req.hdr.tab, name.ptr, name.len, cbserter, &ctx) == QSE_NULL) + &http->req.hdr.tab, name.ptr, name.len, + hdr_cbserter, &ctx) == QSE_NULL) { if (http->errnum == QSE_HTTP_ENOERR) http->errnum = QSE_HTTP_ENOMEM; return QSE_NULL;