--- al.c 2002/11/19 17:02:17 1.36
+++ al.c 2002/11/28 15:12:40 1.37
@@ -818,6 +818,88 @@
}
/*
+ *
+ */
+al_rc_t
+al_setlabel(al_t *al, size_t off, size_t n, al_label_t label)
+{
+ al_rc_t rc;
+ al_chunk_t *cur, *splitbuf;
+ size_t skip, len;
+
+ /* argument sanity check(s) */
+ if (al == NULL || n < 0)
+ return AL_RC(AL_ERR_ARG);
+
+ /*
+ * seek to beginning, return EOF when seek position does not exist
+ * EOD must be a valid seek position so that we can append data
+ */
+ rc = al_seek(al, off, &cur, &skip);
+ if (rc != AL_OK)
+ return AL_RC(rc);
+
+ /*
+ * seek to EOD, nothing to label
+ */
+ if (cur == NULL)
+ return AL_OK;
+
+ /*
+ * if first chunk doesn't need relabeling
+ * then skip it, adjust seek size
+ *
+ * else if offset is not at chunk start
+ * then split chunk at offset, continue
+ * with second half
+ */
+ if (AL_SAME_LABEL(cur, label)) {
+ len = AL_CHUNK_LEN(cur) - skip;
+ n = n < len ? 0 : n - len;
+ cur = NEXT(cur, chunks);
+ } else if (skip > 0) {
+ rc = split_chunk(al, cur, skip, &splitbuf);
+ if (rc != AL_OK)
+ return AL_RC(rc);
+ INSERT(al,chunks,cur,splitbuf);
+ }
+
+ /*
+ * for all remaining chunks and bytes
+ *
+ * if chunk doesn't need relabeling
+ * then skip it, adjust size
+ *
+ * else if chunk isn't covered in total
+ * then split chunk at end offset and
+ * process first half
+ */
+ while (n > 0 && cur != NULL) {
+ len = AL_CHUNK_LEN(cur);
+ if (AL_SAME_LABEL(cur, label)) {
+ n = n < len ? 0 : n - len;
+ } else {
+ if (n < len) {
+ /*
+ * split last chunk at end offset
+ */
+ rc = split_chunk(al, cur, n, &splitbuf);
+ if (rc != AL_OK)
+ return AL_RC(rc);
+ INSERT(al,chunks,cur,splitbuf);
+ cur = splitbuf;
+ len = AL_CHUNK_LEN(cur);
+ }
+ AL_CHUNK_LABEL(cur) = label;
+ n -= len;
+ }
+ cur = NEXT(cur, chunks);
+ }
+
+ return AL_OK;
+}
+
+/*
* assembly line traversal requires a context. It needs to be
* malloced to keep its inner structure private
*/
|