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 //----------------------------------------------------------------------
CFString(CFStringRef s)21 CFString::CFString(CFStringRef s) : CFReleaser<CFStringRef>(s) {}
22
23 //----------------------------------------------------------------------
24 // CFString copy constructor
25 //----------------------------------------------------------------------
CFString(const CFString & rhs)26 CFString::CFString(const CFString &rhs) : CFReleaser<CFStringRef>(rhs) {}
27
28 //----------------------------------------------------------------------
29 // CFString copy constructor
30 //----------------------------------------------------------------------
operator =(const CFString & rhs)31 CFString &CFString::operator=(const CFString &rhs) {
32 if (this != &rhs)
33 *this = rhs;
34 return *this;
35 }
36
CFString(const char * cstr,CFStringEncoding cstr_encoding)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 //----------------------------------------------------------------------
~CFString()48 CFString::~CFString() {}
49
GetFileSystemRepresentation(std::string & s)50 const char *CFString::GetFileSystemRepresentation(std::string &s) {
51 return CFString::FileSystemRepresentation(get(), s);
52 }
53
SetFileSystemRepresentation(const char * path)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
SetFileSystemRepresentationFromCFType(CFTypeRef cf_type)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
SetFileSystemRepresentationAndExpandTilde(const char * path)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
UTF8(std::string & str)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 and
95 // returns the C string pointer that is contained in STR when successful, else
96 // NULL is returned. This allows the std::string parameter to own the extracted
97 // string,
98 // and also allows that string to be returned as a C string pointer that can be
99 // used.
100
UTF8(CFStringRef cf_str,std::string & str)101 const char *CFString::UTF8(CFStringRef cf_str, std::string &str) {
102 if (cf_str) {
103 const CFStringEncoding encoding = kCFStringEncodingUTF8;
104 CFIndex max_utf8_str_len = CFStringGetLength(cf_str);
105 max_utf8_str_len =
106 CFStringGetMaximumSizeForEncoding(max_utf8_str_len, encoding);
107 if (max_utf8_str_len > 0) {
108 str.resize(max_utf8_str_len);
109 if (!str.empty()) {
110 if (CFStringGetCString(cf_str, &str[0], str.size(), encoding)) {
111 str.resize(strlen(str.c_str()));
112 return str.c_str();
113 }
114 }
115 }
116 }
117 return NULL;
118 }
119
120 // Static function that puts a copy of the file system representation of CF_STR
121 // into STR and returns the C string pointer that is contained in STR when
122 // successful, else NULL is returned. This allows the std::string parameter to
123 // own the extracted string, and also allows that string to be returned as a C
124 // string pointer that can be used.
125
FileSystemRepresentation(CFStringRef cf_str,std::string & str)126 const char *CFString::FileSystemRepresentation(CFStringRef cf_str,
127 std::string &str) {
128 if (cf_str) {
129 CFIndex max_length =
130 ::CFStringGetMaximumSizeOfFileSystemRepresentation(cf_str);
131 if (max_length > 0) {
132 str.resize(max_length);
133 if (!str.empty()) {
134 if (::CFStringGetFileSystemRepresentation(cf_str, &str[0],
135 str.size())) {
136 str.erase(::strlen(str.c_str()));
137 return str.c_str();
138 }
139 }
140 }
141 }
142 str.erase();
143 return NULL;
144 }
145
GetLength() const146 CFIndex CFString::GetLength() const {
147 CFStringRef str = get();
148 if (str)
149 return CFStringGetLength(str);
150 return 0;
151 }
152
GlobPath(const char * path,std::string & expanded_path)153 const char *CFString::GlobPath(const char *path, std::string &expanded_path) {
154 glob_t globbuf;
155 if (::glob(path, GLOB_TILDE, NULL, &globbuf) == 0) {
156 expanded_path = globbuf.gl_pathv[0];
157 ::globfree(&globbuf);
158 } else
159 expanded_path.clear();
160
161 return expanded_path.c_str();
162 }
163