1*30fdc8d8SChris Lattner //===-- CFString.cpp --------------------------------------------*- C++ -*-===// 2*30fdc8d8SChris Lattner // 3*30fdc8d8SChris Lattner // The LLVM Compiler Infrastructure 4*30fdc8d8SChris Lattner // 5*30fdc8d8SChris Lattner // This file is distributed under the University of Illinois Open Source 6*30fdc8d8SChris Lattner // License. See LICENSE.TXT for details. 7*30fdc8d8SChris Lattner // 8*30fdc8d8SChris Lattner //===----------------------------------------------------------------------===// 9*30fdc8d8SChris Lattner // 10*30fdc8d8SChris Lattner // Created by Greg Clayton on 1/16/08. 11*30fdc8d8SChris Lattner // 12*30fdc8d8SChris Lattner //===----------------------------------------------------------------------===// 13*30fdc8d8SChris Lattner 14*30fdc8d8SChris Lattner #include "CFString.h" 15*30fdc8d8SChris Lattner #include <string> 16*30fdc8d8SChris Lattner #include <glob.h> 17*30fdc8d8SChris Lattner 18*30fdc8d8SChris Lattner //---------------------------------------------------------------------- 19*30fdc8d8SChris Lattner // CFString constructor 20*30fdc8d8SChris Lattner //---------------------------------------------------------------------- 21*30fdc8d8SChris Lattner CFString::CFString(CFStringRef s) : 22*30fdc8d8SChris Lattner CFReleaser<CFStringRef> (s) 23*30fdc8d8SChris Lattner { 24*30fdc8d8SChris Lattner } 25*30fdc8d8SChris Lattner 26*30fdc8d8SChris Lattner //---------------------------------------------------------------------- 27*30fdc8d8SChris Lattner // CFString copy constructor 28*30fdc8d8SChris Lattner //---------------------------------------------------------------------- 29*30fdc8d8SChris Lattner CFString::CFString(const CFString& rhs) : 30*30fdc8d8SChris Lattner CFReleaser<CFStringRef> (rhs) 31*30fdc8d8SChris Lattner { 32*30fdc8d8SChris Lattner 33*30fdc8d8SChris Lattner } 34*30fdc8d8SChris Lattner 35*30fdc8d8SChris Lattner //---------------------------------------------------------------------- 36*30fdc8d8SChris Lattner // CFString copy constructor 37*30fdc8d8SChris Lattner //---------------------------------------------------------------------- 38*30fdc8d8SChris Lattner CFString& 39*30fdc8d8SChris Lattner CFString::operator=(const CFString& rhs) 40*30fdc8d8SChris Lattner { 41*30fdc8d8SChris Lattner if (this != &rhs) 42*30fdc8d8SChris Lattner *this = rhs; 43*30fdc8d8SChris Lattner return *this; 44*30fdc8d8SChris Lattner } 45*30fdc8d8SChris Lattner 46*30fdc8d8SChris Lattner CFString::CFString (const char *cstr, CFStringEncoding cstr_encoding) : 47*30fdc8d8SChris Lattner CFReleaser<CFStringRef> () 48*30fdc8d8SChris Lattner { 49*30fdc8d8SChris Lattner if (cstr && cstr[0]) 50*30fdc8d8SChris Lattner { 51*30fdc8d8SChris Lattner reset(::CFStringCreateWithCString(kCFAllocatorDefault, cstr, cstr_encoding)); 52*30fdc8d8SChris Lattner } 53*30fdc8d8SChris Lattner } 54*30fdc8d8SChris Lattner 55*30fdc8d8SChris Lattner //---------------------------------------------------------------------- 56*30fdc8d8SChris Lattner // Destructor 57*30fdc8d8SChris Lattner //---------------------------------------------------------------------- 58*30fdc8d8SChris Lattner CFString::~CFString() 59*30fdc8d8SChris Lattner { 60*30fdc8d8SChris Lattner } 61*30fdc8d8SChris Lattner 62*30fdc8d8SChris Lattner const char * 63*30fdc8d8SChris Lattner CFString::GetFileSystemRepresentation(std::string& s) 64*30fdc8d8SChris Lattner { 65*30fdc8d8SChris Lattner return CFString::FileSystemRepresentation(get(), s); 66*30fdc8d8SChris Lattner } 67*30fdc8d8SChris Lattner 68*30fdc8d8SChris Lattner CFStringRef 69*30fdc8d8SChris Lattner CFString::SetFileSystemRepresentation (const char *path) 70*30fdc8d8SChris Lattner { 71*30fdc8d8SChris Lattner CFStringRef new_value = NULL; 72*30fdc8d8SChris Lattner if (path && path[0]) 73*30fdc8d8SChris Lattner new_value = ::CFStringCreateWithFileSystemRepresentation (kCFAllocatorDefault, path); 74*30fdc8d8SChris Lattner reset(new_value); 75*30fdc8d8SChris Lattner return get(); 76*30fdc8d8SChris Lattner } 77*30fdc8d8SChris Lattner 78*30fdc8d8SChris Lattner 79*30fdc8d8SChris Lattner CFStringRef 80*30fdc8d8SChris Lattner CFString::SetFileSystemRepresentationFromCFType (CFTypeRef cf_type) 81*30fdc8d8SChris Lattner { 82*30fdc8d8SChris Lattner CFStringRef new_value = NULL; 83*30fdc8d8SChris Lattner if (cf_type != NULL) 84*30fdc8d8SChris Lattner { 85*30fdc8d8SChris Lattner CFTypeID cf_type_id = ::CFGetTypeID(cf_type); 86*30fdc8d8SChris Lattner 87*30fdc8d8SChris Lattner if (cf_type_id == ::CFStringGetTypeID()) 88*30fdc8d8SChris Lattner { 89*30fdc8d8SChris Lattner // Retain since we are using the existing object 90*30fdc8d8SChris Lattner new_value = (CFStringRef)::CFRetain(cf_type); 91*30fdc8d8SChris Lattner } 92*30fdc8d8SChris Lattner else if (cf_type_id == ::CFURLGetTypeID()) 93*30fdc8d8SChris Lattner { 94*30fdc8d8SChris Lattner new_value = ::CFURLCopyFileSystemPath((CFURLRef)cf_type, kCFURLPOSIXPathStyle); 95*30fdc8d8SChris Lattner } 96*30fdc8d8SChris Lattner } 97*30fdc8d8SChris Lattner reset(new_value); 98*30fdc8d8SChris Lattner return get(); 99*30fdc8d8SChris Lattner } 100*30fdc8d8SChris Lattner 101*30fdc8d8SChris Lattner CFStringRef 102*30fdc8d8SChris Lattner CFString::SetFileSystemRepresentationAndExpandTilde (const char *path) 103*30fdc8d8SChris Lattner { 104*30fdc8d8SChris Lattner std::string expanded_path; 105*30fdc8d8SChris Lattner if (CFString::GlobPath(path, expanded_path)) 106*30fdc8d8SChris Lattner SetFileSystemRepresentation(expanded_path.c_str()); 107*30fdc8d8SChris Lattner else 108*30fdc8d8SChris Lattner reset(); 109*30fdc8d8SChris Lattner return get(); 110*30fdc8d8SChris Lattner } 111*30fdc8d8SChris Lattner 112*30fdc8d8SChris Lattner const char * 113*30fdc8d8SChris Lattner CFString::UTF8(std::string& str) 114*30fdc8d8SChris Lattner { 115*30fdc8d8SChris Lattner return CFString::UTF8(get(), str); 116*30fdc8d8SChris Lattner } 117*30fdc8d8SChris Lattner 118*30fdc8d8SChris Lattner // Static function that puts a copy of the UTF8 contents of CF_STR into STR 119*30fdc8d8SChris Lattner // and returns the C string pointer that is contained in STR when successful, else 120*30fdc8d8SChris Lattner // NULL is returned. This allows the std::string parameter to own the extracted string, 121*30fdc8d8SChris Lattner // and also allows that string to be returned as a C string pointer that can be used. 122*30fdc8d8SChris Lattner 123*30fdc8d8SChris Lattner const char * 124*30fdc8d8SChris Lattner CFString::UTF8 (CFStringRef cf_str, std::string& str) 125*30fdc8d8SChris Lattner { 126*30fdc8d8SChris Lattner if (cf_str) 127*30fdc8d8SChris Lattner { 128*30fdc8d8SChris Lattner const CFStringEncoding encoding = kCFStringEncodingUTF8; 129*30fdc8d8SChris Lattner CFIndex max_utf8_str_len = CFStringGetLength (cf_str); 130*30fdc8d8SChris Lattner max_utf8_str_len = CFStringGetMaximumSizeForEncoding (max_utf8_str_len, encoding); 131*30fdc8d8SChris Lattner if (max_utf8_str_len > 0) 132*30fdc8d8SChris Lattner { 133*30fdc8d8SChris Lattner str.resize(max_utf8_str_len); 134*30fdc8d8SChris Lattner if (!str.empty()) 135*30fdc8d8SChris Lattner { 136*30fdc8d8SChris Lattner if (CFStringGetCString (cf_str, &str[0], str.size(), encoding)) 137*30fdc8d8SChris Lattner { 138*30fdc8d8SChris Lattner str.resize(strlen(str.c_str())); 139*30fdc8d8SChris Lattner return str.c_str(); 140*30fdc8d8SChris Lattner } 141*30fdc8d8SChris Lattner } 142*30fdc8d8SChris Lattner } 143*30fdc8d8SChris Lattner } 144*30fdc8d8SChris Lattner return NULL; 145*30fdc8d8SChris Lattner } 146*30fdc8d8SChris Lattner 147*30fdc8d8SChris Lattner // Static function that puts a copy of the file system representation of CF_STR 148*30fdc8d8SChris Lattner // into STR and returns the C string pointer that is contained in STR when 149*30fdc8d8SChris Lattner // successful, else NULL is returned. This allows the std::string parameter 150*30fdc8d8SChris Lattner // to own the extracted string, and also allows that string to be returned as 151*30fdc8d8SChris Lattner // a C string pointer that can be used. 152*30fdc8d8SChris Lattner 153*30fdc8d8SChris Lattner const char * 154*30fdc8d8SChris Lattner CFString::FileSystemRepresentation (CFStringRef cf_str, std::string& str) 155*30fdc8d8SChris Lattner { 156*30fdc8d8SChris Lattner if (cf_str) 157*30fdc8d8SChris Lattner { 158*30fdc8d8SChris Lattner CFIndex max_length = ::CFStringGetMaximumSizeOfFileSystemRepresentation (cf_str); 159*30fdc8d8SChris Lattner if (max_length > 0) 160*30fdc8d8SChris Lattner { 161*30fdc8d8SChris Lattner str.resize(max_length); 162*30fdc8d8SChris Lattner if (!str.empty()) 163*30fdc8d8SChris Lattner { 164*30fdc8d8SChris Lattner if (::CFStringGetFileSystemRepresentation (cf_str, &str[0], str.size())) 165*30fdc8d8SChris Lattner { 166*30fdc8d8SChris Lattner str.erase(::strlen(str.c_str())); 167*30fdc8d8SChris Lattner return str.c_str(); 168*30fdc8d8SChris Lattner } 169*30fdc8d8SChris Lattner } 170*30fdc8d8SChris Lattner } 171*30fdc8d8SChris Lattner } 172*30fdc8d8SChris Lattner str.erase(); 173*30fdc8d8SChris Lattner return NULL; 174*30fdc8d8SChris Lattner } 175*30fdc8d8SChris Lattner 176*30fdc8d8SChris Lattner 177*30fdc8d8SChris Lattner CFIndex 178*30fdc8d8SChris Lattner CFString::GetLength() const 179*30fdc8d8SChris Lattner { 180*30fdc8d8SChris Lattner CFStringRef str = get(); 181*30fdc8d8SChris Lattner if (str) 182*30fdc8d8SChris Lattner return CFStringGetLength (str); 183*30fdc8d8SChris Lattner return 0; 184*30fdc8d8SChris Lattner } 185*30fdc8d8SChris Lattner 186*30fdc8d8SChris Lattner 187*30fdc8d8SChris Lattner const char* 188*30fdc8d8SChris Lattner CFString::GlobPath(const char* path, std::string &expanded_path) 189*30fdc8d8SChris Lattner { 190*30fdc8d8SChris Lattner glob_t globbuf; 191*30fdc8d8SChris Lattner if (::glob (path, GLOB_TILDE, NULL, &globbuf) == 0) 192*30fdc8d8SChris Lattner { 193*30fdc8d8SChris Lattner expanded_path = globbuf.gl_pathv[0]; 194*30fdc8d8SChris Lattner ::globfree (&globbuf); 195*30fdc8d8SChris Lattner } 196*30fdc8d8SChris Lattner else 197*30fdc8d8SChris Lattner expanded_path.clear(); 198*30fdc8d8SChris Lattner 199*30fdc8d8SChris Lattner return expanded_path.c_str(); 200*30fdc8d8SChris Lattner } 201*30fdc8d8SChris Lattner 202