From: Robert Spalek Date: Fri, 25 Jun 2004 16:28:16 +0000 (+0000) Subject: added buck2obj_realloc(), it is automatically called when needed X-Git-Tag: holmes-import~1015 X-Git-Url: http://mj.ucw.cz/gitweb/?a=commitdiff_plain;h=1b0a16240bdcc069979452f56fbbf2299625be78;p=libucw.git added buck2obj_realloc(), it is automatically called when needed --- diff --git a/lib/buck2obj.c b/lib/buck2obj.c index b2eb455e..8c74bdd1 100644 --- a/lib/buck2obj.c +++ b/lib/buck2obj.c @@ -23,19 +23,33 @@ struct buck2obj_buf { + uns max_len, raw_len; byte *raw; - uns raw_len; struct lizard_buffer *lizard; struct mempool *mp; }; -struct buck2obj_buf * -buck2obj_alloc(uns max_len, struct mempool *mp) +static void +buck2obj_alloc_internal(struct buck2obj_buf *buf, uns max_len) { - struct buck2obj_buf *buf = xmalloc(sizeof(struct buck2obj_buf)); + buf->max_len = max_len; buf->raw_len = max_len * LIZARD_MAX_MULTIPLY + LIZARD_MAX_ADD + MAX_HEADER_SIZE; buf->raw = xmalloc(buf->raw_len); buf->lizard = lizard_alloc(max_len); +} + +static void +buck2obj_free_internal(struct buck2obj_buf *buf) +{ + lizard_free(buf->lizard); + xfree(buf->raw); +} + +struct buck2obj_buf * +buck2obj_alloc(uns max_len, struct mempool *mp) +{ + struct buck2obj_buf *buf = xmalloc(sizeof(struct buck2obj_buf)); + buck2obj_alloc_internal(buf, max_len); buf->mp = mp; return buf; } @@ -43,11 +57,21 @@ buck2obj_alloc(uns max_len, struct mempool *mp) void buck2obj_free(struct buck2obj_buf *buf) { - lizard_free(buf->lizard); - xfree(buf->raw); + buck2obj_free_internal(buf); xfree(buf); } +void +buck2obj_realloc(struct buck2obj_buf *buf, uns max_len) +{ + if (max_len <= buf->max_len) + return; + if (max_len < 2*buf->max_len + 1) // to ensure amortized logarithmic complexity + max_len = 2*buf->max_len + 1; + buck2obj_free_internal(buf); + buck2obj_alloc_internal(buf, max_len); +} + static inline byte * decode_attributes(byte *ptr, byte *end, struct odes *o, uns can_overwrite) { @@ -128,7 +152,7 @@ buck2obj_convert(struct buck2obj_buf *buf, uns buck_type, struct fastbuf *body) /* Copy if the original buffer is too small. * If it is write-protected, copy it also if it is uncompressed. */ if (buck_len > buf->raw_len) - RET_ERR(EFBIG); + buck2obj_realloc(buf, buck_len); len = bread(body, buf->raw, buck_len); ptr = buf->raw; can_overwrite = 2; diff --git a/lib/buck2obj.h b/lib/buck2obj.h index e59ead02..0a7d0c05 100644 --- a/lib/buck2obj.h +++ b/lib/buck2obj.h @@ -8,6 +8,7 @@ struct buck2obj_buf; struct buck2obj_buf *buck2obj_alloc(uns max_len, struct mempool *mp); void buck2obj_free(struct buck2obj_buf *buf); +void buck2obj_realloc(struct buck2obj_buf *buf, uns max_len); struct odes *buck2obj_convert(struct buck2obj_buf *buf, uns buck_type, struct fastbuf *body); /* If BCONFIG_CAN_OVERWRITE(body)==2, then the buffer of body has probably * been tampered (unless the bucket is larger than the buffer). In such a