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