/*************************************************
* Secure Memory Allocator Header File            *
* (C) 1999-2003 The Botan Project                *
*************************************************/

#ifndef BOTAN_SECURE_ALLOCATOR_H__
#define BOTAN_SECURE_ALLOCATOR_H__

#include <botan/exceptn.h>
#include <botan/mutex.h>
#include <map>
#include <vector>

namespace Botan {

/*************************************************
* Secure Memory Allocator                        *
*************************************************/
class SecureAllocator
   {
   public:
      struct Memory_Exhaustion : public Exception
         {
         Memory_Exhaustion() :
            Exception("SecureAllocator: Ran out of memory") {}
         };

      struct Buffer { u32bit length; void* data; };

      virtual void* allocate(u32bit) const;
      virtual void deallocate(void*, u32bit) const;
      virtual SecureAllocator* clone() = 0;
      bool single_copy() const { return single; }

      SecureAllocator(bool, u32bit = 0);
      virtual ~SecureAllocator();
   protected:
      const u32bit PREF_SIZE;
   private:
      static const u32bit ALIGN_TO = 8;
      virtual void* alloc_block(u32bit) const = 0;
      virtual void dealloc_block(void*, u32bit) const = 0;

      void* find_free_block(u32bit) const;
      void defrag_free_list() const;
      u32bit find_buffer(void*) const;

      bool same_buffer(Buffer&, Buffer&) const;
      bool overlap(Buffer, Buffer) const;
      void remove_empty_buffers(std::vector<Buffer>&) const;

      const bool single;
      mutable std::map<void*, Buffer*> allocated;
      mutable std::vector<Buffer> free_list;
      mutable std::vector<Buffer> buffer_list;
      mutable Mutex* lock;
   };

}

#endif
