130fdc8d8SChris Lattner //===-- CFString.cpp --------------------------------------------*- C++ -*-===// 230fdc8d8SChris Lattner // 330fdc8d8SChris Lattner // The LLVM Compiler Infrastructure 430fdc8d8SChris Lattner // 530fdc8d8SChris Lattner // This file is distributed under the University of Illinois Open Source 630fdc8d8SChris Lattner // License. See LICENSE.TXT for details. 730fdc8d8SChris Lattner // 830fdc8d8SChris Lattner //===----------------------------------------------------------------------===// 930fdc8d8SChris Lattner // 1030fdc8d8SChris Lattner // Created by Greg Clayton on 1/16/08. 1130fdc8d8SChris Lattner // 1230fdc8d8SChris Lattner //===----------------------------------------------------------------------===// 1330fdc8d8SChris Lattner 1430fdc8d8SChris Lattner #include "CFString.h" 1530fdc8d8SChris Lattner #include <glob.h> 16*b9c1b51eSKate Stone #include <string> 1730fdc8d8SChris Lattner 1830fdc8d8SChris Lattner //---------------------------------------------------------------------- 1930fdc8d8SChris Lattner // CFString constructor 2030fdc8d8SChris Lattner //---------------------------------------------------------------------- 21*b9c1b51eSKate Stone CFString::CFString(CFStringRef s) : CFReleaser<CFStringRef>(s) {} 2230fdc8d8SChris Lattner 2330fdc8d8SChris Lattner //---------------------------------------------------------------------- 2430fdc8d8SChris Lattner // CFString copy constructor 2530fdc8d8SChris Lattner //---------------------------------------------------------------------- 26*b9c1b51eSKate Stone CFString::CFString(const CFString &rhs) : CFReleaser<CFStringRef>(rhs) {} 2730fdc8d8SChris Lattner 2830fdc8d8SChris Lattner //---------------------------------------------------------------------- 2930fdc8d8SChris Lattner // CFString copy constructor 3030fdc8d8SChris Lattner //---------------------------------------------------------------------- 31*b9c1b51eSKate Stone CFString &CFString::operator=(const CFString &rhs) { 3230fdc8d8SChris Lattner if (this != &rhs) 3330fdc8d8SChris Lattner *this = rhs; 3430fdc8d8SChris Lattner return *this; 3530fdc8d8SChris Lattner } 3630fdc8d8SChris Lattner 37*b9c1b51eSKate Stone CFString::CFString(const char *cstr, CFStringEncoding cstr_encoding) 38*b9c1b51eSKate Stone : CFReleaser<CFStringRef>() { 39*b9c1b51eSKate Stone if (cstr && cstr[0]) { 40*b9c1b51eSKate Stone reset( 41*b9c1b51eSKate Stone ::CFStringCreateWithCString(kCFAllocatorDefault, cstr, cstr_encoding)); 4230fdc8d8SChris Lattner } 4330fdc8d8SChris Lattner } 4430fdc8d8SChris Lattner 4530fdc8d8SChris Lattner //---------------------------------------------------------------------- 4630fdc8d8SChris Lattner // Destructor 4730fdc8d8SChris Lattner //---------------------------------------------------------------------- 48*b9c1b51eSKate Stone CFString::~CFString() {} 4930fdc8d8SChris Lattner 50*b9c1b51eSKate Stone const char *CFString::GetFileSystemRepresentation(std::string &s) { 5130fdc8d8SChris Lattner return CFString::FileSystemRepresentation(get(), s); 5230fdc8d8SChris Lattner } 5330fdc8d8SChris Lattner 54*b9c1b51eSKate Stone CFStringRef CFString::SetFileSystemRepresentation(const char *path) { 5530fdc8d8SChris Lattner CFStringRef new_value = NULL; 5630fdc8d8SChris Lattner if (path && path[0]) 57*b9c1b51eSKate Stone new_value = 58*b9c1b51eSKate Stone ::CFStringCreateWithFileSystemRepresentation(kCFAllocatorDefault, path); 5930fdc8d8SChris Lattner reset(new_value); 6030fdc8d8SChris Lattner return get(); 6130fdc8d8SChris Lattner } 6230fdc8d8SChris Lattner 63*b9c1b51eSKate Stone CFStringRef CFString::SetFileSystemRepresentationFromCFType(CFTypeRef cf_type) { 6430fdc8d8SChris Lattner CFStringRef new_value = NULL; 65*b9c1b51eSKate Stone if (cf_type != NULL) { 6630fdc8d8SChris Lattner CFTypeID cf_type_id = ::CFGetTypeID(cf_type); 6730fdc8d8SChris Lattner 68*b9c1b51eSKate Stone if (cf_type_id == ::CFStringGetTypeID()) { 6930fdc8d8SChris Lattner // Retain since we are using the existing object 7030fdc8d8SChris Lattner new_value = (CFStringRef)::CFRetain(cf_type); 71*b9c1b51eSKate Stone } else if (cf_type_id == ::CFURLGetTypeID()) { 72*b9c1b51eSKate Stone new_value = 73*b9c1b51eSKate Stone ::CFURLCopyFileSystemPath((CFURLRef)cf_type, kCFURLPOSIXPathStyle); 7430fdc8d8SChris Lattner } 7530fdc8d8SChris Lattner } 7630fdc8d8SChris Lattner reset(new_value); 7730fdc8d8SChris Lattner return get(); 7830fdc8d8SChris Lattner } 7930fdc8d8SChris Lattner 8030fdc8d8SChris Lattner CFStringRef 81*b9c1b51eSKate Stone CFString::SetFileSystemRepresentationAndExpandTilde(const char *path) { 8230fdc8d8SChris Lattner std::string expanded_path; 8330fdc8d8SChris Lattner if (CFString::GlobPath(path, expanded_path)) 8430fdc8d8SChris Lattner SetFileSystemRepresentation(expanded_path.c_str()); 8530fdc8d8SChris Lattner else 8630fdc8d8SChris Lattner reset(); 8730fdc8d8SChris Lattner return get(); 8830fdc8d8SChris Lattner } 8930fdc8d8SChris Lattner 90*b9c1b51eSKate Stone const char *CFString::UTF8(std::string &str) { 9130fdc8d8SChris Lattner return CFString::UTF8(get(), str); 9230fdc8d8SChris Lattner } 9330fdc8d8SChris Lattner 9430fdc8d8SChris Lattner // Static function that puts a copy of the UTF8 contents of CF_STR into STR 95*b9c1b51eSKate Stone // and returns the C string pointer that is contained in STR when successful, 96*b9c1b51eSKate Stone // else 97*b9c1b51eSKate Stone // NULL is returned. This allows the std::string parameter to own the extracted 98*b9c1b51eSKate Stone // string, 99*b9c1b51eSKate Stone // and also allows that string to be returned as a C string pointer that can be 100*b9c1b51eSKate Stone // used. 10130fdc8d8SChris Lattner 102*b9c1b51eSKate Stone const char *CFString::UTF8(CFStringRef cf_str, std::string &str) { 103*b9c1b51eSKate Stone if (cf_str) { 10430fdc8d8SChris Lattner const CFStringEncoding encoding = kCFStringEncodingUTF8; 10530fdc8d8SChris Lattner CFIndex max_utf8_str_len = CFStringGetLength(cf_str); 106*b9c1b51eSKate Stone max_utf8_str_len = 107*b9c1b51eSKate Stone CFStringGetMaximumSizeForEncoding(max_utf8_str_len, encoding); 108*b9c1b51eSKate Stone if (max_utf8_str_len > 0) { 10930fdc8d8SChris Lattner str.resize(max_utf8_str_len); 110*b9c1b51eSKate Stone if (!str.empty()) { 111*b9c1b51eSKate Stone if (CFStringGetCString(cf_str, &str[0], str.size(), encoding)) { 11230fdc8d8SChris Lattner str.resize(strlen(str.c_str())); 11330fdc8d8SChris Lattner return str.c_str(); 11430fdc8d8SChris Lattner } 11530fdc8d8SChris Lattner } 11630fdc8d8SChris Lattner } 11730fdc8d8SChris Lattner } 11830fdc8d8SChris Lattner return NULL; 11930fdc8d8SChris Lattner } 12030fdc8d8SChris Lattner 12130fdc8d8SChris Lattner // Static function that puts a copy of the file system representation of CF_STR 12230fdc8d8SChris Lattner // into STR and returns the C string pointer that is contained in STR when 12330fdc8d8SChris Lattner // successful, else NULL is returned. This allows the std::string parameter 12430fdc8d8SChris Lattner // to own the extracted string, and also allows that string to be returned as 12530fdc8d8SChris Lattner // a C string pointer that can be used. 12630fdc8d8SChris Lattner 127*b9c1b51eSKate Stone const char *CFString::FileSystemRepresentation(CFStringRef cf_str, 128*b9c1b51eSKate Stone std::string &str) { 129*b9c1b51eSKate Stone if (cf_str) { 130*b9c1b51eSKate Stone CFIndex max_length = 131*b9c1b51eSKate Stone ::CFStringGetMaximumSizeOfFileSystemRepresentation(cf_str); 132*b9c1b51eSKate Stone if (max_length > 0) { 13330fdc8d8SChris Lattner str.resize(max_length); 134*b9c1b51eSKate Stone if (!str.empty()) { 135*b9c1b51eSKate Stone if (::CFStringGetFileSystemRepresentation(cf_str, &str[0], 136*b9c1b51eSKate Stone str.size())) { 13730fdc8d8SChris Lattner str.erase(::strlen(str.c_str())); 13830fdc8d8SChris Lattner return str.c_str(); 13930fdc8d8SChris Lattner } 14030fdc8d8SChris Lattner } 14130fdc8d8SChris Lattner } 14230fdc8d8SChris Lattner } 14330fdc8d8SChris Lattner str.erase(); 14430fdc8d8SChris Lattner return NULL; 14530fdc8d8SChris Lattner } 14630fdc8d8SChris Lattner 147*b9c1b51eSKate Stone CFIndex CFString::GetLength() const { 14830fdc8d8SChris Lattner CFStringRef str = get(); 14930fdc8d8SChris Lattner if (str) 15030fdc8d8SChris Lattner return CFStringGetLength(str); 15130fdc8d8SChris Lattner return 0; 15230fdc8d8SChris Lattner } 15330fdc8d8SChris Lattner 154*b9c1b51eSKate Stone const char *CFString::GlobPath(const char *path, std::string &expanded_path) { 15530fdc8d8SChris Lattner glob_t globbuf; 156*b9c1b51eSKate Stone if (::glob(path, GLOB_TILDE, NULL, &globbuf) == 0) { 15730fdc8d8SChris Lattner expanded_path = globbuf.gl_pathv[0]; 15830fdc8d8SChris Lattner ::globfree(&globbuf); 159*b9c1b51eSKate Stone } else 16030fdc8d8SChris Lattner expanded_path.clear(); 16130fdc8d8SChris Lattner 16230fdc8d8SChris Lattner return expanded_path.c_str(); 16330fdc8d8SChris Lattner } 164