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

source code of lldb/tools/debugserver/source/MacOSX/CFString.cpp