X-Git-Url: http://mj.ucw.cz/gitweb/?a=blobdiff_plain;ds=sidebyside;f=lib%2Fobject.c;h=6a2a90c5b5d46aeec6c8709be842121bd553f41a;hb=aac897f2337471637d9a47b38e1b7b35ab0359b5;hp=1c9cb23fc5a629b6f2f054724b2583ca2a352e0c;hpb=df60793e9f71c2b5f2e1cc0db3011435a3638b77;p=libucw.git diff --git a/lib/object.c b/lib/object.c index 1c9cb23f..6a2a90c5 100644 --- a/lib/object.c +++ b/lib/object.c @@ -1,121 +1,67 @@ /* * Sherlock Library -- Object Functions * - * (c) 1997--2001 Martin Mares + * (c) 1997--2004 Martin Mares + * (c) 2004 Robert Spalek + * + * This software may be freely distributed and used according to the terms + * of the GNU Lesser General Public License. */ #include "lib/lib.h" -#include "lib/pools.h" +#include "lib/mempool.h" #include "lib/fastbuf.h" +#include "lib/object.h" #include #include - -#define OBJ_POOL_SIZE 4096 +#include void obj_dump(struct odes *o) { - struct oattr *a, *b; - - for(a=o->attrs; a; a=a->next) - for(b=a; b; b=b->same) + for(struct oattr *a=o->attrs; a; a=a->next) + for(struct oattr *b=a; b; b=b->same) printf("%c%s\n", (a==b ? a->attr : ' '), b->val); } static struct oattr * oa_new(struct odes *o, uns x, byte *v) { - struct oattr *a = mp_alloc(o->pool, sizeof(struct oattr) + strlen(v)); + struct oattr *a = mp_alloc(o->pool, sizeof(struct oattr) + strlen(v)+1); a->next = a->same = NULL; - a->last_same = a; a->attr = x; + a->val = (byte*) (a+1); strcpy(a->val, v); return a; } -struct odes * -obj_new(struct mempool *pool) -{ - struct mempool *lp = pool; - struct odes *o; - - if (!lp) - lp = mp_new(OBJ_POOL_SIZE); - o = mp_alloc(lp, sizeof(struct odes)); - o->pool = lp; - o->local_pool = (pool == lp) ? NULL : lp; - o->attrs = NULL; - return o; -} - -void -obj_free(struct odes *o) -{ - if (o->local_pool) - mp_delete(o->local_pool); -} - -int -obj_read(struct fastbuf *f, struct odes *o) +static struct oattr * +oa_new_ref(struct odes *o, uns x, byte *v) { - byte buf[1024]; - struct oattr **last = &o->attrs; - struct oattr *a, *la; + struct oattr *a = mp_alloc(o->pool, sizeof(struct oattr)); - la = NULL; - *last = NULL; - while (bgets(f, buf, sizeof(buf))) - { - if (!buf[0]) - return 1; - a = oa_new(o, buf[0], buf+1); - if (!la || la->attr != a->attr) - for(la=o->attrs; la && la->attr != a->attr; la=la->next) - ; - if (la) - { - la->last_same->same = a; - la->last_same = a; - } - else - { - *last = a; - last = &a->next; - la = a; - } - } - return 0; + a->next = a->same = NULL; + a->attr = x; + a->val = v; + return a; } -void -obj_write(struct fastbuf *f, struct odes *d) +struct odes * +obj_new(struct mempool *pool) { - struct oattr *a, *b; - byte *z; - - for(a=d->attrs; a; a=a->next) - for(b=a; b; b=b->same) - { - bputc(f, a->attr); - for(z = b->val; *z; z++) - if (*z >= ' ') - bputc(f, *z); - else - { - bputc(f, '?'); - log(L_ERROR, "obj_dump: Found non-ASCII characters (URL might be %s)", obj_find_aval(d, 'U')); - } - bputc(f, '\n'); - } + struct odes *o = mp_alloc(pool, sizeof(struct odes)); + o->pool = pool; + o->attrs = NULL; + o->cached_attr = NULL; + return o; } struct oattr * obj_find_attr(struct odes *o, uns x) { struct oattr *a; - for(a=o->attrs; a && a->attr != x; a=a->next) ; return a; @@ -126,7 +72,12 @@ obj_find_attr_last(struct odes *o, uns x) { struct oattr *a = obj_find_attr(o, x); - return a ? a->last_same : NULL; + if (a) + { + while (a->same) + a = a->same; + } + return a; } uns @@ -135,6 +86,7 @@ obj_del_attr(struct odes *o, struct oattr *a) struct oattr *x, **p, *y, *l; byte aa = a->attr; + o->cached_attr = NULL; p = &o->attrs; while (x = *p) { @@ -147,8 +99,6 @@ obj_del_attr(struct odes *o, struct oattr *a) if (x == a) { *p = x->same; - if (y->last_same == x) - y->last_same = l; return 1; } p = &x->same; @@ -165,10 +115,16 @@ byte * obj_find_aval(struct odes *o, uns x) { struct oattr *a = obj_find_attr(o, x); - return a ? a->val : NULL; } +uns +obj_find_anum(struct odes *o, uns x, uns def) +{ + struct oattr *a = obj_find_attr(o, x); + return a ? (uns)atol(a->val) : def; +} + struct oattr * obj_set_attr(struct odes *o, uns x, byte *v) { @@ -194,6 +150,7 @@ obj_set_attr(struct odes *o, uns x, byte *v) } else a = NULL; + o->cached_attr = a; return a; } @@ -206,21 +163,41 @@ obj_set_attr_num(struct odes *o, uns a, uns v) return obj_set_attr(o, a, x); } -struct oattr * -obj_add_attr(struct odes *o, struct oattr *a, uns x, byte *v) +static inline struct oattr * +obj_add_attr_internal(struct odes *o, struct oattr *b) { - struct oattr *b; + struct oattr *a, **z; - if (!a) + if (!(a = o->cached_attr) || a->attr != b->attr) { - a = obj_find_attr(o, x); + z = &o->attrs; + while ((a = *z) && a->attr != b->attr) + z = &a->next; if (!a) - return obj_set_attr(o, x, v); + { + *z = b; + /* b->next is NULL */ + goto done; + } } - b = oa_new(o, x, v); - a->last_same->same = b; - a->last_same = b; - return a; + while (a->same) + a = a->same; + a->same = b; + done: + o->cached_attr = b; + return b; +} + +struct oattr * +obj_add_attr(struct odes *o, uns x, byte *v) +{ + return obj_add_attr_internal(o, oa_new(o, x, v)); +} + +struct oattr * +obj_add_attr_ref(struct odes *o, uns x, byte *v) +{ + return obj_add_attr_internal(o, oa_new_ref(o, x, v)); } struct oattr * @@ -238,7 +215,6 @@ obj_prepend_attr(struct odes *o, uns x, byte *v) b->next = a->next; a->next = NULL; *z = b; - b->last_same = a->last_same; return b; } z = &a->next; @@ -251,12 +227,48 @@ obj_prepend_attr(struct odes *o, uns x, byte *v) struct oattr * obj_insert_attr(struct odes *o, struct oattr *first, struct oattr *after, byte *v) { - struct oattr *b; - - b = oa_new(o, first->attr, v); + struct oattr *b = oa_new(o, first->attr, v); b->same = after->same; after->same = b; - if (first->last_same == after) - first->last_same = b; return b; } + +void +obj_move_attr_to_head(struct odes *o, uns x) +{ + struct oattr *a, **z; + + z = &o->attrs; + while (a = *z) + { + if (a->attr == x) + { + *z = a->next; + a->next = o->attrs; + o->attrs = a; + break; + } + z = &a->next; + } +} + +void +obj_move_attr_to_tail(struct odes *o, uns x) +{ + struct oattr *a, **z; + + z = &o->attrs; + while (a = *z) + { + if (a->attr == x) + { + *z = a->next; + while (*z) + z = &(*z)->next; + *z = a; + a->next = NULL; + break; + } + z = &a->next; + } +}