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