]> mj.ucw.cz Git - libucw.git/blob - lib/obj2buck.c
enlarge MAX_ATTR_SIZE
[libucw.git] / lib / obj2buck.c
1 /*
2  *      Generating Buckets from Objects
3  *
4  *      (c) 2004, Robert Spalek <robert@ucw.cz>
5  *
6  *      This software may be freely distributed and used according to the terms
7  *      of the GNU Lesser General Public License.
8  */
9
10 #include "lib/lib.h"
11 #include "lib/fastbuf.h"
12 #include "lib/ff-utf8.h"
13 #include "lib/bucket.h"
14 #include "lib/object.h"
15
16 #include <string.h>
17 #include <stdarg.h>
18
19 static uns use_v33;
20 static int hdr_sep;
21
22 void
23 put_attr_set_type(uns type)
24 {
25   switch (type)
26     {
27     case BUCKET_TYPE_PLAIN:
28       use_v33 = 0;
29       hdr_sep = -1;
30       break;
31     case BUCKET_TYPE_V30:
32       use_v33 = 0;
33       hdr_sep = '\n';
34       break;
35     case BUCKET_TYPE_V33:
36     case BUCKET_TYPE_V33_LIZARD:
37       use_v33 = 1;
38       hdr_sep = 0;
39       break;
40     default:
41       die("Don't know how to generate buckets of type %08x", type);
42     }
43 }
44
45 uns
46 size_attr(uns len)
47 {
48   ASSERT(len <= MAX_ATTR_SIZE);
49   if (use_v33)
50     {
51       len++;
52       return len + utf8_space(len);
53     }
54   else
55     return len + 2;
56 }
57
58 inline byte *
59 put_attr(byte *ptr, uns type, byte *val, uns len)
60 {
61   if (use_v33)
62   {
63     PUT_UTF8_32(ptr, len+1);
64     memcpy(ptr, val, len);
65     ptr += len;
66     *ptr++ = type;
67   }
68   else
69   {
70     *ptr++ = type;
71     memcpy(ptr, val, len);
72     ptr += len;
73     *ptr++ = '\n';
74   }
75   return ptr;
76 }
77
78 byte *
79 put_attr_str(byte *ptr, uns type, byte *val)
80 {
81   return put_attr(ptr, type, val, strlen(val));
82 }
83
84 inline byte *
85 put_attr_vformat(byte *ptr, uns type, byte *mask, va_list va)
86 {
87   if (use_v33)
88   {
89     uns len = vsprintf(ptr+1, mask, va);
90     if (len >= 127)
91     {
92       byte tmp[6], *tmp_end = tmp;
93       PUT_UTF8_32(tmp_end, len+1);
94       uns l = tmp_end - tmp;
95       memmove(ptr+l, ptr+1, len);
96       memcpy(ptr, tmp, l);
97       ptr += l + len;
98     }
99     else
100     {
101       *ptr = len+1;
102       ptr += len+1;
103     }
104     *ptr++ = type;
105   }
106   else
107   {
108     *ptr++ = type;
109     ptr += vsprintf(ptr, mask, va);
110     *ptr++ = '\n';
111   }
112   return ptr;
113 }
114
115 byte *
116 put_attr_format(byte *ptr, uns type, char *mask, ...)
117 {
118   va_list va;
119   va_start(va, mask);
120   byte *ret = put_attr_vformat(ptr, type, mask, va);
121   va_end(va);
122   return ret;
123 }
124
125 byte *
126 put_attr_num(byte *ptr, uns type, uns val)
127 {
128   if (use_v33)
129   {
130     uns len = sprintf(ptr+1, "%d", val) + 1;
131     *ptr = len;
132     ptr += len;
133     *ptr++ = type;
134   }
135   else
136     ptr += sprintf(ptr, "%c%d\n", type, val);
137   return ptr;
138 }
139
140 byte *
141 put_attr_separator(byte *ptr)
142 {
143   if (hdr_sep >= 0)
144     *ptr++ = hdr_sep;
145   return ptr;
146 }
147
148 inline void
149 bput_attr(struct fastbuf *b, uns type, byte *val, uns len)
150 {
151   if (use_v33)
152   {
153     bput_utf8_32(b, len+1);
154     bwrite(b, val, len);
155     bputc(b, type);
156   }
157   else
158   {
159     bputc(b, type);
160     bwrite(b, val, len);
161     bputc(b, '\n');
162   }
163 }
164
165 void
166 bput_attr_str(struct fastbuf *b, uns type, byte *val)
167 {
168   bput_attr(b, type, val, strlen(val));
169 }
170
171 inline void
172 bput_attr_vformat(struct fastbuf *b, uns type, byte *mask, va_list va)
173 {
174   if (use_v33)
175   {
176     int len = vsnprintf(NULL, 0, mask, va);
177     if (len < 0)
178       die("vsnprintf() does not support size=0");
179     bput_utf8_32(b, len+1);
180     vbprintf(b, mask, va);
181     bputc(b, type);
182   }
183   else
184   {
185     bputc(b, type);
186     vbprintf(b, mask, va);
187     bputc(b, '\n');
188   }
189 }
190
191 void
192 bput_attr_format(struct fastbuf *b, uns type, char *mask, ...)
193 {
194   va_list va;
195   va_start(va, mask);
196   bput_attr_vformat(b, type, mask, va);
197   va_end(va);
198 }
199
200 void
201 bput_attr_num(struct fastbuf *b, uns type, uns val)
202 {
203   if (use_v33)
204   {
205     byte tmp[12];
206     uns len = sprintf(tmp, "%d", val);
207     bputc(b, len+1);
208     bwrite(b, tmp, len);
209     bputc(b, type);
210   }
211   else
212     bprintf(b, "%c%d\n", type, val);
213 }
214
215 void
216 bput_attr_separator(struct fastbuf *b)
217 {
218   if (hdr_sep >= 0)
219     bputc(b, hdr_sep);
220 }
221
222 void
223 obj_write(struct fastbuf *f, struct odes *d)
224 {
225   for(struct oattr *a=d->attrs; a; a=a->next)
226     for(struct oattr *b=a; b; b=b->same)
227       {
228         byte *z;
229         for (z = b->val; *z; z++)
230           if (*z < ' ' && *z != '\t')
231             {
232               log(L_ERROR, "obj_dump: Found non-ASCII character %02x (URL might be %s) in %c%s", *z, obj_find_aval(d, 'U'), a->attr, b->val);
233               *z = '?';
234             }
235         ASSERT(z - b->val <= MAX_ATTR_SIZE-2);
236         bput_attr_str(f, a->attr, b->val);
237       }
238 }
239
240 void
241 obj_write_nocheck(struct fastbuf *f, struct odes *d)
242 {
243   for(struct oattr *a=d->attrs; a; a=a->next)
244     for(struct oattr *b=a; b; b=b->same)
245       bput_attr_str(f, a->attr, b->val);
246 }