blob: 81a96b824999c0656ffb5aa1ed76fec2be5c1fd1 [file] [log] [blame]
//===-- CFCString.cpp -------------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "CFCString.h"
#include <string>
#include <glob.h>
//----------------------------------------------------------------------
// CFCString constructor
//----------------------------------------------------------------------
CFCString::CFCString(CFStringRef s) :
CFCReleaser<CFStringRef> (s)
{
}
//----------------------------------------------------------------------
// CFCString copy constructor
//----------------------------------------------------------------------
CFCString::CFCString(const CFCString& rhs) :
CFCReleaser<CFStringRef> (rhs)
{
}
//----------------------------------------------------------------------
// CFCString copy constructor
//----------------------------------------------------------------------
CFCString&
CFCString::operator=(const CFCString& rhs)
{
if (this != &rhs)
*this = rhs;
return *this;
}
CFCString::CFCString (const char *cstr, CFStringEncoding cstr_encoding) :
CFCReleaser<CFStringRef> ()
{
if (cstr && cstr[0])
{
reset(::CFStringCreateWithCString(kCFAllocatorDefault, cstr, cstr_encoding));
}
}
//----------------------------------------------------------------------
// Destructor
//----------------------------------------------------------------------
CFCString::~CFCString()
{
}
const char *
CFCString::GetFileSystemRepresentation(std::string& s)
{
return CFCString::FileSystemRepresentation(get(), s);
}
CFStringRef
CFCString::SetFileSystemRepresentation (const char *path)
{
CFStringRef new_value = NULL;
if (path && path[0])
new_value = ::CFStringCreateWithFileSystemRepresentation (kCFAllocatorDefault, path);
reset(new_value);
return get();
}
CFStringRef
CFCString::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
CFCString::SetFileSystemRepresentationAndExpandTilde (const char *path)
{
std::string expanded_path;
if (CFCString::ExpandTildeInPath(path, expanded_path))
SetFileSystemRepresentation(expanded_path.c_str());
else
reset();
return get();
}
const char *
CFCString::UTF8(std::string& str)
{
return CFCString::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 *
CFCString::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;
}
const char*
CFCString::ExpandTildeInPath(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();
}
// 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 *
CFCString::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
CFCString::GetLength() const
{
CFStringRef str = get();
if (str)
return CFStringGetLength (str);
return 0;
}