]> mj.ucw.cz Git - libucw.git/blob - lib/buck2obj.c
Mainline is now v3.3.
[libucw.git] / lib / buck2obj.c
1 /*
2  *      Bucket -> Object converter
3  *
4  *      (c) 2004, Robert Spalek <robert@ucw.cz>
5  */
6
7 #include "lib/lib.h"
8 #include "lib/fastbuf.h"
9 #include "charset/unicode.h"
10 #include "lib/object.h"
11 #include "lib/bucket.h"
12 #include "lib/lizard.h"
13 #include "lib/buck2obj.h"
14
15 #include <errno.h>
16
17 static inline byte *
18 decode_attributes(byte *ptr, byte *end, struct odes *o)
19 {
20   /* FIXME: this forbids storing attributes with empty string as a value.
21    * Verify whether it is used or not.  */
22   while (ptr < end)
23   {
24     uns len;
25     GET_UTF8(ptr, len);
26     if (!len)
27       break;
28     byte type = ptr[len];
29     ptr[len] = 0;
30     obj_add_attr(o, type, ptr);
31     ptr += len + 1;
32   }
33   return ptr;
34 }
35
36 int
37 extract_odes(struct obuck_header *hdr, struct fastbuf *body, struct odes *o, byte *buf, uns buf_len, struct lizard_buffer *lizard_buf)
38 {
39   if (hdr->type < BUCKET_TYPE_V30C)
40   {
41     oa_allocate = 1;
42     obj_read_multi(body, o);
43   }
44   else
45   {
46     oa_allocate = 0;
47
48     /* Read all the bucket into 1 buffer, 0-copy if possible.  */
49     byte *ptr, *end;
50     uns len = bdirect_read_prepare(body, &ptr);         // WARNING: must NOT use mmaped-I/O
51     if (len < hdr->length)
52     {
53       if (hdr->length > buf_len)
54       {
55         errno = EFBIG;
56         return -1;
57       }
58       len = bread(body, buf, hdr->length);
59       ptr = buf;
60     }
61     end = ptr + len;
62
63     ptr = decode_attributes(ptr, end, o);               // header
64     if (hdr->type == BUCKET_TYPE_V30C)                  // decompression
65     {
66       GET_UTF8(ptr, len);
67       int res = lizard_decompress_safe(ptr, lizard_buf, len);
68       if (res != (int) len)
69       {
70         if (res < 0)
71           return res;
72         errno = EINVAL;
73         return -1;
74       }
75       ptr = lizard_buf->ptr;
76       end = ptr + len;
77     }
78     ptr = decode_attributes(ptr, end, o);               // body
79
80     if (ptr != end)
81     {
82       errno = EINVAL;
83       return -1;
84     }
85   }
86   return 0;
87 }