xref: /llvm-project/lldb/source/Host/macosx/cfcpp/CFCString.cpp (revision 05097246f352eca76207c9ebb08656c88bdf751a)
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 and
92 // returns the C string pointer that is contained in STR when successful, else
93 // NULL is returned. This allows the std::string parameter to own the extracted
94 // string,
95 // and also allows that string to be returned as a C string pointer that can be
96 // used.
97 
98 const char *CFCString::UTF8(CFStringRef cf_str, std::string &str) {
99   if (cf_str) {
100     const CFStringEncoding encoding = kCFStringEncodingUTF8;
101     CFIndex max_utf8_str_len = CFStringGetLength(cf_str);
102     max_utf8_str_len =
103         CFStringGetMaximumSizeForEncoding(max_utf8_str_len, encoding);
104     if (max_utf8_str_len > 0) {
105       str.resize(max_utf8_str_len);
106       if (!str.empty()) {
107         if (CFStringGetCString(cf_str, &str[0], str.size(), encoding)) {
108           str.resize(strlen(str.c_str()));
109           return str.c_str();
110         }
111       }
112     }
113   }
114   return NULL;
115 }
116 
117 const char *CFCString::ExpandTildeInPath(const char *path,
118                                          std::string &expanded_path) {
119   glob_t globbuf;
120   if (::glob(path, GLOB_TILDE, NULL, &globbuf) == 0) {
121     expanded_path = globbuf.gl_pathv[0];
122     ::globfree(&globbuf);
123   } else
124     expanded_path.clear();
125 
126   return expanded_path.c_str();
127 }
128 
129 // Static function that puts a copy of the file system representation of CF_STR
130 // into STR and returns the C string pointer that is contained in STR when
131 // successful, else NULL is returned. This allows the std::string parameter to
132 // own the extracted string, and also allows that string to be returned as a C
133 // string pointer that can be used.
134 
135 const char *CFCString::FileSystemRepresentation(CFStringRef cf_str,
136                                                 std::string &str) {
137   if (cf_str) {
138     CFIndex max_length =
139         ::CFStringGetMaximumSizeOfFileSystemRepresentation(cf_str);
140     if (max_length > 0) {
141       str.resize(max_length);
142       if (!str.empty()) {
143         if (::CFStringGetFileSystemRepresentation(cf_str, &str[0],
144                                                   str.size())) {
145           str.erase(::strlen(str.c_str()));
146           return str.c_str();
147         }
148       }
149     }
150   }
151   str.erase();
152   return NULL;
153 }
154 
155 CFIndex CFCString::GetLength() const {
156   CFStringRef str = get();
157   if (str)
158     return CFStringGetLength(str);
159   return 0;
160 }
161