]> code.citadel.org Git - citadel.git/blobdiff - libcitadel/lib/hash.c
* fix hashlist iterator
[citadel.git] / libcitadel / lib / hash.c
index fd8916f1757988627045b9dca75f7088e5b6025f..e3be284023c196ddce920a4966c49adef566a9e4 100644 (file)
@@ -575,8 +575,7 @@ HashPos *GetNewHashPos(HashList *Hash, int StepWidth)
        else
                Ret->StepWidth = 1;
        if (Ret->StepWidth <  0) {
-               Ret->Position = (Hash->nMembersUsed % (-Ret->StepWidth)) 
-                       * (-Ret->StepWidth);
+               Ret->Position = Hash->nMembersUsed - 1;
        }
        else {
                Ret->Position = 0;
@@ -589,8 +588,13 @@ HashPos *GetNewHashPos(HashList *Hash, int StepWidth)
  * \param the Iterator to analyze
  * \returns the n'th hashposition we point at
  */
-int GetHashPosCounter(HashPos *At)
+int GetHashPosCounter(HashList *Hash, HashPos *At)
 {
+       if ((Hash == NULL) || 
+           (At->Position >= Hash->nMembersUsed) || 
+           (At->Position < 0) ||
+           (At->Position > Hash->nMembersUsed))
+               return 0;
        return At->Position;
 }
 
@@ -618,19 +622,49 @@ void DeleteHashPos(HashPos **DelMe)
 int GetNextHashPos(HashList *Hash, HashPos *At, long *HKLen, const char **HashKey, void **Data)
 {
        long PayloadPos;
+       long offset = 0;
 
-       if ((Hash == NULL) || (At->Position >= Hash->nMembersUsed))
+       if ((Hash == NULL) || 
+           (At->Position >= Hash->nMembersUsed) || 
+           (At->Position < 0) ||
+           (At->Position > Hash->nMembersUsed))
                return 0;
        *HKLen = Hash->LookupTable[At->Position]->HKLen;
        *HashKey = Hash->LookupTable[At->Position]->HashKey;
        PayloadPos = Hash->LookupTable[At->Position]->Position;
        *Data = Hash->Members[PayloadPos]->Data;
+       /* Position is NULL-Based, while Stepwidth is not... */
+       if (At->StepWidth < 0)
+               offset = 1;
+       if ((At->Position % abs(At->StepWidth)) == 0)
+               At->Position += At->StepWidth;
+       else 
+               At->Position += ((At->Position) % abs(At->StepWidth)) * 
+                       (At->StepWidth / abs(At->StepWidth));
+       return 1;
+}
 
-       At->Position += At->StepWidth;
-       if (At->Position > Hash->nMembersUsed) {
-               At->Position = Hash->nMembersUsed;
+/**
+ * \brief Get the data located where At points to
+ * note: you should prefer iterator operations instead of using me.
+ * \param Hash your Hashlist peek from
+ * \param HKLen returns Length of Hashkey Returned
+ * \param HashKey returns the Hashkey corrosponding to HashPos
+ * \param Data returns the Data found at HashPos
+ * \returns whether the item was found or not.
+ */
+int GetHashAt(HashList *Hash,long At, long *HKLen, const char **HashKey, void **Data)
+{
+       long PayloadPos;
+
+       if ((Hash == NULL) || 
+           (At < 0) || 
+           (At > Hash->nMembersUsed))
                return 0;
-       }
+       *HKLen = Hash->LookupTable[At]->HKLen;
+       *HashKey = Hash->LookupTable[At]->HashKey;
+       PayloadPos = Hash->LookupTable[At]->Position;
+       *Data = Hash->Members[PayloadPos]->Data;
        return 1;
 }
 
@@ -766,4 +800,10 @@ void reference_free_handler(void *ptr)
 }
 
 
+/*
+ * This exposes the hashlittle() function to consumers.
+ */
+int HashLittle(const void *key, size_t length) {
+       return (int)hashlittle(key, length, 1);
+}