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
14CFCString::CFCString(CFStringRef s) : CFCReleaser<CFStringRef>(s) {}
15
16// CFCString copy constructor
17CFCString::CFCString(const CFCString &rhs) = default;
18
19// CFCString copy constructor
20CFCString &CFCString::operator=(const CFCString &rhs) {
21 if (this != &rhs)
22 *this = rhs;
23 return *this;
24}
25
26CFCString::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
35CFCString::~CFCString() = default;
36
37const char *CFCString::GetFileSystemRepresentation(std::string &s) {
38 return CFCString::FileSystemRepresentation(get(), s);
39}
40
41CFStringRef 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
50CFStringRef
51CFCString::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
68CFStringRef
69CFCString::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
78const char *CFCString::UTF8(std::string &str) {
79 return CFCString::UTF8(str&: 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
89const 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
108const char *CFCString::ExpandTildeInPath(const char *path,
109 std::string &expanded_path) {
110 glob_t globbuf;
111 if (::glob(pattern: path, GLOB_TILDE, NULL, pglob: &globbuf) == 0) {
112 expanded_path = globbuf.gl_pathv[0];
113 ::globfree(pglob: &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
126const 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(s&: 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
146CFIndex CFCString::GetLength() const {
147 CFStringRef str = get();
148 if (str)
149 return CFStringGetLength(str);
150 return 0;
151}
152

source code of lldb/source/Host/macosx/cfcpp/CFCString.cpp