OSSP CVS Repository

ossp - Difference in ossp-pkg/sio/al.c versions 1.28 and 1.29
Not logged in
[Honeypot]  [Browse]  [Home]  [Login]  [Reports
[Search]  [Ticket]  [Timeline
  [History

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)
 {

CVSTrac 2.0.1