2  * Copyright (c) 2000-2004,2006,2011,2014 Apple Inc. All Rights Reserved. 
   4  * @APPLE_LICENSE_HEADER_START@ 
   6  * This file contains Original Code and/or Modifications of Original Code 
   7  * as defined in and that are subject to the Apple Public Source License 
   8  * Version 2.0 (the 'License'). You may not use this file except in 
   9  * compliance with the License. Please obtain a copy of the License at 
  10  * http://www.opensource.apple.com/apsl/ and read it before using this 
  13  * The Original Code and all software distributed under the License are 
  14  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 
  15  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 
  16  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 
  17  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 
  18  * Please see the License for the specific language governing rights and 
  19  * limitations under the License. 
  21  * @APPLE_LICENSE_HEADER_END@ 
  26 // cssmalloc - memory allocation in the CDSA world 
  31 #include <security_utilities/alloc.h> 
  32 #include <Security/cssm.h> 
  41 // A POD wrapper for the memory functions structure passed around in CSSM. 
  43 class CssmMemoryFunctions 
: public PodWrapper
<CssmMemoryFunctions
, CSSM_MEMORY_FUNCS
> { 
  45         CssmMemoryFunctions(const CSSM_MEMORY_FUNCS 
&funcs
) 
  46         { *(CSSM_MEMORY_FUNCS 
*)this = funcs
; } 
  47         CssmMemoryFunctions() { } 
  49         void *malloc(size_t size
) const throw(std::bad_alloc
); 
  50         void free(void *mem
) const throw() { free_func(mem
, AllocRef
); } 
  51         void *realloc(void *mem
, size_t size
) const throw(std::bad_alloc
); 
  52         void *calloc(uint32 count
, size_t size
) const throw(std::bad_alloc
); 
  54         bool operator == (const CSSM_MEMORY_FUNCS 
&other
) const throw() 
  55         { return !memcmp(this, &other
, sizeof(*this)); } 
  58 inline void *CssmMemoryFunctions::malloc(size_t size
) const throw(std::bad_alloc
) 
  60         if (void *addr 
= malloc_func(size
, AllocRef
)) 
  62         throw std::bad_alloc(); 
  65 inline void *CssmMemoryFunctions::calloc(uint32 count
, size_t size
) const throw(std::bad_alloc
) 
  67         if (void *addr 
= calloc_func(count
, size
, AllocRef
)) 
  69         throw std::bad_alloc(); 
  72 inline void *CssmMemoryFunctions::realloc(void *mem
, size_t size
) const throw(std::bad_alloc
) 
  74         if (void *addr 
= realloc_func(mem
, size
, AllocRef
)) 
  76         throw std::bad_alloc(); 
  81 // A Allocator based on CssmMemoryFunctions 
  83 class CssmMemoryFunctionsAllocator 
: public Allocator 
{ 
  85         CssmMemoryFunctionsAllocator(const CssmMemoryFunctions 
&memFuncs
) : functions(memFuncs
) { } 
  87         void *malloc(size_t size
) throw(std::bad_alloc
); 
  88         void free(void *addr
) throw(); 
  89         void *realloc(void *addr
, size_t size
) throw(std::bad_alloc
); 
  91         operator const CssmMemoryFunctions 
& () const throw() { return functions
; } 
  94         const CssmMemoryFunctions functions
; 
  99 // A MemoryFunctions object based on a Allocator. 
 100 // Note that we don't copy the Allocator object. It needs to live (at least) 
 101 // as long as any CssmAllocatorMemoryFunctions object based on it. 
 103 class CssmAllocatorMemoryFunctions 
: public CssmMemoryFunctions 
{ 
 105         CssmAllocatorMemoryFunctions(Allocator 
&alloc
); 
 106         CssmAllocatorMemoryFunctions() { /*IFDEBUG(*/ AllocRef 
= NULL 
/*)*/ ; } // later assignment req'd 
 109         static void *relayMalloc(size_t size
, void *ref
) throw(std::bad_alloc
); 
 110         static void relayFree(void *mem
, void *ref
) throw(); 
 111         static void *relayRealloc(void *mem
, size_t size
, void *ref
) throw(std::bad_alloc
); 
 112         static void *relayCalloc(uint32 count
, size_t size
, void *ref
) throw(std::bad_alloc
); 
 114         static Allocator 
&allocator(void *ref
) throw() 
 115         { return *reinterpret_cast<Allocator 
*>(ref
); } 
 120 // A generic helper for the unhappily ubiquitous CSSM-style 
 121 // (count, pointer-to-array) style of arrays. 
 123 template <class Base
, class Wrapper 
= Base
> 
 126     CssmVector(uint32 
&cnt
, Base 
* &vec
, Allocator 
&alloc 
= Allocator::standard()) 
 127         : count(cnt
), vector(reinterpret_cast<Wrapper 
* &>(vec
)), 
 134     ~CssmVector()       { allocator
.free(vector
); } 
 138     Allocator 
&allocator
; 
 141     Wrapper 
&operator [] (uint32 ix
) 
 142     { assert(ix 
< count
); return vector
[ix
]; } 
 144     void operator += (const Wrapper 
&add
) 
 146         vector 
= reinterpret_cast<Wrapper 
*>(allocator
.realloc(vector
, (count 
+ 1) * sizeof(Wrapper
))); 
 147         //@@@???compiler bug??? vector = allocator.alloc<Wrapper>(vector, count + 1); 
 148         vector
[count
++] = add
; 
 153 } // end namespace Security 
 155 #endif //_H_CSSMALLOC