CoreFoundation: redesign
Signed-off-by: Simon Rozman <simon@rozman.si>
This commit is contained in:
parent
c0e1163877
commit
a04c27a14e
@ -8,34 +8,97 @@
|
|||||||
#include "common.hpp"
|
#include "common.hpp"
|
||||||
#include <CoreFoundation/CoreFoundation.h>
|
#include <CoreFoundation/CoreFoundation.h>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <system_error>
|
||||||
|
|
||||||
namespace macstd {
|
namespace macstd {
|
||||||
///
|
///
|
||||||
/// Deleter for unique_ptr using CFRelease
|
/// IOKit handle wrapper class
|
||||||
///
|
///
|
||||||
struct CFRelease_delete
|
template <typename T, const T INVAL>
|
||||||
|
class cf_object : public handle<T, INVAL>
|
||||||
{
|
{
|
||||||
///
|
MACSTD_HANDLE_IMPL(cf_object, T, INVAL)
|
||||||
/// Default constructor
|
|
||||||
///
|
|
||||||
CFRelease_delete() noexcept {}
|
|
||||||
|
|
||||||
|
public:
|
||||||
///
|
///
|
||||||
/// Delete a pointer
|
/// Releases a Core Foundation object
|
||||||
///
|
///
|
||||||
/// \sa [CFRelease function](https://developer.apple.com/documentation/corefoundation/1521153-cfrelease)
|
/// \sa [CFRelease function](https://developer.apple.com/documentation/corefoundation/1521153-cfrelease)
|
||||||
///
|
///
|
||||||
template <class _T>
|
virtual ~cf_object()
|
||||||
void operator()(_T *_Ptr) const
|
|
||||||
{
|
{
|
||||||
CFRelease(_Ptr);
|
if (this->m_h != INVAL)
|
||||||
|
free_internal();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
///
|
||||||
|
/// Releases a Core Foundation object
|
||||||
|
///
|
||||||
|
/// \sa [CFRelease function](https://developer.apple.com/documentation/corefoundation/1521153-cfrelease)
|
||||||
|
///
|
||||||
|
void free_internal() noexcept override
|
||||||
|
{
|
||||||
|
CFRelease(this->m_h);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
using cfstring = cf_object<CFStringRef, static_cast<CFStringRef>(NULL)>;
|
||||||
|
using cferror = cf_object<CFErrorRef, static_cast<CFErrorRef>(NULL)>;
|
||||||
|
|
||||||
///
|
///
|
||||||
/// CFType helper
|
/// Core Foundation runtime error
|
||||||
///
|
///
|
||||||
/// \sa [CFType](https://developer.apple.com/documentation/corefoundation/cftype)
|
class cf_runtime_error : public num_runtime_error<CFIndex>
|
||||||
template <class T>
|
{
|
||||||
using CFType = std::unique_ptr<T, CFRelease_delete>;
|
protected:
|
||||||
|
cferror m_error;
|
||||||
|
|
||||||
|
public:
|
||||||
|
///
|
||||||
|
/// Constructs an exception
|
||||||
|
///
|
||||||
|
/// \param[in] error Core Foundation error
|
||||||
|
///
|
||||||
|
cf_runtime_error(CFErrorRef error) :
|
||||||
|
num_runtime_error<CFIndex>(CFErrorGetCode(error), message(error)),
|
||||||
|
m_error(error)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Constructs an exception
|
||||||
|
///
|
||||||
|
/// \param[in] error Core Foundation error
|
||||||
|
///
|
||||||
|
cf_runtime_error(cferror&& error) :
|
||||||
|
num_runtime_error<CFIndex>(CFErrorGetCode(error), message(error)),
|
||||||
|
m_error(std::move(error))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
CFErrorRef cferror() const noexcept { return m_error; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
///
|
||||||
|
/// Returns a string explaining the meaning of a Core Foundation error
|
||||||
|
///
|
||||||
|
static std::string message(CFErrorRef error)
|
||||||
|
{
|
||||||
|
macstd::cfstring description(CFErrorCopyDescription(error));
|
||||||
|
if (description && CFStringGetLength(description) > 0) {
|
||||||
|
auto str = CFStringGetCStringPtr(description, kCFStringEncodingUTF8);
|
||||||
|
if (str)
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
std::string msg("Core Foundation error " + std::to_string(CFErrorGetCode(error)));
|
||||||
|
macstd::cfstring domain(CFErrorGetDomain(error));
|
||||||
|
if (domain && CFStringGetLength(domain) > 0) {
|
||||||
|
auto str = CFStringGetCStringPtr(domain, kCFStringEncodingUTF8);
|
||||||
|
if (str)
|
||||||
|
msg += std::string(", domain ") + str;
|
||||||
|
}
|
||||||
|
return msg;
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "common.hpp"
|
#include "common.hpp"
|
||||||
|
#include "CoreFoundation.hpp"
|
||||||
#import <Security/Security.h>
|
#import <Security/Security.h>
|
||||||
|
|
||||||
namespace macstd
|
namespace macstd
|
||||||
@ -19,7 +20,7 @@ namespace macstd
|
|||||||
///
|
///
|
||||||
/// Constructs an exception
|
/// Constructs an exception
|
||||||
///
|
///
|
||||||
/// \param[in] num WinSock2 error code
|
/// \param[in] num Security error code
|
||||||
///
|
///
|
||||||
security_runtime_error(error_type num) : num_runtime_error<OSStatus>(num, message(num))
|
security_runtime_error(error_type num) : num_runtime_error<OSStatus>(num, message(num))
|
||||||
{
|
{
|
||||||
@ -28,7 +29,7 @@ namespace macstd
|
|||||||
///
|
///
|
||||||
/// Constructs an exception
|
/// Constructs an exception
|
||||||
///
|
///
|
||||||
/// \param[in] num WinSock2 error code
|
/// \param[in] num Security error code
|
||||||
/// \param[in] msg Error message
|
/// \param[in] msg Error message
|
||||||
///
|
///
|
||||||
security_runtime_error(error_type num, const std::string &msg) : num_runtime_error<OSStatus>(num, msg + ": " + message(num))
|
security_runtime_error(error_type num, const std::string &msg) : num_runtime_error<OSStatus>(num, msg + ": " + message(num))
|
||||||
@ -38,7 +39,7 @@ namespace macstd
|
|||||||
///
|
///
|
||||||
/// Constructs an exception
|
/// Constructs an exception
|
||||||
///
|
///
|
||||||
/// \param[in] num WinSock2 error code
|
/// \param[in] num Security error code
|
||||||
/// \param[in] msg Error message
|
/// \param[in] msg Error message
|
||||||
///
|
///
|
||||||
security_runtime_error(error_type num, const char *msg) : num_runtime_error<OSStatus>(num, std::string(msg) + ": " + message(num))
|
security_runtime_error(error_type num, const char *msg) : num_runtime_error<OSStatus>(num, std::string(msg) + ": " + message(num))
|
||||||
@ -59,16 +60,13 @@ namespace macstd
|
|||||||
case errAuthorizationDenied: return "Authorization was denied";
|
case errAuthorizationDenied: return "Authorization was denied";
|
||||||
case errAuthorizationInteractionNotAllowed: return "User interaction not allowed for authorization";
|
case errAuthorizationInteractionNotAllowed: return "User interaction not allowed for authorization";
|
||||||
}
|
}
|
||||||
auto cfstr = SecCopyErrorMessageString(num, NULL);
|
cfstring cfstr(SecCopyErrorMessageString(num, NULL));
|
||||||
if (!cfstr)
|
if (!cfstr)
|
||||||
return "Security Framework error " + std::to_string(num);
|
return "Security Framework error " + std::to_string(num);
|
||||||
auto ptr = CFStringGetCStringPtr(cfstr, kCFStringEncodingUTF8);
|
auto ptr = CFStringGetCStringPtr(cfstr, kCFStringEncodingUTF8);
|
||||||
if (!ptr) {
|
if (!ptr)
|
||||||
CFRelease(cfstr);
|
|
||||||
return "Security Framework error " + std::to_string(num);
|
return "Security Framework error " + std::to_string(num);
|
||||||
}
|
|
||||||
std::string str(ptr);
|
std::string str(ptr);
|
||||||
CFRelease(cfstr);
|
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user