]> mj.ucw.cz Git - libucw.git/blob - lib/object.c
dd7b43cf368f3ba45093d22cf45e8256bf771f15
[libucw.git] / lib / object.c
1 /*
2  *      Sherlock Library -- Object Functions
3  *
4  *      (c) 1997--2003 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->attr = x;
36   strcpy(a->val, v);
37   return a;
38 }
39
40 struct odes *
41 obj_new(struct mempool *pool)
42 {
43   struct mempool *lp = pool;
44   struct odes *o;
45
46   if (!lp)
47     lp = mp_new(OBJ_POOL_SIZE);
48   o = mp_alloc(lp, sizeof(struct odes));
49   o->pool = lp;
50   o->local_pool = (pool == lp) ? NULL : lp;
51   o->attrs = NULL;
52   o->cached_attr = 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[1024];
67
68   while (bgets(f, buf, sizeof(buf)))
69     {
70       if (!buf[0])
71         return 1;
72       obj_add_attr(o, buf[0], buf+1);
73     }
74   return 0;
75 }
76
77 void
78 obj_write(struct fastbuf *f, struct odes *d)
79 {
80   struct oattr *a, *b;
81   byte *z;
82
83   for(a=d->attrs; a; a=a->next)
84     for(b=a; b; b=b->same)
85       {
86         bputc(f, a->attr);
87         for(z = b->val; *z; z++)
88           if (*z >= ' ' || *z == '\t')
89             bputc(f, *z);
90           else
91             {
92               bputc(f, '?');
93               log(L_ERROR, "obj_dump: Found non-ASCII characters (URL might be %s)", obj_find_aval(d, 'U'));
94             }
95         bputc(f, '\n');
96       }
97 }
98
99 struct oattr *
100 obj_find_attr(struct odes *o, uns x)
101 {
102   struct oattr *a;
103
104   for(a=o->attrs; a && a->attr != x; a=a->next)
105     ;
106   return a;
107 }
108
109 struct oattr *
110 obj_find_attr_last(struct odes *o, uns x)
111 {
112   struct oattr *a = obj_find_attr(o, x);
113
114   if (a)
115     {
116       while (a->same)
117         a = a->same;
118     }
119   return a;
120 }
121
122 uns
123 obj_del_attr(struct odes *o, struct oattr *a)
124 {
125   struct oattr *x, **p, *y, *l;
126   byte aa = a->attr;
127
128   o->cached_attr = NULL;
129   p = &o->attrs;
130   while (x = *p)
131     {
132       if (x->attr == aa)
133         {
134           y = x;
135           l = NULL;
136           while (x = *p)
137             {
138               if (x == a)
139                 {
140                   *p = x->same;
141                   return 1;
142                 }
143               p = &x->same;
144               l = x;
145             }
146           return 0;
147         }
148       p = &x->next;
149     }
150   return 0;
151 }
152
153 byte *
154 obj_find_aval(struct odes *o, uns x)
155 {
156   struct oattr *a = obj_find_attr(o, x);
157
158   return a ? a->val : NULL;
159 }
160
161 struct oattr *
162 obj_set_attr(struct odes *o, uns x, byte *v)
163 {
164   struct oattr *a, **z;
165
166   z = &o->attrs;
167   while (a = *z)
168     {
169       if (a->attr == x)
170         {
171           *z = a->next;
172           goto set;
173         }
174       z = &a->next;
175     }
176
177  set:
178   if (v)
179     {
180       a = oa_new(o, x, v);
181       a->next = o->attrs;
182       o->attrs = a;
183     }
184   else
185     a = NULL;
186   o->cached_attr = a;
187   return a;
188 }
189
190 struct oattr *
191 obj_set_attr_num(struct odes *o, uns a, uns v)
192 {
193   byte x[32];
194
195   sprintf(x, "%d", v);
196   return obj_set_attr(o, a, x);
197 }
198
199 struct oattr *
200 obj_add_attr(struct odes *o, uns x, byte *v)
201 {
202   struct oattr *a, *b;
203
204   b = oa_new(o, x, v);
205   if (!(a = o->cached_attr) || a->attr != x)
206     {
207       if (!(a = obj_find_attr(o, x)))
208         {
209           b->next = o->attrs;
210           o->attrs = b;
211           goto done;
212         }
213     }
214   while (a->same)
215     a = a->same;
216   a->same = b;
217  done:
218   o->cached_attr = b;
219   return b;
220 }
221
222 struct oattr *
223 obj_prepend_attr(struct odes *o, uns x, byte *v)
224 {
225   struct oattr *a, *b, **z;
226
227   b = oa_new(o, x, v);
228   z = &o->attrs;
229   while (a = *z)
230     {
231       if (a->attr == x)
232         {
233           b->same = a;
234           b->next = a->next;
235           a->next = NULL;
236           *z = b;
237           return b;
238         }
239       z = &a->next;
240     }
241   b->next = o->attrs;
242   o->attrs = b;
243   return b;
244 }
245
246 struct oattr *
247 obj_insert_attr(struct odes *o, struct oattr *first, struct oattr *after, byte *v)
248 {
249   struct oattr *b;
250
251   b = oa_new(o, first->attr, v);
252   b->same = after->same;
253   after->same = b;
254   return b;
255 }