--- al.c 2002/10/14 12:32:16 1.3
+++ al.c 2002/10/14 13:34:25 1.4
@@ -2,6 +2,8 @@
#include <stdlib.h>
#include <string.h>
+/****************************************************************************/
+
#define LIST(elem) \
struct { elem *head, *tail; }
#define NODE(elem) \
@@ -123,6 +125,8 @@
#define FOREACHR(q,l,n) for (n = TAIL(q,l); n; n = PREV(n,l))
#define FOREACHD(q,l,n,r) for (n = TAIL(q,l); n && (r = PREV(n,l), 1); n = r)
+/****************************************************************************/
+
#include "al.h"
/* unique library identifier */
@@ -184,7 +188,7 @@
/* number of bytes of a span that are stored in a chunk */
#define AL_CHUNK_SPAN(alc, off, n) \
- ((n) == AL_BYTES_ALL || (n) > AL_CHUNK_LEN(alc) - (off) ? \
+ ((n) > AL_CHUNK_LEN(alc) - (off) ? \
AL_CHUNK_LEN(alc) - (off) : (n))
/* number of bytes a chunk can be grown to the end */
@@ -357,41 +361,50 @@
* if off is negative, treat it as relative offset from the end
* a reference to the chunk is stored in *alcp
* the relative offset into the chunk is stored in *skipp
+ * return AL_OK and *alcp == NULL if positioned exactly to end of list
* return AL_ERR_EOF when no such chunk can be found
*/
static
al_rc_t al_seek(al_t *al, size_t off, al_chunk_t **alcp, size_t *skipp)
{
al_chunk_t *cur;
- size_t pos;
+ size_t pos, end;
size_t chunksize;
if (off >= 0) {
pos = 0;
FOREACH(al,chunks,cur) {
chunksize = AL_CHUNK_LEN(cur);
- if (pos <= off && off < pos+chunksize) {
+ end = pos+chunksize;
+ if (pos <= off && off < end) {
*alcp = cur;
*skipp = off - pos;
return AL_OK;
}
- if (pos+chunksize >= off)
- return AL_ERR_EOF;
- pos += chunksize;
+ if (end > off)
+ break;
+ pos = end;
+ }
+ /* seek to EOF position is ok */
+ if (pos == off) {
+ *alcp = NULL;
+ *skipp = 0;
+ return AL_OK;
}
} else {
off += al->bytes;
pos = al->bytes;
FOREACHR(al,chunks,cur) {
chunksize = AL_CHUNK_LEN(cur);
+ end = pos;
pos -= chunksize;
- if (pos <= off && off < pos+chunksize) {
+ if (pos <= off && off < end) {
*alcp = cur;
*skipp = off - pos;
return AL_OK;
}
- if (pos+chunksize < off)
- return AL_ERR_EOF;
+ if (pos < off)
+ break;
}
}
@@ -416,7 +429,7 @@
}
#endif
-/******************************************************************/
+/****************************************************************************/
/*
* allocate an empty assembly list
@@ -589,19 +602,15 @@
al_chunk_t *cur, *next;
size_t pos, skip, len, step;
- /* simplify API */
- if (n == AL_BYTES_ALL) n = al->bytes - off;
-
- pos = off;
-
/*
* 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, pos, &cur, &skip);
+ rc = al_seek(al, off, &cur, &skip);
if (rc != AL_OK) return rc;
/* as long as there is data to move */
+ pos = off;
while (n > 0 && cur != NULL) {
next = NEXT(cur, chunks);
len = AL_CHUNK_LEN(cur);
@@ -661,9 +670,6 @@
pos += step;
cur = next;
skip = 0;
-
- if (cur == NULL)
- break;
}
/*
@@ -704,7 +710,6 @@
nal->bytes = 0;
}
-
return AL_OK;
}
@@ -743,8 +748,6 @@
{
al_rc_t rc;
- if (n == AL_BYTES_ALL) n = al->bytes - off;
-
txp->cur = NULL;
rc = al_seek(al, off, &txp->cur, &txp->skip);
@@ -889,3 +892,22 @@
return AL_CHUNK_PTR(alc, off);
}
+/*
+ * convert error code into human readable form
+ */
+const char *al_error(al_rc_t rc)
+{
+ const char *mess;
+
+ switch (rc) {
+ case AL_OK: mess = "Everything Ok"; break;
+ case AL_ERR_ARG: mess = "Invalid Argument"; break;
+ case AL_ERR_MEM: mess = "Not Enough Memory"; break;
+ case AL_ERR_EOF: mess = "End Of Data"; break;
+ case AL_ERR_INT: mess = "Internal Error"; break;
+ default: mess = "Invalid Result Code"; break;
+ }
+
+ return mess;
+}
+
|