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