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