X-Git-Url: http://mj.ucw.cz/gitweb/?a=blobdiff_plain;f=lib%2Fbuck2obj.c;h=e90ff875447eead2125b08e7d8624804df20a612;hb=06a12f5259063aa66bb4d6d8b4226677f4849157;hp=b87326bba3f18653eb2b45cf41a9d6c365309a9b;hpb=b4e90a25c062283506931c8c21a38c2d23ecde6f;p=libucw.git diff --git a/lib/buck2obj.c b/lib/buck2obj.c index b87326bb..e90ff875 100644 --- a/lib/buck2obj.c +++ b/lib/buck2obj.c @@ -1,5 +1,5 @@ /* - * Bucket -> Object Converter + * Generating Objects from Buckets * * (c) 2004, Robert Spalek * (c) 2004, Martin Mares @@ -7,23 +7,19 @@ #include "lib/lib.h" #include "lib/unaligned.h" -#include "lib/pools.h" +#include "lib/mempool.h" #include "lib/fastbuf.h" -#include "charset/unicode.h" +#include "lib/unicode.h" #include "lib/object.h" #include "lib/bucket.h" #include "lib/lizard.h" -#include "lib/buck2obj.h" +#include "lib/bbuf.h" #include #include #include -#define RET_ERR(num) ({ errno = num; return NULL; }) - -#define GBUF_TYPE byte -#define GBUF_PREFIX(x) bb_##x -#include "lib/gbuf.h" +#define RET_ERR(num) ({ errno = num; return -1; }) struct buck2obj_buf { @@ -84,23 +80,36 @@ decode_attributes(byte *ptr, byte *end, struct odes *o, uns can_overwrite) return ptr; } -struct odes * -obj_read_bucket(struct buck2obj_buf *buf, struct mempool *pool, uns buck_type, uns buck_len, struct fastbuf *body, uns *body_start) +int +buck2obj_parse(struct buck2obj_buf *buf, uns buck_type, uns buck_len, struct fastbuf *body, struct odes *o_hdr, uns *body_start, struct odes *o_body) { - struct odes *o = obj_new(pool); - - if (buck_type == BUCKET_TYPE_PLAIN || buck_type == BUCKET_TYPE_V30) + if (buck_type <= BUCKET_TYPE_PLAIN) { - if (!body_start) // header + body: ignore empty lines, read until EOF or NUL - { - obj_read_multi(body, o); - bgetc(body); - } - else // header only: end on EOF or the first empty line - { - sh_off_t start = btell(body); - obj_read(body, o); + if (body_start) // there is no header part + *body_start = 0; + // ignore empty lines and read until the end of the bucket + sh_off_t end = btell(body) + buck_len; + byte buf[MAX_ATTR_SIZE]; + while (btell(body) < end && bgets(body, buf, sizeof(buf))) + if (buf[0]) + obj_add_attr(o_hdr, buf[0], buf+1); + ASSERT(btell(body) == end); + } + else if (buck_type == BUCKET_TYPE_V30) + { + sh_off_t start = btell(body); + sh_off_t end = start + buck_len; + byte buf[MAX_ATTR_SIZE]; + while (btell(body) < end && bgets(body, buf, sizeof(buf)) && buf[0]) + obj_add_attr(o_hdr, buf[0], buf+1); + if (body_start) *body_start = btell(body) - start; + else + { + while (btell(body) < end && bgets(body, buf, sizeof(buf))) + if (buf[0]) + obj_add_attr(o_hdr, buf[0], buf+1); + ASSERT(btell(body) == end); } } else if (buck_type == BUCKET_TYPE_V33 || buck_type == BUCKET_TYPE_V33_LIZARD) @@ -122,30 +131,34 @@ obj_read_bucket(struct buck2obj_buf *buf, struct mempool *pool, uns buck_type, u end = ptr + len; byte *start = ptr; - ptr = decode_attributes(ptr, end, o, 0); // header + ptr = decode_attributes(ptr, end, o_hdr, 0); // header if (body_start) { *body_start = ptr - start; if (!copied) bdirect_read_commit(body, ptr); - return o; + return 0; } if (buck_type == BUCKET_TYPE_V33_LIZARD) // decompression { - if (ptr + 4 > end) + if (ptr + 8 > end) RET_ERR(EINVAL); len = GET_U32(ptr); ptr += 4; + uns adler = GET_U32(ptr); + ptr += 4; byte *new_ptr = lizard_decompress_safe(ptr, buf->lizard, len); if (!new_ptr) - return NULL; + return -1; + if (adler32(new_ptr, len) != adler) + RET_ERR(EINVAL); if (!copied) bdirect_read_commit(body, end); ptr = new_ptr; end = ptr + len; copied = 1; } - ptr = decode_attributes(ptr, end, o, 2); // body + ptr = decode_attributes(ptr, end, o_body, 2); // body if (ptr != end) RET_ERR(EINVAL); if (!copied) @@ -153,5 +166,29 @@ obj_read_bucket(struct buck2obj_buf *buf, struct mempool *pool, uns buck_type, u } else RET_ERR(EINVAL); - return o; + return 0; +} + +struct odes * +obj_read_bucket(struct buck2obj_buf *buf, struct mempool *pool, uns buck_type, uns buck_len, struct fastbuf *body, uns *body_start) +{ + struct odes *o = obj_new(pool); + if (buck2obj_parse(buf, buck_type, buck_len, body, o, body_start, o) < 0) + return NULL; + else + return o; +} + +int +obj_read(struct fastbuf *f, struct odes *o) +{ + byte buf[MAX_ATTR_SIZE]; + + while (bgets(f, buf, sizeof(buf))) + { + if (!buf[0]) + return 1; + obj_add_attr(o, buf[0], buf+1); + } + return 0; }