#ifndef _H_UTILITIES
#define _H_UTILITIES
#include <security_utilities/utility_config.h>
#include <security_utilities/errors.h>
#include <exception>
#include <new>
#include <string>
#include <string.h>
namespace Security
{
#define IFDEBUG(it) IFELSEDEBUG(it,)
#define IFNDEBUG(it) IFELSEDEBUG(,it)
#if defined(NDEBUG)
# define safe_cast static_cast
# define safer_cast static_cast
# define IFELSEDEBUG(d,nd) nd
#else
template <class Derived, class Base>
inline Derived safer_cast(Base &base)
{
return dynamic_cast<Derived>(base);
}
template <class Derived, class Base>
inline Derived safe_cast(Base *base)
{
if (base == NULL)
return NULL; Derived p = dynamic_cast<Derived>(base);
assert(p);
return p;
}
# define IFELSEDEBUG(d,nd) d
#endif //NDEBUG
#define NOCOPY(Type) \
private: Type(const Type &) DEPRECATED_IN_MAC_OS_X_VERSION_10_0_AND_LATER; \
void operator = (const Type &) DEPRECATED_IN_MAC_OS_X_VERSION_10_0_AND_LATER;
#define MY_CSSM_ERRCODE_INVALID_POINTER 0x0004
template <class T>
inline T &Required(T *ptr, OSStatus err = MY_CSSM_ERRCODE_INVALID_POINTER)
{
if (ptr == NULL)
MacOSError::throwMe(err);
return *ptr;
}
inline void Required(void *ptr, OSStatus err = MY_CSSM_ERRCODE_INVALID_POINTER)
{
if (ptr == NULL)
MacOSError::throwMe(err);
}
template <class Wrapper, class POD>
class PodWrapper : public POD {
public:
static Wrapper * &overlayVar(POD * &data)
{ return reinterpret_cast<Wrapper * &>(data); }
static const Wrapper * &overlayVar(const POD * &data)
{ return reinterpret_cast<const Wrapper * &>(data); }
static Wrapper *overlay(POD *data)
{ return static_cast<Wrapper *>(data); }
static const Wrapper *overlay(const POD *data)
{ return static_cast<const Wrapper *>(data); }
static Wrapper &overlay(POD &data)
{ return static_cast<Wrapper &>(data); }
static const Wrapper &overlay(const POD &data)
{ return static_cast<const Wrapper &>(data); }
static Wrapper &required(POD *data)
{ return overlay(Required(data)); }
static const Wrapper &required(const POD *data)
{ return overlay(Required(data)); }
static Wrapper *optional(POD *data)
{ return overlay(data); }
static const Wrapper *optional(const POD *data)
{ return overlay(data); }
void clearPod()
{ memset(static_cast<POD *>(this), 0, sizeof(POD)); }
void assignPod(const POD &source)
{ static_cast<POD &>(*this) = source; }
};
template <class T>
struct Nonconst {
typedef T Type;
};
template <class U>
struct Nonconst<const U> {
typedef U Type;
};
template <class U>
struct Nonconst<const U *> {
typedef U *Type;
};
template <class T>
typename Nonconst<T>::Type unconst_cast(T obj)
{
return const_cast<typename Nonconst<T>::Type>(obj);
}
template <class T>
typename Nonconst<T>::Type &unconst_ref_cast(T &obj)
{
return const_cast<typename Nonconst<T>::Type &>(obj);
}
template <class In>
static inline void for_each_delete(In first, In last)
{
while (first != last)
delete *(first++);
}
template <class In>
static inline void for_each_map_delete(In first, In last)
{
while (first != last)
delete (first++)->second;
}
template <class InIterator, class OutIterator>
inline OutIterator copy_first(InIterator first, InIterator last, OutIterator out)
{
while (first != last)
*out++ = (first++)->first;
return out;
}
template <class InIterator, class OutIterator>
inline OutIterator copy_second(InIterator first, InIterator last, OutIterator out)
{
while (first != last)
*out++ = (first++)->second;
return out;
}
class RecursionBlock {
public:
RecursionBlock() : mActive(false) { }
~RecursionBlock() { assert(!mActive); }
public:
class Once {
public:
Once(RecursionBlock &rb) : block(rb), mActive(false) { }
~Once() { block.mActive &= !mActive; }
bool operator () ()
{ if (block.mActive) return true; mActive = block.mActive = true; return false; }
RecursionBlock █
private:
bool mActive;
};
friend class Once;
private:
bool mActive;
};
template <class T>
class auto_array
{
public:
auto_array() : mArray(NULL) {}
auto_array(size_t inSize) : mArray(new T[inSize]) {}
~auto_array() { if (mArray) delete[] mArray; }
T &operator[](size_t inIndex) { return mArray[inIndex]; }
void allocate(size_t inSize) { if (mArray) delete[] mArray; mArray = new T[inSize]; }
T *get() { return mArray; }
T *release() { T *anArray = mArray; mArray = NULL; return anArray; }
private:
T *mArray;
};
template <class _Tp>
class constVector
{
NOCOPY(constVector<_Tp>)
public:
typedef _Tp value_type;
typedef const value_type* const_pointer;
typedef const value_type* const_iterator;
typedef const value_type& const_reference;
typedef size_t size_type;
typedef ptrdiff_t difference_type;
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
public:
const_iterator begin() const { return _M_start; }
const_iterator end() const { return _M_finish; }
const_reverse_iterator rbegin() const
{ return const_reverse_iterator(end()); }
const_reverse_iterator rend() const
{ return const_reverse_iterator(begin()); }
size_type size() const
{ return size_type(end() - begin()); }
bool empty() const
{ return begin() == end(); }
const_reference operator[](size_type __n) const { return *(begin() + __n); }
const_reference at(size_type n) const { return (*this)[n]; }
constVector(size_type __n, const _Tp* __value)
: _M_start(__value), _M_finish(__value + __n)
{}
constVector() : _M_start(NULL), _M_finish(NULL) {}
void overlay(size_type __n, const _Tp* __value) {
_M_start = __value;
_M_finish = __value + __n;
}
const_reference front() const { return *begin(); }
const_reference back() const { return *(end() - 1); }
private:
const _Tp *_M_start;
const _Tp *_M_finish;
};
char *cached_realpath(const char * file_name, char * resolved_name);
}
#endif //_H_UTILITIES