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