]> mj.ucw.cz Git - libucw.git/commitdiff
added buck2obj_realloc(), it is automatically called when needed
authorRobert Spalek <robert@ucw.cz>
Fri, 25 Jun 2004 16:28:16 +0000 (16:28 +0000)
committerRobert Spalek <robert@ucw.cz>
Fri, 25 Jun 2004 16:28:16 +0000 (16:28 +0000)
lib/buck2obj.c
lib/buck2obj.h

index b2eb455ee165537e70bb16fbc28172f726c4f719..8c74bdd13bb6dac1028e8bb5d1df7a2ad94fbe51 100644 (file)
 
 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;
index e59ead024b0d76f128597c4b7b8c7fc7c1501473..0a7d0c05bca253c972bf9a23781f8fbcd0264593 100644 (file)
@@ -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