106 lines
2.5 KiB
C++
106 lines
2.5 KiB
C++
/*
|
|
SPDX-License-Identifier: MIT
|
|
Copyright © 2023-2025 Amebis
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include "common.hpp"
|
|
#include <CoreFoundation/CoreFoundation.h>
|
|
#include <memory>
|
|
#include <system_error>
|
|
|
|
namespace macstd {
|
|
///
|
|
/// IOKit handle wrapper class
|
|
///
|
|
template <typename T, const T INVAL>
|
|
class cf_object : public handle<T, INVAL>
|
|
{
|
|
MACSTD_HANDLE_IMPL(cf_object, T, INVAL)
|
|
|
|
public:
|
|
///
|
|
/// Releases a Core Foundation object
|
|
///
|
|
/// \sa [CFRelease function](https://developer.apple.com/documentation/corefoundation/1521153-cfrelease)
|
|
///
|
|
virtual ~cf_object()
|
|
{
|
|
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 cfarray = cf_object<CFArrayRef, static_cast<CFArrayRef>(NULL)>;
|
|
using cferror = cf_object<CFErrorRef, static_cast<CFErrorRef>(NULL)>;
|
|
|
|
///
|
|
/// Core Foundation runtime error
|
|
///
|
|
class cf_runtime_error : public num_runtime_error<CFIndex>
|
|
{
|
|
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.valid() && 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.valid() && CFStringGetLength(domain) > 0) {
|
|
auto str = CFStringGetCStringPtr(domain, kCFStringEncodingUTF8);
|
|
if (str)
|
|
msg += std::string(", domain ") + str;
|
|
}
|
|
return msg;
|
|
}
|
|
};
|
|
}
|