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