CFString.cpp revision 24943d2ee8bfaa7cf5893e4709143924157a5c1e
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//----------------------------------------------------------------------
21CFString::CFString(CFStringRef s) :
22    CFReleaser<CFStringRef> (s)
23{
24}
25
26//----------------------------------------------------------------------
27// CFString copy constructor
28//----------------------------------------------------------------------
29CFString::CFString(const CFString& rhs) :
30    CFReleaser<CFStringRef> (rhs)
31{
32
33}
34
35//----------------------------------------------------------------------
36// CFString copy constructor
37//----------------------------------------------------------------------
38CFString&
39CFString::operator=(const CFString& rhs)
40{
41    if (this != &rhs)
42        *this = rhs;
43    return *this;
44}
45
46CFString::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//----------------------------------------------------------------------
58CFString::~CFString()
59{
60}
61
62const char *
63CFString::GetFileSystemRepresentation(std::string& s)
64{
65    return CFString::FileSystemRepresentation(get(), s);
66}
67
68CFStringRef
69CFString::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
79CFStringRef
80CFString::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
101CFStringRef
102CFString::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
112const char *
113CFString::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
123const char *
124CFString::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
153const char *
154CFString::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
177CFIndex
178CFString::GetLength() const
179{
180    CFStringRef str = get();
181    if (str)
182        return CFStringGetLength (str);
183    return 0;
184}
185
186
187const char*
188CFString::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