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