Convert from CFURLRef or CFStringRef to std::string

13.1k views Asked by At

How can I convert a CFURLRef to a C++ std::string?

I also can convert from the CFURLRef to a CFStringRef by:

CFStringRef CFURLGetString ( CFURLRef anURL );

But now I have the same problem. How can I convert the CFStringRef to a std::string?

4

There are 4 answers

0
Michael Dautermann On BEST ANSWER

A CFStringRef is toll free bridged to a NSString object, so if you're using Cocoa or Objective C in any way, converting is super simple:

NSString *foo = (NSString *)yourOriginalCFStringRef;
std::string *bar = new std::string([foo UTF8String]);

More detail can be found here.

Now, since you didn't tag this question with Cocoa or Objective-C, I'm guessing you don't want to use the Objective-C solution.

In this case, you need to get the C string equivalent from your CFStringRef:

const CFIndex kCStringSize = 128; 
char temporaryCString[kCStringSize];
bzero(temporaryCString,kCStringSize);
CFStringGetCString(yourStringRef, temporaryCString, kCStringSize, kCFStringEncodingUTF8);
std::string *bar = new std::string(temporaryCString);

I didn't do any error checking on this code and you may need to null terminate the string fetched via CFStringGetCString (I tried to mitigate that by doing bzero).

0
Marek R On

Here is my implementation of conversion function

std::string stdStringFromCF(CFStringRef s)
{
    if (auto fastCString = CFStringGetCStringPtr(s, kCFStringEncodingUTF8))
    {
        return std::string(fastCString);
    }
    auto utf16length = CFStringGetLength(s);
    auto maxUtf8len = CFStringGetMaximumSizeForEncoding(utf16length, kCFStringEncodingUTF8);
    std::string converted(maxUtf8len, '\0');

    CFStringGetCString(s, converted.data(), maxUtf8len, kCFStringEncodingUTF8);
    converted.resize(std::strlen(converted.data()));

    return converted;
}

Didn't test that yet.

1
Alan T. On

This function is possibly the most simple solution:

const char * CFStringGetCStringPtr ( CFStringRef theString, CFStringEncoding encoding );

Of course, there is a ctr for std::string(char*) which gives you this one-liner for the conversion:

std::string str(CFStringGetCStringPtr(CFURLGetString(anUrl),kCFStringEncodingUTF8));
1
MultiColourPixel On

The safest way of achieving this would be:

CFIndex bufferSize = CFStringGetLength(cfString) + 1; // The +1 is for having space for the string to be NUL terminated
char buffer[bufferSize];

// CFStringGetCString is documented to return a false if the buffer is too small 
// (which shouldn't happen in this example) or if the conversion generally fails    
if (CFStringGetCString(cfString, buffer, bufferSize, kCFStringEncodingUTF8))
{
    std::string cppString (buffer);
}

The CFStringGetCString is not documented to return a NULL like CFStringGetCStringPtr can.

Make sure that you are using the correct CFStringEncoding type. I think that UTF8 encoding should be safe for most things.

You can check out Apple's documentation about CFStringGetCString at https://developer.apple.com/reference/corefoundation/1542721-cfstringgetcstring?language=objc