CFString.cpp   [plain text]


//----------------------------------------------------------------------
//  CFString.cpp
//  debugserver
//
//  Created by Greg Clayton on 1/16/08.
//  Copyright (c) 2005-2011 Apple Inc. All rights reserved.
//
//----------------------------------------------------------------------

#include "CFString.h"
#include <string>
#include <glob.h>

static const char* 
CreatePathByExpandingTildePath(const char* path, std::string &expanded_path)
{
    glob_t globbuf;
    if (glob(path, GLOB_TILDE, NULL, &globbuf) == 0)
    {
		expanded_path = globbuf.gl_pathv[0];
        globfree(&globbuf);
    }
	else
		expanded_path.clear();

    return expanded_path.c_str();
}

//----------------------------------------------------------------------
// CFString constructor
//----------------------------------------------------------------------
CFString::CFString(CFStringRef s) : 
    CFReleaser<CFStringRef> (s)
{
}

//----------------------------------------------------------------------
// CFString copy constructor
//----------------------------------------------------------------------
CFString::CFString(const CFString& rhs) :
    CFReleaser<CFStringRef> (rhs)
{
	
}

//----------------------------------------------------------------------
// CFString copy constructor
//----------------------------------------------------------------------
CFString& 
CFString::operator=(const CFString& rhs)
{
	if (this != &rhs)
		*this = rhs;
    return *this;
}

CFString::CFString (const char *cstr, CFStringEncoding cstr_encoding) :
    CFReleaser<CFStringRef> ()
{
	if (cstr && cstr[0])
	{
		reset(::CFStringCreateWithCString(kCFAllocatorDefault, cstr, cstr_encoding));
	}
}

//----------------------------------------------------------------------
// Destructor
//----------------------------------------------------------------------
CFString::~CFString()
{
}

const char *
CFString::GetFileSystemRepresentation(std::string& s)
{
	return CFString::FileSystemRepresentation(get(), s);
}

CFStringRef
CFString::SetFileSystemRepresentation (const char *path)
{
	CFStringRef new_value = NULL;
    if (path && path[0])
        new_value = ::CFStringCreateWithFileSystemRepresentation (kCFAllocatorDefault, path);
    reset(new_value);
    return get();
}


CFStringRef
CFString::SetFileSystemRepresentationFromCFType (CFTypeRef cf_type)
{
	CFStringRef new_value = NULL;
	if (cf_type != NULL)
	{
		CFTypeID cf_type_id = ::CFGetTypeID(cf_type);

		if (cf_type_id == ::CFStringGetTypeID())
		{
			// Retain since we are using the existing object
			new_value = (CFStringRef)::CFRetain(cf_type);
		}
		else if (cf_type_id == ::CFURLGetTypeID())
		{
			new_value = ::CFURLCopyFileSystemPath((CFURLRef)cf_type, kCFURLPOSIXPathStyle);
		}
	}
	reset(new_value);
	return get();
}

CFStringRef
CFString::SetFileSystemRepresentationAndExpandTilde (const char *path)
{
	std::string expanded_path;
	if (CreatePathByExpandingTildePath(path, expanded_path))
		SetFileSystemRepresentation(expanded_path.c_str());
	else
		reset();
    return get();
}

const char *
CFString::UTF8(std::string& str)
{
	return CFString::UTF8(get(), str);
}

// Static function that puts a copy of the UTF8 contents of CF_STR into STR
// and returns the C string pointer that is contained in STR when successful, else
// NULL is returned. This allows the std::string parameter to own the extracted string,
// and also allows that string to be returned as a C string pointer that can be used.

const char *
CFString::UTF8 (CFStringRef cf_str, std::string& str)
{
	if (cf_str)
	{
		const CFStringEncoding encoding = kCFStringEncodingUTF8;
		CFIndex max_utf8_str_len = CFStringGetLength (cf_str);
		max_utf8_str_len = CFStringGetMaximumSizeForEncoding (max_utf8_str_len, encoding);
		if (max_utf8_str_len > 0)
		{
			str.resize(max_utf8_str_len);
			if (!str.empty())
			{
				if (CFStringGetCString (cf_str, &str[0], str.size(), encoding))
				{
					str.resize(strlen(str.c_str()));
					return str.c_str();
				}
			}
		}
	}
    return NULL;
}

// Static function that puts a copy of the file system representation of CF_STR
// into STR and returns the C string pointer that is contained in STR when 
// successful, else NULL is returned. This allows the std::string parameter 
// to own the extracted string, and also allows that string to be returned as
// a C string pointer that can be used.

const char *
CFString::FileSystemRepresentation (CFStringRef cf_str, std::string& str)
{
	if (cf_str)
	{
        CFIndex max_length = ::CFStringGetMaximumSizeOfFileSystemRepresentation (cf_str);
        if (max_length > 0)
        {
            str.resize(max_length);
            if (!str.empty())
            {
                if (::CFStringGetFileSystemRepresentation (cf_str, &str[0], str.size()))
                {
					str.erase(::strlen(str.c_str()));
				    return str.c_str();
				}
            }
        }
	}
	str.erase();
    return NULL;
}


CFIndex
CFString::GetLength() const
{
    CFStringRef str = get();
    if (str)
        return CFStringGetLength (str);
    return 0;
}