]> mj.ucw.cz Git - libucw.git/blob - lib/obj2buck.c
367764a5aef3f214610752313cbe07daf19c338d
[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 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 inline byte *
46 put_attr(byte *ptr, uns type, byte *val, uns len)
47 {
48   if (use_v33)
49   {
50     PUT_UTF8(ptr, len+1);
51     memcpy(ptr, val, len);
52     ptr += len;
53     *ptr++ = type;
54   }
55   else
56   {
57     *ptr++ = type;
58     memcpy(ptr, val, len);
59     ptr += len;
60     *ptr++ = '\n';
61   }
62   return ptr;
63 }
64
65 byte *
66 put_attr_str(byte *ptr, uns type, byte *val)
67 {
68   return put_attr(ptr, type, val, strlen(val));
69 }
70
71 inline byte *
72 put_attr_vformat(byte *ptr, uns type, byte *mask, va_list va)
73 {
74   if (use_v33)
75   {
76     uns len = vsprintf(ptr+1, mask, va);
77     if (len >= 127)
78     {
79       byte tmp[6], *tmp_end = tmp;
80       PUT_UTF8(tmp_end, len+1);
81       uns l = tmp_end - tmp;
82       memmove(ptr+l, ptr+1, len);
83       memcpy(ptr, tmp, l);
84       ptr += l + len;
85     }
86     else
87     {
88       *ptr = len+1;
89       ptr += len+1;
90     }
91     *ptr++ = type;
92   }
93   else
94   {
95     *ptr++ = type;
96     ptr += vsprintf(ptr, mask, va);
97     *ptr++ = '\n';
98   }
99   return ptr;
100 }
101
102 byte *
103 put_attr_format(byte *ptr, uns type, char *mask, ...)
104 {
105   va_list va;
106   va_start(va, mask);
107   byte *ret = put_attr_vformat(ptr, type, mask, va);
108   va_end(va);
109   return ret;
110 }
111
112 byte *
113 put_attr_num(byte *ptr, uns type, uns val)
114 {
115   if (use_v33)
116   {
117     uns len = sprintf(ptr+1, "%d", val) + 1;
118     *ptr = len;
119     ptr += len;
120     *ptr++ = type;
121   }
122   else
123     ptr += sprintf(ptr, "%c%d\n", type, val);
124   return ptr;
125 }
126
127 byte *
128 put_attr_separator(byte *ptr)
129 {
130   if (hdr_sep >= 0)
131     *ptr++ = hdr_sep;
132   return ptr;
133 }
134
135 inline void
136 bput_attr(struct fastbuf *b, uns type, byte *val, uns len)
137 {
138   if (use_v33)
139   {
140     bput_utf8(b, len+1);
141     bwrite(b, val, len);
142     bputc(b, type);
143   }
144   else
145   {
146     bputc(b, type);
147     bwrite(b, val, len);
148     bputc(b, '\n');
149   }
150 }
151
152 void
153 bput_attr_str(struct fastbuf *b, uns type, byte *val)
154 {
155   bput_attr(b, type, val, strlen(val));
156 }
157
158 inline void
159 bput_attr_vformat(struct fastbuf *b, uns type, byte *mask, va_list va)
160 {
161   if (use_v33)
162   {
163     int len = vsnprintf(NULL, 0, mask, va);
164     if (len < 0)
165       die("vsnprintf() does not support size=0");
166     bput_utf8(b, len+1);
167     vbprintf(b, mask, va);
168     bputc(b, type);
169   }
170   else
171   {
172     bputc(b, type);
173     vbprintf(b, mask, va);
174     bputc(b, '\n');
175   }
176 }
177
178 void
179 bput_attr_format(struct fastbuf *b, uns type, char *mask, ...)
180 {
181   va_list va;
182   va_start(va, mask);
183   bput_attr_vformat(b, type, mask, va);
184   va_end(va);
185 }
186
187 void
188 bput_attr_num(struct fastbuf *b, uns type, uns val)
189 {
190   if (use_v33)
191   {
192     byte tmp[12];
193     uns len = sprintf(tmp, "%d", val);
194     bputc(b, len+1);
195     bwrite(b, tmp, len);
196     bputc(b, type);
197   }
198   else
199     bprintf(b, "%c%d\n", type, val);
200 }
201
202 void
203 bput_attr_separator(struct fastbuf *b)
204 {
205   if (hdr_sep >= 0)
206     bputc(b, hdr_sep);
207 }
208
209 void
210 obj_write(struct fastbuf *f, struct odes *d)
211 {
212   for(struct oattr *a=d->attrs; a; a=a->next)
213     for(struct oattr *b=a; b; b=b->same)
214       {
215         byte *z;
216         for (z = b->val; *z; z++)
217           if (*z < ' ' && *z != '\t')
218             {
219               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);
220               *z = '?';
221             }
222         ASSERT(z - b->val <= MAX_ATTR_SIZE-2);
223         bput_attr_str(f, a->attr, b->val);
224       }
225 }
226
227 void
228 obj_write_nocheck(struct fastbuf *f, struct odes *d)
229 {
230   for(struct oattr *a=d->attrs; a; a=a->next)
231     for(struct oattr *b=a; b; b=b->same)
232       bput_attr_str(f, a->attr, b->val);
233 }