enhanced resizing of qse_lda_t and qse_str_t

This commit is contained in:
2010-10-22 07:29:12 +00:00
parent a5f99ece99
commit 299852beaa
11 changed files with 317 additions and 560 deletions

View File

@ -1,5 +1,5 @@
/*
* $Id: lda.c 354 2010-09-03 12:50:08Z hyunghwan.chung $
* $Id: lda.c 360 2010-10-21 13:29:12Z hyunghwan.chung $
*
Copyright 2006-2009 Chung, Hyung-Hwan.
This file is part of QSE.
@ -347,12 +347,14 @@ size_t qse_lda_insert (lda_t* lda, size_t pos, void* dptr, size_t dlen)
* doesn't modify lda on any errors */
if (pos >= lda->capa || lda->size >= lda->capa)
{
size_t capa;
size_t capa, mincapa;
/* get the minimum capacity needed */
mincapa = (pos >= lda->size)? (pos + 1): (lda->size + 1);
if (lda->sizer)
{
capa = (pos >= lda->size)? (pos + 1): (lda->size + 1);
capa = lda->sizer (lda, capa);
capa = lda->sizer (lda, mincapa);
}
else
{
@ -368,13 +370,21 @@ size_t qse_lda_insert (lda_t* lda, size_t pos, void* dptr, size_t dlen)
}
}
if (qse_lda_setcapa(lda,capa) == QSE_NULL)
do
{
if (lda->freeer)
lda->freeer (lda, DPTR(node), DLEN(node));
QSE_MMGR_FREE (lda->mmgr, node);
return QSE_LDA_NIL;
}
if (qse_lda_setcapa(lda,capa) != QSE_NULL) break;
if (capa <= mincapa)
{
if (lda->freeer)
lda->freeer (lda, DPTR(node), DLEN(node));
QSE_MMGR_FREE (lda->mmgr, node);
return QSE_LDA_NIL;
}
capa--; /* let it retry after lowering the capacity */
}
while (1);
}
if (pos >= lda->capa || lda->size >= lda->capa)

View File

@ -1,5 +1,5 @@
/*
* $Id: str_dyn.c 348 2010-08-26 06:26:28Z hyunghwan.chung $
* $Id: str_dyn.c 360 2010-10-21 13:29:12Z hyunghwan.chung $
*
Copyright 2006-2009 Chung, Hyung-Hwan.
This file is part of QSE.
@ -256,12 +256,16 @@ qse_size_t qse_str_ncat (qse_str_t* str, const qse_char_t* s, qse_size_t len)
{
if (len > str->capa - str->len)
{
qse_size_t ncapa;
qse_size_t ncapa, mincapa;
/* let the minimum capacity be as large as
* to fit in the new substring */
mincapa = str->len + len;
if (str->sizer == QSE_NULL)
{
/* increase the capacity by the length to add */
ncapa = str->len + len;
ncapa = mincapa;
/* if the new capacity is less than the double,
* just double it */
if (ncapa < str->capa * 2) ncapa = str->capa * 2;
@ -270,15 +274,19 @@ qse_size_t qse_str_ncat (qse_str_t* str, const qse_char_t* s, qse_size_t len)
{
/* let the user determine the new capacity.
* pass the minimum capacity required as a hint */
ncapa = str->sizer (str, str->len + len);
ncapa = str->sizer (str, mincapa);
/* if no change in capacity, return current length */
if (ncapa == str->capa) return str->len;
}
if (qse_str_setcapa (str, ncapa) == (qse_size_t)-1)
/* change the capacity */
do
{
return (qse_size_t)-1;
if (qse_str_setcapa (str, ncapa) != (qse_size_t)-1) break;
if (ncapa <= mincapa) return (qse_size_t)-1;
ncapa--;
}
while (1);
}
if (len > str->capa - str->len)

View File

@ -705,24 +705,39 @@ void qse_xma_free (qse_xma_t* xma, void* b)
void qse_xma_dump (qse_xma_t* xma, qse_xma_dumper_t dumper, void* target)
{
qse_xma_blk_t* tmp;
unsigned long long fsum, asum;
qse_ulong_t fsum, asum;
#ifdef QSE_XMA_ENABLE_STAT
unsigned long long isum;
qse_ulong_t isum;
#endif
dumper (target, QSE_T("<XMA DUMP>\n"));
#ifdef QSE_XMA_ENABLE_STAT
dumper (target, QSE_T("== statistics ==\n"));
#if QSE_SIZEOF_LONG >= QSE_SIZEOF_LONG_LONG
dumper (target, QSE_T("total = %lu\n"), (unsigned long)xma->stat.total);
dumper (target, QSE_T("alloc = %lu\n"), (unsigned long)xma->stat.alloc);
dumper (target, QSE_T("avail = %lu\n"), (unsigned long)xma->stat.avail);
#else
dumper (target, QSE_T("total = %llu\n"), (unsigned long long)xma->stat.total);
dumper (target, QSE_T("alloc = %llu\n"), (unsigned long long)xma->stat.alloc);
dumper (target, QSE_T("avail = %llu\n"), (unsigned long long)xma->stat.avail);
#endif
#endif
dumper (target, QSE_T("== blocks ==\n"));
dumper (target, QSE_T(" size avail address\n"));
for (tmp = xma->head, fsum = 0, asum = 0; tmp; tmp = tmp->b.next)
{
dumper (target, QSE_T(" %-18llu %-5d %p\n"), (unsigned long long)tmp->size, tmp->avail, tmp);
#if QSE_SIZEOF_LONG >= QSE_SIZEOF_LONG_LONG
dumper (target, QSE_T(" %-18lu %-5d %p\n"),
(unsigned long)tmp->size, tmp->avail, tmp
);
#else
dumper (target, QSE_T(" %-18llu %-5d %p\n"),
(unsigned long long)tmp->size, tmp->avail, tmp
);
#endif
if (tmp->avail) fsum += tmp->size;
else asum += tmp->size;
}
@ -732,11 +747,22 @@ void qse_xma_dump (qse_xma_t* xma, qse_xma_dumper_t dumper, void* target)
#endif
dumper (target, QSE_T("---------------------------------------\n"));
dumper (target, QSE_T("Allocated blocks: %18llu bytes\n"), asum);
dumper (target, QSE_T("Available blocks: %18llu bytes\n"), fsum);
#if QSE_SIZEOF_LONG >= QSE_SIZEOF_LONG_LONG
dumper (target, QSE_T("Allocated blocks: %18lu bytes\n"), (unsigned long)asum);
dumper (target, QSE_T("Available blocks: %18lu bytes\n"), (unsigned long)fsum);
#else
dumper (target, QSE_T("Allocated blocks: %18llu bytes\n"), (unsigned long long)asum);
dumper (target, QSE_T("Available blocks: %18llu bytes\n"), (unsigned long long)fsum);
#endif
#ifdef QSE_XMA_ENABLE_STAT
dumper (target, QSE_T("Internal use : %18llu bytes\n"), isum);
dumper (target, QSE_T("Total : %18llu bytes\n"), asum + fsum + isum);
#if QSE_SIZEOF_LONG >= QSE_SIZEOF_LONG_LONG
dumper (target, QSE_T("Internal use : %18lu bytes\n"), (unsigned long)isum);
dumper (target, QSE_T("Total : %18lu bytes\n"), (unsigned long)(asum + fsum + isum));
#else
dumper (target, QSE_T("Internal use : %18llu bytes\n"), (unsigned long long)isum);
dumper (target, QSE_T("Total : %18llu bytes\n"), (unsigned long long)(asum + fsum + isum));
#endif
#endif
QSE_ASSERT (asum == xma->stat.alloc);

View File

@ -1,5 +1,5 @@
/*
* $Id: sed.c 348 2010-08-26 06:26:28Z hyunghwan.chung $
* $Id: sed.c 360 2010-10-21 13:29:12Z hyunghwan.chung $
*
Copyright 2006-2009 Chung, Hyung-Hwan.
This file is part of QSE.
@ -41,7 +41,7 @@ do { \
qse_sed_seterror (sed, num, &__ea__, loc); \
} while (0)
qse_sed_t* qse_sed_open (qse_mmgr_t* mmgr, qse_size_t xtn)
qse_sed_t* qse_sed_open (qse_mmgr_t* mmgr, qse_size_t xtnsize)
{
qse_sed_t* sed;
@ -55,7 +55,7 @@ qse_sed_t* qse_sed_open (qse_mmgr_t* mmgr, qse_size_t xtn)
if (mmgr == QSE_NULL) return QSE_NULL;
}
sed = (qse_sed_t*) QSE_MMGR_ALLOC (mmgr, QSE_SIZEOF(qse_sed_t) + xtn);
sed = (qse_sed_t*) QSE_MMGR_ALLOC (mmgr, QSE_SIZEOF(qse_sed_t) + xtnsize);
if (sed == QSE_NULL) return QSE_NULL;
if (qse_sed_init (sed, mmgr) == QSE_NULL)

View File

@ -22,6 +22,8 @@
#include <qse/cmn/chr.h>
#include "../cmn/mem.h"
QSE_IMPLEMENT_COMMON_FUNCTIONS (http)
static int is_http_space (qse_char_t c)
{
return QSE_ISSPACE(c) && c != QSE_T('\r') && c != QSE_T('\n');
@ -205,3 +207,165 @@ ok:
*last = QSE_T('\0');
return p;
}
static QSE_INLINE void init_buffer (qse_http_t* http, qse_http_buf_t* buf)
{
buf->size = 0;
buf->capa = 0;
buf->data = QSE_NULL;
}
static QSE_INLINE void fini_buffer (qse_http_t* http, qse_http_buf_t* buf)
{
if (buf->data)
{
QSE_MMGR_FREE (http->mmgr, buf->data);
buf->capa = 0;
buf->size = 0;
buf->data = QSE_NULL;
}
}
static QSE_INLINE_ALWAYS void clear_buffer (qse_http_t* http, qse_http_buf_t* buf)
{
buf->size = 0;
}
static QSE_INLINE int push_to_buffer (
qse_http_t* http, qse_http_buf_t* buf,
const qse_char_t* ptr, qse_size_t len)
{
qse_size_t nsize = (buf)->size + len;
const qse_char_t* end = ptr + len;
if (nsize > (buf)->capa)
{
qse_size_t ncapa = (nsize > (buf)->capa * 2)? nsize: ((buf)->capa * 2);
do
{
void* tmp = QSE_MMGR_REALLOC ((http)->mmgr, (buf)->data, ncapa * QSE_SIZEOF(*ptr));
if (tmp)
{
(buf)->capa = ncapa;
(buf)->data = tmp;
break;
}
if (ncapa <= nsize)
{
(http)->errnum = QSE_HTTP_ENOMEM;
return -1;
}
/* retry with a smaller size */
ncapa--;
}
while (1);
}
while (ptr < end) (buf)->data[(buf)->size++] = *ptr++;
return 0;
}
#define QSE_HTTP_STATE_REQ 1
#define QSE_HTTP_STATE_HDR 2
#define QSE_HTTP_STATE_POST 3
qse_http_t* qse_http_open (qse_mmgr_t* mmgr, qse_size_t xtnsize)
{
qse_http_t* http;
if (mmgr == QSE_NULL)
{
mmgr = QSE_MMGR_GETDFL();
QSE_ASSERTX (mmgr != QSE_NULL,
"Set the memory manager with QSE_MMGR_SETDFL()");
if (mmgr == QSE_NULL) return QSE_NULL;
}
http = (qse_http_t*) QSE_MMGR_ALLOC (
mmgr, QSE_SIZEOF(qse_http_t) + xtnsize
);
if (http == QSE_NULL) return QSE_NULL;
if (qse_http_init (http, mmgr) == QSE_NULL)
{
QSE_MMGR_FREE (http->mmgr, http);
return QSE_NULL;
}
return http;
}
void qse_http_close (qse_http_t* http)
{
qse_http_fini (http);
QSE_MMGR_FREE (http->mmgr, http);
}
qse_http_t* qse_http_init (qse_http_t* http, qse_mmgr_t* mmgr)
{
if (mmgr == QSE_NULL) mmgr = QSE_MMGR_GETDFL();
QSE_MEMSET (http, 0, QSE_SIZEOF(*http));
http->mmgr = mmgr;
init_buffer (http, &http->state.buf);
http->state.no = QSE_HTTP_STATE_REQ;
return http;
}
void qse_http_fini (qse_http_t* http)
{
fini_buffer (http, &http->state.buf);
}
/* feed the percent encoded string */
int qse_http_feed (qse_http_t* http, const qse_char_t* ptr, qse_size_t len)
{
const qse_char_t* end = ptr + len;
const qse_char_t* blk = ptr;
while (ptr < end)
{
if (*ptr++ == '\n')
{
if (push_to_buffer (http, &http->state.buf, blk, ptr - blk) <= -1) return -1;
blk = ptr; /* let ptr point to the next character to '\n' */
if (http->state.no == QSE_HTTP_STATE_REQ)
{
/*
if (parse_http_req (http, &http->state.buf) <= -1)
{
return -1;
}
*/
}
else
{
/*
if (parse_http_hdr (http, &http->state.buf) <= -1)
{
return -1;
}
*/
}
qse_printf (QSE_T("[%.*s]\n"), (int)http->state.buf.size, http->state.buf.data);
clear_buffer (http, &http->state.buf);
}
}
/* enbuffer the unfinished data */
if (push_to_buffer (http, &http->state.buf, blk, ptr - blk) <= -1) return -1;
qse_printf (QSE_T("UNFINISHED [%.*s]\n"), (int)http->state.buf.size, http->state.buf.data);
return 0;
}