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