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