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