From 3fa19b7dfc785aeaa8c1d32782b0b0018a965d13 Mon Sep 17 00:00:00 2001 From: antirez Date: Thu, 9 Feb 2012 16:28:35 +0100 Subject: [PATCH] ziplist.c endianess fixes, chapter 3. --- src/endian.h | 3 +++ src/ziplist.c | 28 ++++++++++++++++++---------- 2 files changed, 21 insertions(+), 10 deletions(-) diff --git a/src/endian.h b/src/endian.h index 03a5b094a..75b91728d 100644 --- a/src/endian.h +++ b/src/endian.h @@ -4,6 +4,9 @@ void memrev16(void *p); void memrev32(void *p); void memrev64(void *p); +uint16_t intrev16(uint16_t v); +uint32_t intrev32(uint32_t v); +uint64_t intrev64(uint64_t v); /* variants of the function doing the actual convertion only if the target * host is big endian */ diff --git a/src/ziplist.c b/src/ziplist.c index f2ce933ff..95103dc07 100644 --- a/src/ziplist.c +++ b/src/ziplist.c @@ -99,7 +99,7 @@ * pushed one at a time. */ #define ZIPLIST_INCR_LENGTH(zl,incr) { \ if (ZIPLIST_LENGTH(zl) < UINT16_MAX) \ - ZIPLIST_LENGTH(zl) += intrev16ifbe(incr); \ + ZIPLIST_LENGTH(zl) = intrev16ifbe(intrev16ifbe(ZIPLIST_LENGTH(zl))+incr); \ } typedef struct zlentry { @@ -308,7 +308,7 @@ static int64_t zipLoadInteger(unsigned char *p, unsigned char encoding) { ret = i32; } else if (encoding == ZIP_INT_64B) { memcpy(&i64,p,sizeof(i64)); - memrev16ifbe(&i64); + memrev64ifbe(&i64); ret = i64; } else { assert(NULL); @@ -403,8 +403,10 @@ static unsigned char *__ziplistCascadeUpdate(unsigned char *zl, unsigned char *p noffset = np-zl; /* Update tail offset when next element is not the tail element. */ - if ((zl+intrev32ifbe(ZIPLIST_TAIL_OFFSET(zl))) != np) - ZIPLIST_TAIL_OFFSET(zl) += intrev32ifbe(extra); + if ((zl+intrev32ifbe(ZIPLIST_TAIL_OFFSET(zl))) != np) { + ZIPLIST_TAIL_OFFSET(zl) = + intrev32ifbe(intrev32ifbe(ZIPLIST_TAIL_OFFSET(zl))+extra); + } /* Move the tail to the back. */ memmove(np+rawlensize, @@ -455,14 +457,17 @@ static unsigned char *__ziplistDelete(unsigned char *zl, unsigned char *p, unsig zipPrevEncodeLength(p-nextdiff,first.prevrawlen); /* Update offset for tail */ - ZIPLIST_TAIL_OFFSET(zl) -= intrev32ifbe(totlen); + ZIPLIST_TAIL_OFFSET(zl) = + intrev32ifbe(intrev32ifbe(ZIPLIST_TAIL_OFFSET(zl))-totlen); /* When the tail contains more than one entry, we need to take * "nextdiff" in account as well. Otherwise, a change in the * size of prevlen doesn't have an effect on the *tail* offset. */ tail = zipEntry(p); - if (p[tail.headersize+tail.len] != ZIP_END) - ZIPLIST_TAIL_OFFSET(zl) += intrev32ifbe(nextdiff); + if (p[tail.headersize+tail.len] != ZIP_END) { + ZIPLIST_TAIL_OFFSET(zl) += + intrev32ifbe(intrev32ifbe(ZIPLIST_TAIL_OFFSET(zl))+nextdiff); + } /* Move tail to the front of the ziplist */ memmove(first.p,p-nextdiff, @@ -542,14 +547,17 @@ static unsigned char *__ziplistInsert(unsigned char *zl, unsigned char *p, unsig zipPrevEncodeLength(p+reqlen,reqlen); /* Update offset for tail */ - ZIPLIST_TAIL_OFFSET(zl) += intrev32ifbe(reqlen); + ZIPLIST_TAIL_OFFSET(zl) = + intrev32ifbe(intrev32ifbe(ZIPLIST_TAIL_OFFSET(zl))+reqlen); /* When the tail contains more than one entry, we need to take * "nextdiff" in account as well. Otherwise, a change in the * size of prevlen doesn't have an effect on the *tail* offset. */ tail = zipEntry(p+reqlen); - if (p[reqlen+tail.headersize+tail.len] != ZIP_END) - ZIPLIST_TAIL_OFFSET(zl) += intrev32ifbe(nextdiff); + if (p[reqlen+tail.headersize+tail.len] != ZIP_END) { + ZIPLIST_TAIL_OFFSET(zl) = + intrev32ifbe(intrev32ifbe(ZIPLIST_TAIL_OFFSET(zl))+nextdiff); + } } else { /* This element will be the new tail. */ ZIPLIST_TAIL_OFFSET(zl) = intrev32ifbe(p-zl);