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