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