CoreFoundation: extend cfstring

Signed-off-by: Simon Rozman <simon@rozman.si>
This commit is contained in:
Simon Rozman 2025-06-23 18:50:25 +02:00
parent c40391e3bb
commit abf371c09f
2 changed files with 64 additions and 18 deletions

View File

@ -44,9 +44,54 @@ namespace macstd {
using cfdictionary = cfobject<CFDictionaryRef>; using cfdictionary = cfobject<CFDictionaryRef>;
using cferror = cfobject<CFErrorRef>; using cferror = cfobject<CFErrorRef>;
using cfreadstream = cfobject<CFReadStreamRef>; using cfreadstream = cfobject<CFReadStreamRef>;
using cfstring = cfobject<CFStringRef>;
using cfurl = cfobject<CFURLRef>; using cfurl = cfobject<CFURLRef>;
template <typename TR = std::char_traits<char>, typename A = std::allocator<char>>
void strcat(std::basic_string<char, TR, A>& str, CFStringRef h, CFStringEncoding encoding = kCFStringEncodingUTF8)
{
auto ptr = CFStringGetCStringPtr(h, encoding);
if (ptr) {
str += ptr;
return;
}
char buf[0x200];
if (CFStringGetCString(h, buf, sizeof(buf)/sizeof(*buf), encoding)) {
str += buf;
return;
}
auto n = str.size();
auto m = CFStringGetMaximumSizeForEncoding(CFStringGetLength(h), encoding);
str.resize(n + m);
if (!CFStringGetCString(h, &str[n], m, encoding)) [[unlikely]]
throw std::runtime_error("CFStringGetCString failed");
str.resize(n + strlen(&str[n]));
}
template <typename TR = std::char_traits<char>, typename A = std::allocator<char>>
void strcpy(std::basic_string<char, TR, A>& str, CFStringRef h, CFStringEncoding encoding = kCFStringEncodingUTF8)
{
str.clear();
strcat(str, h, encoding);
}
///
/// Core Foundation string
///
class cfstring : public cfobject<CFStringRef>
{
public:
cfstring(CFStringRef h) : cfobject<CFStringRef>(h) {}
cfstring(const char *s) : cfobject<CFStringRef>(CFStringCreateWithCString(kCFAllocatorDefault, s, kCFStringEncodingUTF8))
{
if (!valid()) [[unlikely]]
throw std::bad_alloc();
}
template <typename TR, typename A>
cfstring(const std::basic_string<char, TR, A> &s) : cfstring(s.c_str()) {}
};
/// ///
/// Core Foundation runtime error /// Core Foundation runtime error
/// ///
@ -126,18 +171,18 @@ namespace macstd {
/// ///
static std::string message(CFErrorRef error) static std::string message(CFErrorRef error)
{ {
macstd::cfstring description(CFErrorCopyDescription(error)); std::string msg;
if (description.valid() && CFStringGetLength(description) > 0) { cfstring cfstr(CFErrorCopyDescription(error));
auto str = CFStringGetCStringPtr(description, kCFStringEncodingUTF8); if (cfstr.valid() && CFStringGetLength(cfstr) > 0) {
if (str) strcpy(msg, cfstr, kCFStringEncodingUTF8);
return str; } else {
msg = "Core Foundation error ";
msg += std::to_string(CFErrorGetCode(error));
} }
std::string msg("Core Foundation error " + std::to_string(CFErrorGetCode(error))); cfstring domain(CFErrorGetDomain(error));
macstd::cfstring domain(CFErrorGetDomain(error));
if (domain.valid() && CFStringGetLength(domain) > 0) { if (domain.valid() && CFStringGetLength(domain) > 0) {
auto str = CFStringGetCStringPtr(domain, kCFStringEncodingUTF8); msg += ", domain ";
if (str) strcat(msg, domain, kCFStringEncodingUTF8);
msg += std::string(", domain ") + str;
} }
return msg; return msg;
} }

View File

@ -62,14 +62,15 @@ 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";
} }
std::string msg;
cfstring cfstr(SecCopyErrorMessageString(num, NULL)); cfstring cfstr(SecCopyErrorMessageString(num, NULL));
if (!cfstr.valid()) if (cfstr.valid() && CFStringGetLength(cfstr) > 0) {
return "Security Framework error " + std::to_string(num); strcpy(msg, cfstr, kCFStringEncodingUTF8);
auto ptr = CFStringGetCStringPtr(cfstr, kCFStringEncodingUTF8); } else {
if (!ptr) msg = "Security Framework error ";
return "Security Framework error " + std::to_string(num); msg += std::to_string(num);
std::string str(ptr); }
return str; return msg;
} }
}; };