X-Git-Url: https://git.saurik.com/apple/security.git/blobdiff_plain/bac41a7b9a0a9254fa30f8bb6e6038ab71a483e2..ce0ac947b4708d0bc1c7e6789b3e1f3bfc80d6e9:/cdsa/cdsa_utilities/cssmalloc.h?ds=inline diff --git a/cdsa/cdsa_utilities/cssmalloc.h b/cdsa/cdsa_utilities/cssmalloc.h index f09fa171..18bd5097 100644 --- a/cdsa/cdsa_utilities/cssmalloc.h +++ b/cdsa/cdsa_utilities/cssmalloc.h @@ -25,7 +25,6 @@ #include #include #include -#include #ifdef _CPP_CSSMALLOC # pragma export on @@ -42,24 +41,24 @@ namespace Security class CssmAllocator { public: virtual ~CssmAllocator(); - virtual void *malloc(size_t) = 0; - virtual void free(void *) = 0; - virtual void *realloc(void *, size_t) = 0; + virtual void *malloc(size_t) throw(std::bad_alloc) = 0; + virtual void free(void *) throw() = 0; + virtual void *realloc(void *, size_t) throw(std::bad_alloc) = 0; // // Template versions for added expressiveness. // Note that the integers are element counts, not byte sizes. // - template T *alloc() + template T *alloc() throw(std::bad_alloc) { return reinterpret_cast(malloc(sizeof(T))); } - template T *alloc(uint32 count) + template T *alloc(uint32 count) throw(std::bad_alloc) { return reinterpret_cast(malloc(sizeof(T) * count)); } - template T *alloc(T *old, uint32 count) + template T *alloc(T *old, uint32 count) throw(std::bad_alloc) { return reinterpret_cast(realloc(old, sizeof(T) * count)); } - template CssmData alloc(const Data &source) + template CssmData alloc(const Data &source) throw(std::bad_alloc) { size_t length = source.length(); return CssmData(memcpy(malloc(length), source.data(), length), length); @@ -69,14 +68,14 @@ public: // Happier malloc/realloc for any type. Note that these still have // the original (byte-sized) argument profile. // - template T *malloc(size_t size) + template T *malloc(size_t size) throw(std::bad_alloc) { return reinterpret_cast(malloc(size)); } - template T *realloc(void *addr, size_t size) + template T *realloc(void *addr, size_t size) throw(std::bad_alloc) { return reinterpret_cast(realloc(addr, size)); } - + // All right, if you *really* have to have calloc... - void *calloc(size_t size, unsigned int count) + void *calloc(size_t size, unsigned int count) throw(std::bad_alloc) { void *addr = malloc(size * count); memset(addr, 0, size * count); @@ -84,7 +83,7 @@ public: } // compare CssmAllocators for identity - virtual bool operator == (const CssmAllocator &alloc) const; + virtual bool operator == (const CssmAllocator &alloc) const throw(); public: // allocator chooser options @@ -106,30 +105,30 @@ public: { *(CSSM_MEMORY_FUNCS *)this = funcs; } CssmMemoryFunctions() { } - void *malloc(size_t size) const; - void free(void *mem) const { free_func(mem, AllocRef); } - void *realloc(void *mem, size_t size) const; - void *calloc(uint32 count, size_t size) const; + void *malloc(size_t size) const throw(std::bad_alloc); + void free(void *mem) const throw() { free_func(mem, AllocRef); } + void *realloc(void *mem, size_t size) const throw(std::bad_alloc); + void *calloc(uint32 count, size_t size) const throw(std::bad_alloc); - bool operator == (const CSSM_MEMORY_FUNCS &other) const + bool operator == (const CSSM_MEMORY_FUNCS &other) const throw() { return !memcmp(this, &other, sizeof(*this)); } }; -inline void *CssmMemoryFunctions::malloc(size_t size) const +inline void *CssmMemoryFunctions::malloc(size_t size) const throw(std::bad_alloc) { if (void *addr = malloc_func(size, AllocRef)) return addr; throw std::bad_alloc(); } -inline void *CssmMemoryFunctions::calloc(uint32 count, size_t size) const +inline void *CssmMemoryFunctions::calloc(uint32 count, size_t size) const throw(std::bad_alloc) { if (void *addr = calloc_func(count, size, AllocRef)) return addr; throw std::bad_alloc(); } -inline void *CssmMemoryFunctions::realloc(void *mem, size_t size) const +inline void *CssmMemoryFunctions::realloc(void *mem, size_t size) const throw(std::bad_alloc) { if (void *addr = realloc_func(mem, size, AllocRef)) return addr; @@ -144,12 +143,12 @@ class CssmMemoryFunctionsAllocator : public CssmAllocator { public: CssmMemoryFunctionsAllocator(const CssmMemoryFunctions &memFuncs) : functions(memFuncs) { } - void *malloc(size_t size); - void free(void *addr); - void *realloc(void *addr, size_t size); - - operator const CssmMemoryFunctions & () const { return functions; } + void *malloc(size_t size) throw(std::bad_alloc); + void free(void *addr) throw(); + void *realloc(void *addr, size_t size) throw(std::bad_alloc); + operator const CssmMemoryFunctions & () const throw() { return functions; } + private: const CssmMemoryFunctions functions; }; @@ -159,23 +158,27 @@ private: // // Global C++ allocation hooks to use CssmAllocators // -inline void *operator new (size_t size, CssmAllocator &allocator) +inline void *operator new (size_t size, CssmAllocator &allocator) throw (std::bad_alloc) { return allocator.malloc(size); } +inline void *operator new[] (size_t size, CssmAllocator &allocator) throw (std::bad_alloc) +{ return allocator.malloc(size); } + + // // You'd think that this is operator delete(const T *, CssmAllocator &), but you'd // be wrong. Specialized operator delete is only called during constructor cleanup. // Use this to cleanly destroy things. // template -inline void destroy(T *obj, CssmAllocator &alloc) +inline void destroy(T *obj, CssmAllocator &alloc) throw() { obj->~T(); alloc.free(obj); } // untyped (release memory only, no destructor call) -inline void destroy(void *obj, CssmAllocator &alloc) +inline void destroy(void *obj, CssmAllocator &alloc) throw() { alloc.free(obj); } @@ -194,18 +197,18 @@ public: CssmAllocatorMemoryFunctions() { /*IFDEBUG(*/ AllocRef = NULL /*)*/ ; } // later assignment req'd private: - static void *relayMalloc(size_t size, void *ref); - static void relayFree(void *mem, void *ref); - static void *relayRealloc(void *mem, size_t size, void *ref); - static void *relayCalloc(uint32 count, size_t size, void *ref); - - static CssmAllocator &allocator(void *ref) + static void *relayMalloc(size_t size, void *ref) throw(std::bad_alloc); + static void relayFree(void *mem, void *ref) throw(); + static void *relayRealloc(void *mem, size_t size, void *ref) throw(std::bad_alloc); + static void *relayCalloc(uint32 count, size_t size, void *ref) throw(std::bad_alloc); + + static CssmAllocator &allocator(void *ref) throw() { return *reinterpret_cast(ref); } }; // -// A mixin class to automatically manage your allocator. +// A mixin class to automagically manage your allocator. // To allow allocation (of your object) from any instance of CssmAllocator, // inherit from CssmHeap. Your users can then create heap instances of your thing by // new (an-allocator) YourClass(...) @@ -219,9 +222,9 @@ private: // class CssmHeap { public: - void *operator new (size_t size, CssmAllocator *alloc = NULL); - void operator delete (void *addr, size_t size); - void operator delete (void *addr, size_t size, CssmAllocator *alloc); + void *operator new (size_t size, CssmAllocator *alloc = NULL) throw(std::bad_alloc); + void operator delete (void *addr, size_t size) throw(); + void operator delete (void *addr, size_t size, CssmAllocator *alloc) throw(); }; @@ -248,12 +251,12 @@ public: template CssmAutoPtr(CssmAllocator &alloc, CssmAutoPtr &src) : allocator(alloc), mine(rc.release()) { assert(allocator == src.allocator); } - ~CssmAutoPtr() { destroy(mine); } + ~CssmAutoPtr() { allocator.free(mine); } T *get() const throw() { return mine; } T *release() { T *result = mine; mine = NULL; return result; } void reset() { allocator.free(mine); mine = NULL; } - + operator T * () const { return mine; } T *operator -> () const { return mine; } T &operator * () const { assert(mine); return *mine; } @@ -317,48 +320,39 @@ public: // -// A CssmAllocator that keeps track of allocations and can throw everything -// away unless explicitly committed. +// A generic helper for the unhappily ubiquitous CSSM-style +// (count, pointer-to-array) style of arrays. // -class TrackingAllocator : public CssmAllocator -{ +template +class CssmVector { public: - TrackingAllocator(CssmAllocator &inAllocator) : mAllocator(inAllocator) {} - virtual ~TrackingAllocator(); + CssmVector(uint32 &cnt, Base * &vec, CssmAllocator &alloc = CssmAllocator::standard()) + : count(cnt), vector(reinterpret_cast(vec)), + allocator(alloc) + { + count = 0; + vector = NULL; + } + + ~CssmVector() { allocator.free(vector); } + + uint32 &count; + Wrapper * &vector; + CssmAllocator &allocator; - void *malloc(size_t inSize) - { - void *anAddress = mAllocator.malloc(inSize); - mAllocSet.insert(anAddress); - return anAddress; - } - - void free(void *inAddress) - { - mAllocator.free(inAddress); - mAllocSet.erase(inAddress); - } - - void *realloc(void *inAddress, size_t inNewSize) - { - void *anAddress = mAllocator.realloc(inAddress, inNewSize); - if (anAddress != inAddress) - { - mAllocSet.erase(inAddress); - mAllocSet.insert(anAddress); - } - - return anAddress; - } - - void commit() { mAllocSet.clear(); } -private: - typedef std::set AllocSet; - - CssmAllocator &mAllocator; - AllocSet mAllocSet; +public: + Wrapper &operator [] (uint32 ix) + { assert(ix < count); return vector[ix]; } + + void operator += (const Wrapper &add) + { + vector = reinterpret_cast(allocator.realloc(vector, (count + 1) * sizeof(Wrapper))); + //@@@???compiler bug??? vector = allocator.alloc(vector, count + 1); + vector[count++] = add; + } }; + } // end namespace Security #ifdef _CPP_CSSMALLOC