diff options
author | root <devnull@localhost> | 1996-02-15 22:44:46 +0000 |
---|---|---|
committer | root <devnull@localhost> | 1996-02-15 22:44:46 +0000 |
commit | d396a858d132b6099afd5a2a990bb8366aa352c4 (patch) | |
tree | 9e1ff196cc8bcca9636b791381fec7e1ee25e712 /lib/header.c | |
parent | 1efa980d28535a131268521f61851b09e98194f6 (diff) | |
download | librpm-tizen-d396a858d132b6099afd5a2a990bb8366aa352c4.tar.gz librpm-tizen-d396a858d132b6099afd5a2a990bb8366aa352c4.tar.bz2 librpm-tizen-d396a858d132b6099afd5a2a990bb8366aa352c4.zip |
do not allow STRING_TYPE with count != 1
move index/data sorting into copyHeader()
cause sizeofHeader() tp call copyHeader() to sort index/data
have writeHeader() call sizeofHeader() to sort index/data
The net effect is that if you call writeHeader() or sizeofHeader()
your Header is actually sorted and replaced with a new copy.
CVS patchset: 289
CVS date: 1996/02/15 22:44:46
Diffstat (limited to 'lib/header.c')
-rw-r--r-- | lib/header.c | 93 |
1 files changed, 65 insertions, 28 deletions
diff --git a/lib/header.c b/lib/header.c index 3adfc9fef..7d02b8375 100644 --- a/lib/header.c +++ b/lib/header.c @@ -30,6 +30,7 @@ struct headerToken { int data_used; int mutable; + int fully_sorted; /* This means the index and the data! */ }; struct indexEntry { @@ -105,6 +106,8 @@ int nextIterator(HeaderIterator iter, } /* Fall through to STRING_ARRAY_TYPE */ case STRING_ARRAY_TYPE: + /* Correction! */ + *type = STRING_ARRAY_TYPE; /* Otherwise, build up an array of char* to return */ x = index[slot].count; *p = malloc(x * sizeof(char *)); @@ -124,17 +127,39 @@ int nextIterator(HeaderIterator iter, return 1; } +static int indexSort(const void *ap, const void *bp) +{ + int_32 a, b; + + a = ((struct indexEntry *)ap)->tag; + b = ((struct indexEntry *)bp)->tag; + + if (a > b) { + return 1; + } else if (a < b) { + return -1; + } else { + return 0; + } +} + Header copyHeader(Header h) { int_32 tag, type, count; void *ptr; - HeaderIterator headerIter = initIterator(h); + HeaderIterator headerIter; Header res = newHeader(); + + /* Sort the index */ + qsort(h->index, h->entries_used, sizeof(struct indexEntry), indexSort); + headerIter = initIterator(h); + /* The result here is that the data is also sorted */ while (nextIterator(headerIter, &tag, &type, &ptr, &count)) { addEntry(res, tag, type, ptr, count); } + res->fully_sorted = 1; return res; } @@ -144,45 +169,34 @@ Header copyHeader(Header h) /* */ /********************************************************************/ -static int indexSort(const void *ap, const void *bp) -{ - int_32 a, b; - - a = ((struct indexEntry *)ap)->tag; - b = ((struct indexEntry *)bp)->tag; - - if (a > b) { - return 1; - } else if (a < b) { - return -1; - } else { - return 0; - } -} - void writeHeader(int fd, Header h) { int_32 l; - struct indexEntry *sortedIndex, *p; + struct indexEntry *p; + struct indexEntry *copyIndex; int c; void *converted_data; + /* This magic actually sorts the data */ + sizeofHeader(h); + /* We must write using network byte order! */ /* First write out the length of the index (count of index entries) */ l = htonl(h->entries_used); write(fd, &l, sizeof(l)); - /* And the length of the data (number of bytes) */ + /* Then write the length of the data (number of bytes) */ l = htonl(h->data_used); write(fd, &l, sizeof(l)); - /* Sort and convert the index */ - sortedIndex = malloc(sizeof(struct indexEntry) * h->entries_used); - memcpy(sortedIndex, h->index, sizeof(struct indexEntry) * h->entries_used); - qsort(sortedIndex, h->entries_used, sizeof(struct indexEntry), indexSort); + /* Make a copy of the index for htonl() */ + copyIndex = malloc(sizeof(struct indexEntry) * h->entries_used); + memcpy(copyIndex, h->index, sizeof(struct indexEntry) * h->entries_used); + + /* Convert the index */ c = h->entries_used; - p = sortedIndex; + p = copyIndex; while (c--) { p->tag = htonl(p->tag); p->type = htonl(p->type); @@ -192,8 +206,8 @@ void writeHeader(int fd, Header h) } /* Write the index */ - write(fd, sortedIndex, sizeof(struct indexEntry) * h->entries_used); - free(sortedIndex); + write(fd, copyIndex, sizeof(struct indexEntry) * h->entries_used); + free(copyIndex); /* Finally convert and write the data */ converted_data = dataHostToNetwork(h); @@ -296,6 +310,7 @@ Header readHeader(int fd) free(h->data); h->data = converted_data; + h->fully_sorted = 1; h->mutable = 0; return h; @@ -377,6 +392,7 @@ Header loadHeader(void *pv) h->data_used = dl; h->data = p; + h->fully_sorted = 0; h->mutable = 0; return h; @@ -625,6 +641,8 @@ int getEntry(Header h, int_32 tag, int_32 * type, void **p, int_32 * c) } /* Fall through to STRING_ARRAY_TYPE */ case STRING_ARRAY_TYPE: + /* Correction! */ + *type = STRING_ARRAY_TYPE; /* Otherwise, build up an array of char* to return */ x = index->count; *p = malloc(x * sizeof(char *)); @@ -664,6 +682,7 @@ Header newHeader() h->entries_malloced = INDEX_MALLOC_SIZE; h->entries_used = 0; + h->fully_sorted = 0; h->mutable = 1; return (Header) h; @@ -681,12 +700,23 @@ void freeHeader(Header h) unsigned int sizeofHeader(Header h) { unsigned int size; - + Header newh; + Header temph; + + /* Do some real magic to determine the ON-DISK size */ + if (!h->fully_sorted) { + newh = copyHeader(h); + temph = malloc(sizeof(*temph)); + *temph = *h; + *h = *newh; + freeHeader(temph); + } + size = sizeof(int_32); /* count of index entries */ size += sizeof(int_32); /* length of data */ size += sizeof(struct indexEntry) * h->entries_used; size += h->data_used; - + return size; } @@ -757,6 +787,9 @@ int addEntry(Header h, int_32 tag, int_32 type, void *p, int_32 c) break; } /* Otherwise fall through to STRING_ARRAY_TYPE */ + /* This should not be allowed */ + fprintf(stderr, "addEntry() STRING_TYPE count must be 0.\n"); + exit(1); case STRING_ARRAY_TYPE: /* This is like STRING_TYPE, except it's *always* an array */ /* Compute sum of length of all strings, including null terminators */ @@ -801,6 +834,9 @@ int addEntry(Header h, int_32 tag, int_32 type, void *p, int_32 c) break; } /* Fall through to STRING_ARRAY_TYPE */ + /* This should not be allowed */ + fprintf(stderr, "addEntry() internal error!.\n"); + exit(1); case STRING_ARRAY_TYPE: /* Otherwise, p is char** */ i = c; @@ -817,6 +853,7 @@ int addEntry(Header h, int_32 tag, int_32 type, void *p, int_32 c) } h->data_used += length + pad; + h->fully_sorted = 0; return 1; } |