/*
* Sherlock Library -- Object Functions
*
- * (c) 1997--2003 Martin Mares <mj@ucw.cz>
+ * (c) 1997--2004 Martin Mares <mj@ucw.cz>
*
* This software may be freely distributed and used according to the terms
* of the GNU Lesser General Public License.
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->attr = x;
+ a->val = (byte*) (a+1);
strcpy(a->val, v);
return a;
}
+static struct oattr *
+oa_new_ref(struct odes *o, uns x, byte *v)
+{
+ struct oattr *a = mp_alloc(o->pool, sizeof(struct oattr));
+
+ a->next = a->same = NULL;
+ a->attr = x;
+ a->val = v;
+ return a;
+}
+
struct odes *
obj_new(struct mempool *pool)
{
return 0;
}
+void
+obj_read_multi(struct fastbuf *f, struct odes *o)
+{
+ /* Read a multi-part object ending with either EOF or a NUL character */
+ byte buf[MAX_ATTR_SIZE];
+ while (bpeekc(f) > 0 && bgets(f, buf, sizeof(buf)))
+ if (buf[0])
+ obj_add_attr(o, buf[0], buf+1);
+}
+
void
obj_write(struct fastbuf *f, struct odes *d)
{
obj_find_aval(struct odes *o, uns x)
{
struct oattr *a = obj_find_attr(o, x);
-
return a ? a->val : NULL;
}
return obj_set_attr(o, a, x);
}
-struct oattr *
-obj_add_attr(struct odes *o, uns x, byte *v)
+static inline struct oattr *
+obj_add_attr_internal(struct odes *o, struct oattr *b)
{
- struct oattr *a, *b;
+ struct oattr *a;
- b = oa_new(o, x, v);
- if (!(a = o->cached_attr) || a->attr != x)
+ if (!(a = o->cached_attr) || a->attr != b->attr)
{
- if (!(a = obj_find_attr(o, x)))
+ if (!(a = obj_find_attr(o, b->attr)))
{
b->next = o->attrs;
o->attrs = 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 *
obj_prepend_attr(struct odes *o, uns x, byte *v)
{
after->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;
+ }
+}