]> mj.ucw.cz Git - libucw.git/blob - lib/object.c
Fix escaping of "+" characters in outgoing parameters. (BTW: when Galeon
[libucw.git] / lib / object.c
1 /*
2  *      Sherlock Library -- Object Functions
3  *
4  *      (c) 1997--2001 Martin Mares <mj@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/pools.h"
12 #include "lib/fastbuf.h"
13
14 #include <string.h>
15 #include <stdio.h>
16
17 #define OBJ_POOL_SIZE 4096
18
19 void
20 obj_dump(struct odes *o)
21 {
22   struct oattr *a, *b;
23
24   for(a=o->attrs; a; a=a->next)
25     for(b=a; b; b=b->same)
26       printf("%c%s\n", (a==b ? a->attr : ' '), b->val);
27 }
28
29 static struct oattr *
30 oa_new(struct odes *o, uns x, byte *v)
31 {
32   struct oattr *a = mp_alloc(o->pool, sizeof(struct oattr) + strlen(v));
33
34   a->next = a->same = NULL;
35   a->last_same = a;
36   a->attr = x;
37   strcpy(a->val, v);
38   return a;
39 }
40
41 struct odes *
42 obj_new(struct mempool *pool)
43 {
44   struct mempool *lp = pool;
45   struct odes *o;
46
47   if (!lp)
48     lp = mp_new(OBJ_POOL_SIZE);
49   o = mp_alloc(lp, sizeof(struct odes));
50   o->pool = lp;
51   o->local_pool = (pool == lp) ? NULL : lp;
52   o->attrs = NULL;
53   return o;
54 }
55
56 void
57 obj_free(struct odes *o)
58 {
59   if (o->local_pool)
60     mp_delete(o->local_pool);
61 }
62
63 int
64 obj_read(struct fastbuf *f, struct odes *o)
65 {
66   byte buf[4096];
67   struct oattr **last = &o->attrs;
68   struct oattr *a, *la;
69
70   la = NULL;
71   *last = NULL;
72   while (bgets(f, buf, sizeof(buf)))
73     {
74       if (!buf[0])
75         return 1;
76       a = oa_new(o, buf[0], buf+1);
77       if (!la || la->attr != a->attr)
78         for(la=o->attrs; la && la->attr != a->attr; la=la->next)
79           ;
80       if (la)
81         {
82           la->last_same->same = a;
83           la->last_same = a;
84         }
85       else
86         {
87           *last = a;
88           last = &a->next;
89           la = a;
90         }
91     }
92   return 0;
93 }
94
95 void
96 obj_write(struct fastbuf *f, struct odes *d)
97 {
98   struct oattr *a, *b;
99   byte *z;
100
101   for(a=d->attrs; a; a=a->next)
102     for(b=a; b; b=b->same)
103       {
104         bputc(f, a->attr);
105         for(z = b->val; *z; z++)
106           if (*z >= ' ' || *z == '\t')
107             bputc(f, *z);
108           else
109             {
110               bputc(f, '?');
111               log(L_ERROR, "obj_dump: Found non-ASCII characters (URL might be %s)", obj_find_aval(d, 'U'));
112             }
113         bputc(f, '\n');
114       }
115 }
116
117 struct oattr *
118 obj_find_attr(struct odes *o, uns x)
119 {
120   struct oattr *a;
121
122   for(a=o->attrs; a && a->attr != x; a=a->next)
123     ;
124   return a;
125 }
126
127 struct oattr *
128 obj_find_attr_last(struct odes *o, uns x)
129 {
130   struct oattr *a = obj_find_attr(o, x);
131
132   return a ? a->last_same : NULL;
133 }
134
135 uns
136 obj_del_attr(struct odes *o, struct oattr *a)
137 {
138   struct oattr *x, **p, *y, *l;
139   byte aa = a->attr;
140
141   p = &o->attrs;
142   while (x = *p)
143     {
144       if (x->attr == aa)
145         {
146           y = x;
147           l = NULL;
148           while (x = *p)
149             {
150               if (x == a)
151                 {
152                   *p = x->same;
153                   if (y->last_same == x)
154                     y->last_same = l;
155                   return 1;
156                 }
157               p = &x->same;
158               l = x;
159             }
160           return 0;
161         }
162       p = &x->next;
163     }
164   return 0;
165 }
166
167 byte *
168 obj_find_aval(struct odes *o, uns x)
169 {
170   struct oattr *a = obj_find_attr(o, x);
171
172   return a ? a->val : NULL;
173 }
174
175 struct oattr *
176 obj_set_attr(struct odes *o, uns x, byte *v)
177 {
178   struct oattr *a, **z;
179
180   z = &o->attrs;
181   while (a = *z)
182     {
183       if (a->attr == x)
184         {
185           *z = a->next;
186           goto set;
187         }
188       z = &a->next;
189     }
190
191  set:
192   if (v)
193     {
194       a = oa_new(o, x, v);
195       a->next = o->attrs;
196       o->attrs = a;
197     }
198   else
199     a = NULL;
200   return a;
201 }
202
203 struct oattr *
204 obj_set_attr_num(struct odes *o, uns a, uns v)
205 {
206   byte x[32];
207
208   sprintf(x, "%d", v);
209   return obj_set_attr(o, a, x);
210 }
211
212 struct oattr *
213 obj_add_attr(struct odes *o, struct oattr *a, uns x, byte *v)
214 {
215   struct oattr *b;
216
217   if (!a)
218     {
219       a = obj_find_attr(o, x);
220       if (!a)
221         return obj_set_attr(o, x, v);
222     }
223   b = oa_new(o, x, v);
224   a->last_same->same = b;
225   a->last_same = b;
226   return a;
227 }
228
229 struct oattr *
230 obj_prepend_attr(struct odes *o, uns x, byte *v)
231 {
232   struct oattr *a, *b, **z;
233
234   b = oa_new(o, x, v);
235   z = &o->attrs;
236   while (a = *z)
237     {
238       if (a->attr == x)
239         {
240           b->same = a;
241           b->next = a->next;
242           a->next = NULL;
243           *z = b;
244           b->last_same = a->last_same;
245           return b;
246         }
247       z = &a->next;
248     }
249   b->next = o->attrs;
250   o->attrs = b;
251   return b;
252 }
253
254 struct oattr *
255 obj_insert_attr(struct odes *o, struct oattr *first, struct oattr *after, byte *v)
256 {
257   struct oattr *b;
258
259   b = oa_new(o, first->attr, v);
260   b->same = after->same;
261   after->same = b;
262   if (first->last_same == after)
263     first->last_same = b;
264   return b;
265 }