MemPool -- better tests, more robust pointer handling, update documentation
diff --git a/test/qcbor_decode_tests.c b/test/qcbor_decode_tests.c
index 12be915..f1b5dbf 100644
--- a/test/qcbor_decode_tests.c
+++ b/test/qcbor_decode_tests.c
@@ -2502,75 +2502,85 @@
    return 0;
 }
 
+// Cheating declaration to get to the special test hook
+size_t MemPoolTestHook_GetPoolSize(void *ctx);
+
 
 int MemPoolTest(void)
 {
-    QCBORDecodeContext DC;
-    
-    const uint8_t pMinimalCBOR[] = {0xa0}; // One empty map
-    
-    QCBORDecode_Init(&DC, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(pMinimalCBOR),0);
-    
-    UsefulBuf_MAKE_STACK_UB(Pool, 100);
-    
-    QCBORDecode_SetMemPool(&DC, Pool, 0);
-    
-    // Cheat a little to get to the string allocator object
-    // so we can call it directly to test it
-    QCBORStringAllocator *pAlloc = (QCBORStringAllocator *)DC.pStringAllocator;
-    
-    // Ask for too much in one go
-    // 90 < 100, but there is some overhead taken out of the 100
-    UsefulBuf Allocated = (*pAlloc->fAllocate)(pAlloc->pAllocaterContext, NULL, 90);
-    if(!UsefulBuf_IsNULL(Allocated)) {
-        return -1;
-    }
-    
-    
-    
-    QCBORDecode_SetMemPool(&DC, Pool, 0);
-    
-    // Cheat a little to get to the string allocator object
-    // so we can call it directly to test it
-    pAlloc = (QCBORStringAllocator *)DC.pStringAllocator;
-    
-    Allocated = (*pAlloc->fAllocate)(pAlloc->pAllocaterContext, NULL, 30);
-    if(UsefulBuf_IsNULL(Allocated)) { // expected to succeed
-        return -1;
-    }
-    UsefulBuf Allocated2 = (*pAlloc->fAllocate)(pAlloc->pAllocaterContext, NULL, 30);
-    if(!UsefulBuf_IsNULL(Allocated2)) { // expected to fail
-        return -1;
-    }
-    (*pAlloc->fFree)(pAlloc->pAllocaterContext, Allocated.ptr);
-    Allocated = (*pAlloc->fAllocate)(pAlloc->pAllocaterContext, NULL, 30);
-    if(UsefulBuf_IsNULL(Allocated)) { // succeed because of the free
-        return -1;
-    }
-    
-    
-    QCBORDecode_SetMemPool(&DC, Pool, 0);
-    
-    // Cheat a little to get to the string allocator object
-    // so we can call it directly to test it
-    pAlloc = (QCBORStringAllocator *)DC.pStringAllocator;
-    Allocated = (*pAlloc->fAllocate)(pAlloc->pAllocaterContext, NULL, 20);
-    if(UsefulBuf_IsNULL(Allocated)) { // expected to succeed
-        return -1;
-    }
-    Allocated2 = (*pAlloc->fAllocate)(pAlloc->pAllocaterContext, Allocated.ptr, 25);
-    if(UsefulBuf_IsNULL(Allocated2)) { // expected to fail
-        return -1;
-    }
-    if(Allocated2.ptr != Allocated.ptr || Allocated2.len != 25) {
-        return -1;
-    }
-    
-    return 0;
-}
-
-
-
-
+   // Set up the decoder with a tiny bit of CBOR to parse
+   QCBORDecodeContext DC;
+   const uint8_t pMinimalCBOR[] = {0xa0}; // One empty map
+   QCBORDecode_Init(&DC, UsefulBuf_FROM_BYTE_ARRAY_LITERAL(pMinimalCBOR),0);
    
+   // Set up an memory pool of 100 bytes
+   UsefulBuf_MAKE_STACK_UB(Pool, 100);
+   QCBORDecode_SetMemPool(&DC, Pool, 0);
+    
+   // Cheat a little to get to the string allocator object
+   // so we can call it directly to test it
+   QCBORStringAllocator *pAlloc = (QCBORStringAllocator *)DC.pStringAllocator;
+   // Cheat some more to know exactly the 
+   size_t uAvailPool = MemPoolTestHook_GetPoolSize(pAlloc);
+
+   // First test -- ask for too much in one go
+   UsefulBuf Allocated = (*pAlloc->fAllocate)(pAlloc->pAllocaterContext, NULL, uAvailPool+1);
+   if(!UsefulBuf_IsNULL(Allocated)) {
+      return -1;
+   }
+   
+   
+   // Re do the set up for the next test that will do a successful alloc,
+   // a fail, a free and then success
+   // This test should work on 32 and 64-bit machines if the compiler
+   // does the expected thing with pointer sizes for the internal
+   // MemPool implementation leaving 44 or 72 bytes of pool memory.
+   QCBORDecode_SetMemPool(&DC, Pool, 0);
+    
+   // Cheat a little to get to the string allocator object
+   // so we can call it directly to test it
+   pAlloc = (QCBORStringAllocator *)DC.pStringAllocator;
+   // Cheat some more to know exactly the
+   uAvailPool = MemPoolTestHook_GetPoolSize(pAlloc);
+    
+   Allocated = (*pAlloc->fAllocate)(pAlloc->pAllocaterContext, NULL, uAvailPool-1);
+   if(UsefulBuf_IsNULL(Allocated)) { // expected to succeed
+      return -2;
+   }
+   UsefulBuf Allocated2 = (*pAlloc->fAllocate)(pAlloc->pAllocaterContext, NULL, uAvailPool/2);
+   if(!UsefulBuf_IsNULL(Allocated2)) { // expected to fail
+      return -3;
+   }
+   (*pAlloc->fFree)(pAlloc->pAllocaterContext, Allocated.ptr);
+   Allocated = (*pAlloc->fAllocate)(pAlloc->pAllocaterContext, NULL, uAvailPool/2);
+   if(UsefulBuf_IsNULL(Allocated)) { // succeed because of the free
+      return -4;
+   }
+    
+   
+   // Re do set up for next test that involves a successful alloc,
+   // and a successful realloc and a failed realloc
+   QCBORDecode_SetMemPool(&DC, Pool, 0);
+    
+   // Cheat a little to get to the string allocator object
+   // so we can call it directly to test it
+   pAlloc = (QCBORStringAllocator *)DC.pStringAllocator;
+   Allocated = (*pAlloc->fAllocate)(pAlloc->pAllocaterContext, NULL, uAvailPool/2);
+   if(UsefulBuf_IsNULL(Allocated)) { // expected to succeed
+      return -5;
+   }
+   Allocated2 = (*pAlloc->fAllocate)(pAlloc->pAllocaterContext, Allocated.ptr, uAvailPool);
+   if(UsefulBuf_IsNULL(Allocated2)) {
+      return -6;
+   }
+   if(Allocated2.ptr != Allocated.ptr || Allocated2.len != uAvailPool) {
+      return -7;
+   }
+   UsefulBuf Allocated3 = (*pAlloc->fAllocate)(pAlloc->pAllocaterContext, Allocated.ptr, uAvailPool+1);
+   if(!UsefulBuf_IsNULL(Allocated3)) { // expected to fail
+      return -8;
+   }
+    
+   return 0;
+}