Index: ossp-pkg/sio/al.c RCS File: /v/ossp/cvs/ossp-pkg/sio/Attic/al.c,v rcsdiff -q -kk '-r1.30' '-r1.31' -u '/v/ossp/cvs/ossp-pkg/sio/Attic/al.c,v' 2>/dev/null --- al.c 2002/10/23 13:59:30 1.30 +++ al.c 2002/10/23 16:49:29 1.31 @@ -579,7 +579,7 @@ al_chunk_t *cur; /* argument sanity check(s) */ - if (al == NULL || p == NULL || n < 0) + if (al == NULL || p == NULL || n <= 0) return AL_RC(AL_ERR_ARG); rc = make_buffer(al, p, n, freemem, u, &buf); @@ -874,12 +874,27 @@ tx->view.end = tx->view.begin + step; switch (tx->dir) { + case AL_FORWARD: + case AL_BACKWARD: + break; + case AL_FORWARD_SPAN: + case AL_BACKWARD_SPAN: + if (!AL_SAME_LABEL(&tx->view, tx->label)) { + tx->togo = 0; + return AL_ERR_EOF; + } + break; + } + + switch (tx->dir) { case AL_FORWARD: + case AL_FORWARD_SPAN: tx->cur = NEXT(tx->cur,chunks); tx->togo -= step; tx->skip = 0; break; case AL_BACKWARD: + case AL_BACKWARD_SPAN: tx->cur = PREV(tx->cur,chunks); tx->togo -= step; tx->skip = 0; @@ -948,7 +963,7 @@ * traversal context is kept on stack (XXX ?) */ al_rc_t -al_flatten(al_t *al, size_t off, size_t n, al_label_t label, +al_flatten(al_t *al, size_t off, size_t n, al_td_t dir, al_label_t label, char *dst, size_t *lenp) { al_rc_t rc; @@ -958,20 +973,42 @@ *lenp = 0; /* keep caller on safe side */ - rc = al_traverse(al, off, n, AL_FORWARD, label, &tx); + rc = al_traverse(al, off, n, dir, label, &tx); if (rc != AL_OK) return AL_RC(rc); + switch (dir) { + case AL_FORWARD: + case AL_FORWARD_SPAN: + break; + case AL_BACKWARD: + case AL_BACKWARD_SPAN: + dst += n; + break; + } + total = 0; - while ((rc = al_traverse_next(al, &tx, &view)) == AL_OK) { - step = AL_CHUNK_LEN(view); - if (dst != NULL) { - memmove(dst, AL_CHUNK_PTR(view, 0), step); - dst += step; + if (dst == NULL) { + while ((rc = al_traverse_next(al, &tx, &view)) == AL_OK) + total += AL_CHUNK_LEN(view); + } else { + while ((rc = al_traverse_next(al, &tx, &view)) == AL_OK) { + step = AL_CHUNK_LEN(view); + switch (dir) { + case AL_FORWARD: + case AL_FORWARD_SPAN: + memmove(dst, AL_CHUNK_PTR(view, 0), step); + dst += step; + break; + case AL_BACKWARD: + case AL_BACKWARD_SPAN: + dst -= step; + memmove(dst, AL_CHUNK_PTR(view, 0), step); + break; + } + total += step; } - - total += step; } *lenp = total; @@ -1014,6 +1051,31 @@ } /* + * traverse assembly line and retrieve first chunk + * + * traversal context is kept on stack (XXX ?) + */ +al_rc_t +al_firstlabel(al_t *al, size_t off, size_t n, al_td_t dir, al_label_t label, + al_label_t *labelp) +{ + 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, label, &tx); + if (rc != AL_OK) + return AL_RC(rc); + + if ((rc = al_traverse_next(al, &tx, &view)) == AL_OK) + *labelp = AL_CHUNK_LABEL(view); + + al_traverse_end(al, &tx, 1); + + return rc; +} + +/* * relay macros to caller * * al_bytes - total number of bytes in assembly line Index: ossp-pkg/sio/al.h RCS File: /v/ossp/cvs/ossp-pkg/sio/Attic/al.h,v rcsdiff -q -kk '-r1.13' '-r1.14' -u '/v/ossp/cvs/ossp-pkg/sio/Attic/al.h,v' 2>/dev/null --- al.h 2002/10/22 15:33:16 1.13 +++ al.h 2002/10/23 16:49:29 1.14 @@ -50,7 +50,9 @@ typedef enum { AL_FORWARD, - AL_BACKWARD + AL_BACKWARD, + AL_FORWARD_SPAN, + AL_BACKWARD_SPAN } al_td_t; struct al_tx_st; @@ -69,7 +71,8 @@ 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, al_label_t label, char *dst, size_t *lenp); +al_rc_t al_flatten (al_t *al, size_t off, size_t n, al_td_t dir, al_label_t label, char *dst, size_t *lenp); +al_rc_t al_firstlabel (al_t *al, size_t off, size_t n, al_td_t dir, al_label_t label, al_label_t *labelp); size_t al_bytes (const al_t *al); size_t al_chunk_len (al_chunk_t *alc); Index: ossp-pkg/sio/al.pod RCS File: /v/ossp/cvs/ossp-pkg/sio/Attic/al.pod,v rcsdiff -q -kk '-r1.11' '-r1.12' -u '/v/ossp/cvs/ossp-pkg/sio/Attic/al.pod,v' 2>/dev/null --- al.pod 2002/10/22 15:33:16 1.11 +++ al.pod 2002/10/23 16:49:29 1.12 @@ -122,6 +122,14 @@ This is an opaque data type representing a data buffer. Only pointers to this abstract data type are used in the API. +=item B (Label Type) + +This is an opaque 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. You may use +NULL as a label but on traversal NULL matches any label. + =item B (Traversal Context Type) This is an opaque data type representing the state of a buffer @@ -133,8 +141,10 @@ This is an exported enumerated integer type with the following possible values: - AL_FORWARD traverse assembly line from beginning to end - AL_BACKWARD traverse assembly line from end to beginning + AL_FORWARD traverse assembly line from beginning to end + AL_BACKWARD traverse assembly line from end to beginning + AL_FORWARD_SPAN like AL_FORWARD, but stop when label does not match + AL_BACKWARD_SPAN like AL_BACKWARD, but stop when label does not match =item B (Chunk Type) @@ -143,14 +153,6 @@ used in the API. The B type is used to generate a pointer and byte count to access the data in the buffer. -=item B (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. You may use -NULL as a label but on traversal NULL matches any label. - =back =head1 FUNCTIONS @@ -335,7 +337,7 @@ =over 4 -=item al_rc_t B(al_t *I, size_t I, size_t I, char *I, size_t *I); +=item al_rc_t B(al_t *I, size_t I, size_t I, al_td_t I, char *I, size_t *I); I and I are byte counts that define a span of bytes with the assembly line I. These bytes are copied to the storage array I @@ -348,6 +350,8 @@ still counted in I. This can be used to precalculate the size of the needed storage array by passing an arbitrary high maximum size as I. +If I denotes a backwards traversal the storage array is filled +from its end. Example: @@ -355,7 +359,7 @@ char buffer[42]; size_t actual; - al_flatten(al, 500, 42, buffer, &actual); + al_flatten(al, 500, 42, AL_FORWARD, buffer, &actual); =item al_rc_t B(al_t *I, size_t I, size_t I, al_t *I); Index: ossp-pkg/sio/al_test.c RCS File: /v/ossp/cvs/ossp-pkg/sio/Attic/al_test.c,v rcsdiff -q -kk '-r1.14' '-r1.15' -u '/v/ossp/cvs/ossp-pkg/sio/Attic/al_test.c,v' 2>/dev/null --- al_test.c 2002/10/22 15:33:16 1.14 +++ al_test.c 2002/10/23 16:49:29 1.15 @@ -104,7 +104,7 @@ buf = (char *)malloc(n); if (buf == NULL) abort(); - al_flatten(al, 0, n, LABEL, buf, &len); + al_flatten(al, 0, n, AL_FORWARD, LABEL, buf, &len); printf("%s = %d of %d\n",tag,len,n); fwrite(">>", 2, 1, stdout);