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