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 and 92 // returns the C string pointer that is contained in STR when successful, else 93 // NULL is returned. This allows the std::string parameter to own the extracted 94 // string, 95 // and also allows that string to be returned as a C string pointer that can be 96 // used. 97 98 const char *CFCString::UTF8(CFStringRef cf_str, std::string &str) { 99 if (cf_str) { 100 const CFStringEncoding encoding = kCFStringEncodingUTF8; 101 CFIndex max_utf8_str_len = CFStringGetLength(cf_str); 102 max_utf8_str_len = 103 CFStringGetMaximumSizeForEncoding(max_utf8_str_len, encoding); 104 if (max_utf8_str_len > 0) { 105 str.resize(max_utf8_str_len); 106 if (!str.empty()) { 107 if (CFStringGetCString(cf_str, &str[0], str.size(), encoding)) { 108 str.resize(strlen(str.c_str())); 109 return str.c_str(); 110 } 111 } 112 } 113 } 114 return NULL; 115 } 116 117 const char *CFCString::ExpandTildeInPath(const char *path, 118 std::string &expanded_path) { 119 glob_t globbuf; 120 if (::glob(path, GLOB_TILDE, NULL, &globbuf) == 0) { 121 expanded_path = globbuf.gl_pathv[0]; 122 ::globfree(&globbuf); 123 } else 124 expanded_path.clear(); 125 126 return expanded_path.c_str(); 127 } 128 129 // Static function that puts a copy of the file system representation of CF_STR 130 // into STR and returns the C string pointer that is contained in STR when 131 // successful, else NULL is returned. This allows the std::string parameter to 132 // own the extracted string, and also allows that string to be returned as a C 133 // string pointer that can be used. 134 135 const char *CFCString::FileSystemRepresentation(CFStringRef cf_str, 136 std::string &str) { 137 if (cf_str) { 138 CFIndex max_length = 139 ::CFStringGetMaximumSizeOfFileSystemRepresentation(cf_str); 140 if (max_length > 0) { 141 str.resize(max_length); 142 if (!str.empty()) { 143 if (::CFStringGetFileSystemRepresentation(cf_str, &str[0], 144 str.size())) { 145 str.erase(::strlen(str.c_str())); 146 return str.c_str(); 147 } 148 } 149 } 150 } 151 str.erase(); 152 return NULL; 153 } 154 155 CFIndex CFCString::GetLength() const { 156 CFStringRef str = get(); 157 if (str) 158 return CFStringGetLength(str); 159 return 0; 160 } 161