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 //----------------------------------------------------------------------
CFCString(CFStringRef s)17 CFCString::CFCString(CFStringRef s) :
18 CFCReleaser<CFStringRef> (s)
19 {
20 }
21
22 //----------------------------------------------------------------------
23 // CFCString copy constructor
24 //----------------------------------------------------------------------
CFCString(const CFCString & rhs)25 CFCString::CFCString(const CFCString& rhs) :
26 CFCReleaser<CFStringRef> (rhs)
27 {
28
29 }
30
31 //----------------------------------------------------------------------
32 // CFCString copy constructor
33 //----------------------------------------------------------------------
34 CFCString&
operator =(const CFCString & rhs)35 CFCString::operator=(const CFCString& rhs)
36 {
37 if (this != &rhs)
38 *this = rhs;
39 return *this;
40 }
41
CFCString(const char * cstr,CFStringEncoding cstr_encoding)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 //----------------------------------------------------------------------
~CFCString()54 CFCString::~CFCString()
55 {
56 }
57
58 const char *
GetFileSystemRepresentation(std::string & s)59 CFCString::GetFileSystemRepresentation(std::string& s)
60 {
61 return CFCString::FileSystemRepresentation(get(), s);
62 }
63
64 CFStringRef
SetFileSystemRepresentation(const char * path)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
SetFileSystemRepresentationFromCFType(CFTypeRef cf_type)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
SetFileSystemRepresentationAndExpandTilde(const char * path)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 *
UTF8(std::string & str)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 *
UTF8(CFStringRef cf_str,std::string & str)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*
ExpandTildeInPath(const char * path,std::string & expanded_path)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 *
FileSystemRepresentation(CFStringRef cf_str,std::string & str)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
GetLength() const189 CFCString::GetLength() const
190 {
191 CFStringRef str = get();
192 if (str)
193 return CFStringGetLength (str);
194 return 0;
195 }
196