OSSP CVS Repository

ossp - Check-in [2649]
Not logged in
[Honeypot]  [Browse]  [Home]  [Login]  [Reports
[Search]  [Ticket]  [Timeline
  [Patchset]  [Tagging/Branching

Check-in Number: 2649
Date: 2002-Oct-22 17:33:16 (local)
2002-Oct-22 15:33:16 (UTC)
User:mlelstv
Branch:
Comment: significant API change. now support data labels.

PR: Submitted by: Reviewed by: Approved by: Obtained from:

Tickets:
Inspections:
Files:
ossp-pkg/sio/al.c      1.28 -> 1.29     102 inserted, 61 deleted
ossp-pkg/sio/al.h      1.12 -> 1.13     16 inserted, 12 deleted
ossp-pkg/sio/al.pod      1.10 -> 1.11     44 inserted, 18 deleted
ossp-pkg/sio/al_test.c      1.13 -> 1.14     21 inserted, 13 deleted

ossp-pkg/sio/al.c 1.28 -> 1.29

--- al.c 2002/10/22 15:09:44     1.28
+++ al.c 2002/10/22 15:33:16     1.29
@@ -76,6 +76,7 @@
     al_buffer_t      *buf;             /* (non-exlusively) referenced buffer object */
     size_t            begin;           /* offset into buf->mem where data starts */
     size_t            end;             /* offset into buf->mem where data ends */
+    al_label_t        label;           /* tag data with a label, chunks with distinct labels are not coalesced */
 };
 
 struct al_buffer_st {
@@ -91,6 +92,7 @@
     al_chunk_t       *cur;             /* current chunk during traveral steps */
     size_t            skip;            /* number of bytes to skip for traversal */
     size_t            togo;            /* number of bytes left for traversal */
+    al_label_t        label;           /* label filter or NULL */
     al_chunk_t        view;            /* synthetic chunk for returning during traversal steps */
 };
 
@@ -107,14 +109,22 @@
     ((n) > (AL_CHUNK_LEN(alc) - (off)) ? \
     (AL_CHUNK_LEN(alc) - (off)) : (n))
 
+/* return chunk label */
+#define AL_CHUNK_LABEL(alc) \
+    ((alc)->label)
+
+/* check wether labels match */
+#define AL_SAME_LABEL(alc,label) \
+    ((label) == NULL || AL_CHUNK_LABEL(alc) == (label))
+
 /*
  * number of bytes a chunk can be grown to the end
  * we must not grow a chunk in a shared buffer since
  * we do not track other chunks sharing the buffer
  */
-#define AL_CHUNK_RESERVE(alc) \
+#define AL_CHUNK_RESERVE(alc,label) \
     (  (alc) != NULL \
-     ? (  (alc)->buf->usecount > 1 \
+     ? (  (alc)->buf->usecount > 1 || !AL_SAME_LABEL(alc,label) \
         ? 0 \
         : (alc)->buf->size - (alc)->end) \
      : 0)
@@ -128,9 +138,9 @@
  * we must not grow a chunk in a shared buffer since
  * we do not track other chunks sharing the buffer
  */
-#define AL_CHUNK_PRESERVE(alc) \
+#define AL_CHUNK_PRESERVE(alc,label) \
     ( (alc) != NULL \
-     ? (  (alc)->buf->usecount > 1 \
+     ? (  (alc)->buf->usecount > 1 || !AL_SAME_LABEL(alc,label) \
         ? 0 \
         : (alc)->begin) \
      : 0)
@@ -230,7 +240,7 @@
 static int alc_freecount = 0;
 
 static al_rc_t
-new_chunk(al_t *al, al_buffer_t *buf, al_chunk_t **alcp)
+new_chunk(al_t *al, al_buffer_t *buf, al_label_t label, al_chunk_t **alcp)
 {
     al_chunk_t *alc;
 
@@ -254,6 +264,7 @@
     alc->buf   = buf;
     alc->begin = 0;
     alc->end   = 0;
+    alc->label = label;
 
     buf->usecount++;
 
@@ -271,7 +282,7 @@
     if (off < 0 || off > len)
         return AL_ERR_ARG;
 
-    rc = new_chunk(al, orig->buf, &alc);
+    rc = new_chunk(al, orig->buf, orig->label, &alc);
     if (rc != AL_OK)
         return rc;
 
@@ -290,6 +301,7 @@
     if (alc->buf->usecount == 0)
         dispose_buffer(al,alc->buf);
     alc->buf = NULL;
+    alc->label = NULL;
 
     /* stop freelist from growing infinitely */
     if (alc_freecount >= al->m.max_freechunks)
@@ -369,8 +381,9 @@
     printf("AL: %p\n", al);
     total = 0;
     FOREACH(al,chunks,cur) {
-        printf(" C: %p (%d @ %p + %d < %d (use=%d))\n",
+        printf(" C: %p [%p] (%d @ %p + %d < %d (use=%d))\n",
             cur,
+            cur->label,
             cur->buf->size,cur->buf->mem,
             cur->begin,cur->end,
             cur->buf->usecount);
@@ -451,7 +464,7 @@
  * but leaves data structure consistent
  */
 al_rc_t
-al_append_bytes(al_t *al, const char *src, size_t n)
+al_append_bytes(al_t *al, const char *src, size_t n, al_label_t label)
 {
     al_rc_t rc;
     al_chunk_t *cur;
@@ -464,17 +477,17 @@
         return AL_RC(AL_ERR_ARG);
 
     cur = TAIL(al,chunks);
-    res = AL_CHUNK_RESERVE(cur);
+    res = AL_CHUNK_RESERVE(cur,label);
 
     while (n > 0) {
         if (res == 0) {
             rc = new_buffer(al, &buf);
             if (rc != AL_OK)
                 return AL_RC(rc);
-            rc = new_chunk(al,buf,&cur);
+            rc = new_chunk(al,buf,label,&cur);
             if (rc != AL_OK)
                 return AL_RC(rc);
-            res = AL_CHUNK_RESERVE(cur);
+            res = AL_CHUNK_RESERVE(cur,label);
             ADDTAIL(al, chunks, cur);
         }
         step = n;
@@ -487,7 +500,7 @@
         src += step;
         AL_RESIZE(al, cur, step);
         n   -= step;
-        res = AL_CHUNK_RESERVE(cur);
+        res = AL_CHUNK_RESERVE(cur,label);
     }
 
     return AL_OK;
@@ -500,7 +513,7 @@
  * but leaves data structure consistent
  */
 al_rc_t
-al_prepend_bytes(al_t *al, const char *src, size_t n)
+al_prepend_bytes(al_t *al, const char *src, size_t n, al_label_t label)
 {
     al_rc_t rc;
     al_chunk_t *cur;
@@ -513,7 +526,7 @@
         return AL_RC(AL_ERR_ARG);
 
     cur = HEAD(al,chunks);
-    res = AL_CHUNK_PRESERVE(cur);
+    res = AL_CHUNK_PRESERVE(cur,label);
 
     src += n;
 
@@ -522,10 +535,10 @@
             rc = new_buffer(al, &buf);
             if (rc != AL_OK)
                 return AL_RC(rc);
-            rc = new_chunk(al,buf,&cur);
+            rc = new_chunk(al,buf,label,&cur);
             if (rc != AL_OK)
                 return AL_RC(rc);
-            res = AL_CHUNK_PRESERVE(cur);
+            res = AL_CHUNK_PRESERVE(cur,label);
             ADDHEAD(al, chunks, cur);
         }
         step = n;
@@ -535,7 +548,7 @@
         src -= step;
         AL_PRESIZE(al, cur, step);
         n   -= step;
-        res = AL_CHUNK_PRESERVE(cur);
+        res = AL_CHUNK_PRESERVE(cur,label);
 
         dst = AL_CHUNK_PTR(cur, 0);
         memcpy(dst, src, step);
@@ -552,7 +565,8 @@
  * XXX - some list operations modify the buffer
  *
  */
-al_rc_t al_attach_buffer(al_t *al, char *p, size_t n, void (*freemem)(char *, size_t, void *), void *u)
+al_rc_t al_attach_buffer(al_t *al, char *p, size_t n, al_label_t label,
+                         void (*freemem)(char *, size_t, void *), void *u)
 {
     al_rc_t rc;
     al_buffer_t *buf;
@@ -565,7 +579,7 @@
     rc = make_buffer(al, p, n, freemem, u, &buf);
     if (rc != AL_OK)
         return AL_RC(rc);
-    rc = new_chunk(al,buf, &cur);
+    rc = new_chunk(al,buf,label,&cur);
     if (rc != AL_OK)
         return AL_RC(rc);
     ADDTAIL(al, chunks, cur);
@@ -672,7 +686,8 @@
                  */
                 size_t before = tal->bytes;
 
-                rc = al_append_bytes(tal, AL_CHUNK_PTR(cur, skip), step);
+                rc = al_append_bytes(tal, AL_CHUNK_PTR(cur, skip),
+                                     step, AL_CHUNK_LABEL(cur));
                 if (rc != AL_OK)
                     /* correct step size to actual size */
                     step = tal->bytes - before;
@@ -802,7 +817,7 @@
  * - save traversal parameters
  */
 al_rc_t
-al_traverse(al_t *al, size_t off, size_t n, al_td_t dir, al_tx_t *tx)
+al_traverse(al_t *al, size_t off, size_t n, al_td_t dir, al_label_t label, al_tx_t *tx)
 {
     al_rc_t rc;
 
@@ -812,8 +827,9 @@
     if (rc != AL_OK)
         return AL_RC(rc);
 
-    tx->dir  = dir;
-    tx->togo = n;
+    tx->dir   = dir;
+    tx->togo  = n;
+    tx->label = label;
 
     return AL_OK;
 }
@@ -830,38 +846,40 @@
 {
     size_t step;
 
-    if (tx->togo <= 0)     /* XXX - togo can be negative from bad input */
-        return AL_ERR_EOF;
+    do {
+        if (tx->togo <= 0)     /* XXX - togo can be negative from bad input */
+            return AL_ERR_EOF;
 
-    if (tx->cur == NULL)   /* premature EOF */
-        return AL_ERR_EOF;
+        if (tx->cur == NULL)   /* premature EOF */
+            return AL_ERR_EOF;
 
-    /* compute number of bytes to process */
-    step = AL_CHUNK_SPAN(tx->cur, tx->skip, tx->togo);
+        /* compute number of bytes to process */
+        step = AL_CHUNK_SPAN(tx->cur, tx->skip, tx->togo);
 
-    /*
-     * synthetic chunk which is NOT maintained in usecount
-     * MUST NOT BE USED for modifications to chunk list
-     * MUST NOT BE USED for modifications to chunk size
-     * ALLOWED is read access to chunk content
-     * ALLOWED is modification in place of chunk content
-     */
-    tx->view        = *(tx->cur);
-    tx->view.begin += tx->skip;
-    tx->view.end    = tx->view.begin + step;
-
-    switch (tx->dir) {
-        case AL_FORWARD:
-            tx->cur   = NEXT(tx->cur,chunks);
-            tx->togo -= step;
-            tx->skip  = 0;
-            break;
-        case AL_BACKWARD:
-            tx->cur   = PREV(tx->cur,chunks);
-            tx->togo -= step;
-            tx->skip  = 0;
-            break;
-    }
+        /*
+         * synthetic chunk which is NOT maintained in usecount
+         * MUST NOT BE USED for modifications to chunk list
+         * MUST NOT BE USED for modifications to chunk size
+         * ALLOWED is read access to chunk content
+         * ALLOWED is modification in place of chunk content
+         */
+        tx->view        = *(tx->cur);
+        tx->view.begin += tx->skip;
+        tx->view.end    = tx->view.begin + step;
+
+        switch (tx->dir) {
+            case AL_FORWARD:
+                tx->cur   = NEXT(tx->cur,chunks);
+                tx->togo -= step;
+                tx->skip  = 0;
+                break;
+            case AL_BACKWARD:
+                tx->cur   = PREV(tx->cur,chunks);
+                tx->togo -= step;
+                tx->skip  = 0;
+                break;
+        }
+    } while (!AL_SAME_LABEL(&tx->view, tx->label));
 
     *alcp = &tx->view;
     return AL_OK;
@@ -887,14 +905,14 @@
  * traversal context is kept on stack (XXX ?)
  */
 al_rc_t
-al_traverse_cb(al_t *al, size_t off, size_t n, al_td_t dir,
+al_traverse_cb(al_t *al, size_t off, size_t n, al_td_t dir, al_label_t label,
                al_rc_t (*cb)(al_chunk_t *, void *), void *u)
 {
     al_rc_t rc;
     al_tx_t tx;                /* XXX - private tx structure on stack */
     al_chunk_t *view;
 
-    rc = al_traverse(al, off, n, dir, &tx);
+    rc = al_traverse(al, off, n, dir, label, &tx);
     if (rc != AL_OK)
         return AL_RC(rc);
 
@@ -917,10 +935,15 @@
  *
  * returns actual number of bytes copied
  *
+ * Do not copy if destination pointer is NULL, but still count.
+ * This can be used to precalculate the size of the needed linear
+ * buffer with n set to some arbitrary huge value.
+ *
  * traversal context is kept on stack (XXX ?)
  */
 al_rc_t
-al_flatten(al_t *al, size_t off, size_t n, char *dst, size_t *lenp)
+al_flatten(al_t *al, size_t off, size_t n, al_label_t label,
+           char *dst, size_t *lenp)
 {
     al_rc_t rc;
     al_tx_t tx;                /* XXX - private tx structure on stack */
@@ -929,15 +952,19 @@
 
     *lenp = 0; /* keep caller on safe side */
 
-    rc = al_traverse(al, off, n, AL_FORWARD, &tx);
+    rc = al_traverse(al, off, n, AL_FORWARD, label, &tx);
     if (rc != AL_OK)
         return AL_RC(rc);
 
     total = 0;
     while ((rc = al_traverse_next(al, &tx, &view)) == AL_OK) {
         step = AL_CHUNK_LEN(view);
-        memmove(dst, AL_CHUNK_PTR(view, 0), step);
-        dst   += step;
+
+        if (dst != NULL) {
+            memmove(dst, AL_CHUNK_PTR(view, 0), step);
+            dst   += step;
+        }
+
         total += step;
     }
     *lenp = total;
@@ -956,20 +983,20 @@
  * traversal context is kept on stack (XXX ?)
  */
 al_rc_t
-al_copy(al_t *al, size_t off, size_t n, al_t *tal)
+al_copy(al_t *al, size_t off, size_t n, al_label_t label, al_t *tal)
 {
     al_rc_t rc;
     al_tx_t tx;                /* XXX - private tx structure on stack */
     al_chunk_t *view;
     size_t step;
 
-    rc = al_traverse(al, off, n, AL_FORWARD, &tx);
+    rc = al_traverse(al, off, n, AL_FORWARD, label, &tx);
     if (rc != AL_OK)
         return AL_RC(rc);
 
     while ((rc = al_traverse_next(al, &tx, &view)) == AL_OK) {
         step = AL_CHUNK_LEN(view);
-        al_append_bytes(tal, AL_CHUNK_PTR(view, 0), step);
+        al_append_bytes(tal, AL_CHUNK_PTR(view, 0), step, AL_CHUNK_LABEL(view));
     }
 
     al_traverse_end(al, &tx, 1);
@@ -986,6 +1013,8 @@
  * al_bytes      - total number of bytes in assembly line
  * al_chunk_len  - number of bytes in chunk
  * al_chunk_span - clip interval (off,off+n( against chunk length
+ * al_chunk_label- return chunk label
+ * al_same_label - check if label matches with chunk label
  * al_chunk_ptr  - return memory pointer to byte within chunk
  *
  * off must be a valid offset within (0,len(
@@ -1009,6 +1038,18 @@
     return AL_CHUNK_SPAN(alc, off, n);
 }
 
+al_label_t
+al_chunk_label(al_chunk_t *alc)
+{
+    return AL_CHUNK_LABEL(alc);
+}
+
+int
+al_same_label(al_chunk_t *alc, al_label_t label)
+{
+    return AL_SAME_LABEL(alc, label);
+}
+
 char *
 al_chunk_ptr(al_chunk_t *alc, size_t off)
 {


ossp-pkg/sio/al.h 1.12 -> 1.13

--- al.h 2002/10/18 12:24:53     1.12
+++ al.h 2002/10/22 15:33:16     1.13
@@ -46,6 +46,8 @@
 struct al_chunk_st;
 typedef struct al_chunk_st al_chunk_t;
 
+typedef void *al_label_t;
+
 typedef enum {
     AL_FORWARD,
     AL_BACKWARD
@@ -56,25 +58,27 @@
 
 al_rc_t al_create       (al_t **alp);
 al_rc_t al_destroy      (al_t *al);
-al_rc_t al_append_bytes (al_t *al, const char *src, size_t n);
-al_rc_t al_prepend_bytes(al_t *al, const char *src, size_t n);
-al_rc_t al_attach_buffer(al_t *al, char *p, size_t n, void (*freemem)(char *, size_t, void *), void *u);
+al_rc_t al_append_bytes (al_t *al, const char *src, size_t n, al_label_t label);
+al_rc_t al_prepend_bytes(al_t *al, const char *src, size_t n, al_label_t label);
+al_rc_t al_attach_buffer(al_t *al, char *p, size_t n, al_label_t label, void (*freemem)(char *, size_t, void *), void *u);
 al_rc_t al_txalloc      (al_t *al, al_tx_t **txp);
 al_rc_t al_txfree       (al_t *al, al_tx_t *tx);
-al_rc_t al_traverse     (al_t *al, size_t off, size_t n, al_td_t dir, al_tx_t *tx);
+al_rc_t al_traverse     (al_t *al, size_t off, size_t n, al_td_t dir, al_label_t label, al_tx_t *tx);
 al_rc_t al_traverse_next(al_t *al, al_tx_t *tx, al_chunk_t **alcp);
 al_rc_t al_traverse_end (al_t *al, al_tx_t *tx, int final);
-al_rc_t al_traverse_cb  (al_t *al, size_t off, size_t n, al_td_t dir, al_rc_t (*cb)(al_chunk_t *, void *), void *u);
-al_rc_t al_copy         (al_t *al, size_t off, size_t n, al_t *tal);
+al_rc_t al_traverse_cb  (al_t *al, size_t off, size_t n, al_td_t dir, al_label_t, al_rc_t (*cb)(al_chunk_t *, void *), void *u);
+al_rc_t al_copy         (al_t *al, size_t off, size_t n, al_label_t label, al_t *tal);
 al_rc_t al_splice       (al_t *al, size_t off, size_t n, al_t *nal, al_t *tal);
-al_rc_t al_flatten      (al_t *al, size_t off, size_t n, char *dst, size_t *lenp);
+al_rc_t al_flatten      (al_t *al, size_t off, size_t n, al_label_t label, char *dst, size_t *lenp);
 
-size_t al_bytes     (const al_t *al);
-size_t al_chunk_len (al_chunk_t *alc);
-size_t al_chunk_span(al_chunk_t *alc, size_t off, size_t n);
-char  *al_chunk_ptr (al_chunk_t *alc, size_t off);
+size_t     al_bytes      (const al_t *al);
+size_t     al_chunk_len  (al_chunk_t *alc);
+al_label_t al_chunk_label(al_chunk_t *alc);
+int        al_same_label (al_chunk_t *alc, al_label_t label);
+size_t     al_chunk_span (al_chunk_t *alc, size_t off, size_t n);
+char      *al_chunk_ptr  (al_chunk_t *alc, size_t off);
 
-const char *al_error(al_rc_t rc);
+const char *al_error      (al_rc_t rc);
 
 #endif /* __AL_H__ */
 


ossp-pkg/sio/al.pod 1.10 -> 1.11

--- al.pod       2002/10/18 12:23:35     1.10
+++ al.pod       2002/10/22 15:33:16     1.11
@@ -79,6 +79,8 @@
 
 al_chunk_len,
 al_chunk_span,
+al_chunk_label,
+al_same_label,
 al_chunk_ptr.
 
 =item B<Error Handling>:
@@ -100,7 +102,7 @@
 
 =head1 DATA TYPES
 
-B<OSSP al> uses five data types in its API:
+B<OSSP al> uses six data types in its API:
 
 =over 4
 
@@ -141,6 +143,14 @@
 used in the API. The B<al_chunk_t> type is used to generate a pointer
 and byte count to access the data in the buffer.
 
+=item B<al_label_t> (Label Type)
+
+This is a pointer type representing a specific data flavour. You
+can restrict traversal operations to data that was marked with
+the specific flavour. Usually you would cast a pointer to the
+object that maintains the data to B<al_label_t>. You may use
+NULL as a label but on traversal NULL matches any label.
+
 =back
 
 =head1 FUNCTIONS
@@ -172,21 +182,22 @@
 
 Example: C<al_destroy(al);>
 
-=item al_rc_t B<al_append_bytes>(al_t *I<al>, const char *I<src>, size_t I<n>);
+=item al_rc_t B<al_append_bytes>(al_t *I<al>, const char *I<src>, size_t I<n>, al_label_t I<label>);
 
 Append I<n> bytes from a storage array at I<src> to the assembly line. The
-bytes are copied, memory is allocated as necessary.
+bytes are copied, memory is allocated as necessary. The data is tagged
+with I<label>.
 
-Example: C<al_append_bytes(al, "Goodbye cruel world\n", 20);>
+Example: C<al_append_bytes(al, "Goodbye cruel world\n", 20, NULL);>
 
-=item al_rc_t B<al_prepend_bytes>(al_t *I<al>, const char *I<src>, size_t I<n>);
+=item al_rc_t B<al_prepend_bytes>(al_t *I<al>, const char *I<src>, size_t I<n>, al_label_t I<label>);
 
 Prepend I<n> bytes from a storage array at I<src> to the assembly line. The
 bytes are copied, memory is allocated as necessary.
 
-Example: C<al_prepend_bytes(al, "Hello world\n", 12);>
+Example: C<al_prepend_bytes(al, "Hello world\n", 12, NULL);>
 
-=item al_rc_t B<al_attach_buffer>(al_t *I<al>, char *I<p>, size_t I<n>, void (*I<freemem>)(char *, size_t, void *), void *I<u>);
+=item al_rc_t B<al_attach_buffer>(al_t *I<al>, char *I<p>, size_t I<n>, al_label_t I<label>, void (*I<freemem>)(char *, size_t, void *), void *I<u>);
 
 Attach the storage array starting at I<p> with size I<n> at the end of
 the assembly line. Its content becomes part of the assembly line
@@ -197,7 +208,7 @@
 for I<freemem> is valid, then no callback takes place, which might be
 appropriate for static buffers.
 
-Example: C<char store[] = "foo\n"; al_attach_buffer(al, store, sizeof(store), NULL, NULL);>
+Example: C<char store[] = "foo\n"; al_attach_buffer(al, store, sizeof(store), NULL, NULL, NULL);>
 
 =item al_rc_t B<al_splice>(al_t *I<al>, size_t I<off>, size_t I<n>, al_t *I<nal>, al_t *I<tal>);
 
@@ -231,8 +242,8 @@
  al_create(&insertion);
  al_create(&buffer);
 
- al_append_bytes(source, "Hello world\n", 12);
- al_append_bytes(insertion, "Goodbye cruel", 13);
+ al_append_bytes(source, "Hello world\n", 12, NULL);
+ al_append_bytes(insertion, "Goodbye cruel", 13, NULL);
 
  al_splice(source, 0, 5, insertion, buffer);
 
@@ -240,16 +251,16 @@
 The source now holds the string "Goodbye cruel world\n".
 The insertion is now empty.
 
- al_append_bytes(insertion, "brave", 5);
+ al_append_bytes(insertion, "brave", 5, NULL);
  al_splice(source, 8, 5, insertion, NULL);
 
 The source now holds the string "Goodbye brave world\n".
 The insertion is now empty.
 
- al_append_bytes(insertion, "B", 1);
+ al_append_bytes(insertion, "B", 1, NULL);
  al_splice(source, 0, 8, NULL, buffer);
  al_splice(source, 0, 1, insertion, NULL);
- al_append_bytes(insertion, "\n", 1);
+ al_append_bytes(insertion, "\n", 1, NULL);
  al_splice(buffer, al_bytes(buffer)-1, 1, insertion, NULL),
 
 The source now holds the string "Brave world\n".
@@ -280,11 +291,12 @@
 
 Example: C<al_tx_t *tx; al_txfree(tx);>
 
-=item al_rc_t B<al_traverse>(al_t *I<al>, size_t I<off>, size_t I<n>, al_td_t I<dir>, al_tx_t *I<tx>);
+=item al_rc_t B<al_traverse>(al_t *I<al>, size_t I<off>, size_t I<n>, al_td_t I<dir>, al_label_t I<label>, al_tx_t *I<tx>);
 
 Start traversing the assembly line I<al> beginning at byte offset I<off>
-for up to I<n> bytes in direction I<dir>. The state of the traversal is
-stored in the supplied context I<tx>.
+for up to I<n> bytes in direction I<dir>. If I<label> is not NULL then
+you will see only data that was tagged with I<label>. The state of the
+traversal is stored in the supplied context I<tx>.
 
 This function fails when the offset is outside the assembly line bounds.
 
@@ -307,7 +319,7 @@
 mandatory that every traversal that was started is finished by
 a call to B<al_traverse_end> with I<final> set to a non-zero value.
 
-=item al_rc_t B<al_traverse_cb>(al_t *I<al>, size_t I<off>, size_t I<n>, al_td_t I<dir>, al_rc_t (*I<cb>)(al_chunk_t *, void *), void *u);
+=item al_rc_t B<al_traverse_cb>(al_t *I<al>, size_t I<off>, size_t I<n>, al_td_t I<dir>, al_label_t I<label>, al_rc_t (*I<cb>)(al_chunk_t *, void *), void *u);
 
 B<al_traverse_cb> is a wrapper function that does a full assembly line traversal in
 a single call. In every step a chunk descriptor is passed to the callback
@@ -332,6 +344,10 @@
 the size of the assembly line.
 The actual number of bytes that is copied to the destination is stored
 in I<lenp>.
+If I<dst> is NULL then no data is copied but the number of bytes is
+still counted in I<lenp>. This can be used to precalculate the size
+of the needed storage array by passing an arbitrary high maximum size
+as I<n>.
 
 Example:
 
@@ -341,7 +357,7 @@
 
  al_flatten(al, 500, 42, buffer, &actual);
 
-=item al_rc_t B<al_copy>(al_t *I<al>, size_t I<off>, size_t I<n>, al_t *I<tal);
+=item al_rc_t B<al_copy>(al_t *I<al>, size_t I<off>, size_t I<n>, al_t *I<tal>);
 
 I<off> and I<n> are byte counts that define a span of bytes within the
 assembly line I<al>. These bytes are appended to the target assembly line I<tal>,
@@ -374,6 +390,16 @@
 I<off> must be a valid offset, I<n> must be positive but may exceed
 the size of the chunk.
 
+=item al_label_t B<al_chunk_label>(al_chunk_t *I<alc>);
+
+Return the label that was used to tag the data in I<alc>. This can
+be NULL.
+
+=item int B<al_same_label>(al_chunk_t *I<alc>, al_label_t *I<label>);
+
+Return true if I<label> matches the label that was used to tag the data
+in I<alc>. A NULL I<label> matches everything.
+
 =item char *B<al_chunk_ptr>(al_chunk_t *I<alc>, size_t I<off>);
 
 Returns the pointer to the byte at offset I<off> within the chunk I<alc>.


ossp-pkg/sio/al_test.c 1.13 -> 1.14

--- al_test.c    2002/10/18 15:53:17     1.13
+++ al_test.c    2002/10/22 15:33:16     1.14
@@ -36,6 +36,11 @@
 
 #include "al.h"
 
+/* get unique pointers */
+static char label, label2;
+#define LABEL  ((al_label_t)&label)
+#define LABEL2 ((al_label_t)&label2)
+
 #define S(s) s, strlen(s)
 
 static const char *fill(char *p, int n)
@@ -65,12 +70,13 @@
     size_t len, pre, post;
 
     len = al_chunk_len(alc);
-    pre  = 20; if (pre > len) pre = len;
-    post = 20; if (post > len-pre) post = len-pre;
+    pre  = 16; if (pre > len) pre = len;
+    post = 16; if (post > len-pre) post = len-pre;
 
-    printf("C: %08lx + %-6d = ",
+    printf("C: %08lx + %-6d [%08lx] = ",
         (long)al_chunk_ptr(alc, 0),
-        al_chunk_len(alc));
+        al_chunk_len(alc),
+        (long)al_chunk_label(alc));
     fputs(fill(al_chunk_ptr(alc,0),pre), stdout);
     if (post > 0) {
         fputs(" .. ", stdout);
@@ -83,7 +89,7 @@
 
 #define DUMP(tag,al) do {\
 printf("+DUMP(%s)\n",tag);\
-al_traverse_cb(al, 0, al_bytes(al), AL_FORWARD, printchunk, NULL);\
+al_traverse_cb(al, 0, al_bytes(al), AL_FORWARD, LABEL, printchunk, NULL);\
 printf("-DUMP(%s)\n\n",tag);\
 } while (0)
 
@@ -92,11 +98,13 @@
     char *buf;
     size_t n, len;
 
+    return;
+
     n = al_bytes(al);
     buf = (char *)malloc(n);
     if (buf == NULL) abort();
 
-    al_flatten(al, 0, n, buf, &len);
+    al_flatten(al, 0, n, LABEL, buf, &len);
 
     printf("%s = %d of %d\n",tag,len,n);
     fwrite(">>", 2, 1, stdout);
@@ -116,7 +124,7 @@
     total = 0;
 
     al_txalloc(al, &tx);
-    al_traverse(al, 0, -1, AL_FORWARD, tx);
+    al_traverse(al, 0, -1, AL_FORWARD, NULL, tx);
     while (al_traverse_next(al, tx, &cur) == AL_OK)
         total += al_chunk_len(cur);
     al_traverse_end(al, tx, 1);
@@ -145,15 +153,15 @@
     al_create(&al2);
     al_create(&al3);
 
-    al_append_bytes(al, S("Hello world\n"));
-    al_attach_buffer(al, S(baf), reclaim, NULL);
+    al_append_bytes(al, S("Hello world\n"), LABEL);
+    al_attach_buffer(al, S(baf), LABEL, reclaim, NULL);
 
     for (i=0; i<500; ++i)
-        al_append_bytes(al, S("Huhu world\n"));
+        al_append_bytes(al, S("Huhu world\n"), LABEL);
 
-    al_append_bytes(al2, S("Hello world\n"));
+    al_append_bytes(al2, S("Hello world\n"), LABEL);
 
-    al_append_bytes(al3, S("HUHU WORLD\n"));
+    al_append_bytes(al3, S("HUHU WORLD\n"), LABEL2);
 
     DUMP("DATA",al);
     DUMP("BUFFER",al2);
@@ -167,7 +175,7 @@
     checklen("REPLACEMENT",al3);
 
     al_create(&al4);
-    rc = al_copy(al, al_bytes(al)-42, 38, al4);
+    rc = al_copy(al, al_bytes(al)-42, 38, LABEL, al4);
     printf("copy result: %d (%s)\n\n",rc,al_error(rc));
 
     DUMP("SPLICED",al);

CVSTrac 2.0.1