xref: /openbsd-src/gnu/llvm/lldb/source/Host/macosx/cfcpp/CFCString.cpp (revision f6aab3d83b51b91c24247ad2c2573574de475a82)
1dda28197Spatrick //===-- CFCString.cpp -----------------------------------------------------===//
2061da546Spatrick //
3061da546Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4061da546Spatrick // See https://llvm.org/LICENSE.txt for license information.
5061da546Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6061da546Spatrick //
7061da546Spatrick //===----------------------------------------------------------------------===//
8061da546Spatrick 
9061da546Spatrick #include "CFCString.h"
10061da546Spatrick #include <glob.h>
11061da546Spatrick #include <string>
12061da546Spatrick 
13061da546Spatrick // CFCString constructor
CFCString(CFStringRef s)14061da546Spatrick CFCString::CFCString(CFStringRef s) : CFCReleaser<CFStringRef>(s) {}
15061da546Spatrick 
16061da546Spatrick // CFCString copy constructor
17*f6aab3d8Srobert CFCString::CFCString(const CFCString &rhs) = default;
18061da546Spatrick 
19061da546Spatrick // CFCString copy constructor
operator =(const CFCString & rhs)20061da546Spatrick CFCString &CFCString::operator=(const CFCString &rhs) {
21061da546Spatrick   if (this != &rhs)
22061da546Spatrick     *this = rhs;
23061da546Spatrick   return *this;
24061da546Spatrick }
25061da546Spatrick 
CFCString(const char * cstr,CFStringEncoding cstr_encoding)26061da546Spatrick CFCString::CFCString(const char *cstr, CFStringEncoding cstr_encoding)
27061da546Spatrick     : CFCReleaser<CFStringRef>() {
28061da546Spatrick   if (cstr && cstr[0]) {
29061da546Spatrick     reset(
30061da546Spatrick         ::CFStringCreateWithCString(kCFAllocatorDefault, cstr, cstr_encoding));
31061da546Spatrick   }
32061da546Spatrick }
33061da546Spatrick 
34061da546Spatrick // Destructor
35be691f3bSpatrick CFCString::~CFCString() = default;
36061da546Spatrick 
GetFileSystemRepresentation(std::string & s)37061da546Spatrick const char *CFCString::GetFileSystemRepresentation(std::string &s) {
38061da546Spatrick   return CFCString::FileSystemRepresentation(get(), s);
39061da546Spatrick }
40061da546Spatrick 
SetFileSystemRepresentation(const char * path)41061da546Spatrick CFStringRef CFCString::SetFileSystemRepresentation(const char *path) {
42061da546Spatrick   CFStringRef new_value = NULL;
43061da546Spatrick   if (path && path[0])
44061da546Spatrick     new_value =
45061da546Spatrick         ::CFStringCreateWithFileSystemRepresentation(kCFAllocatorDefault, path);
46061da546Spatrick   reset(new_value);
47061da546Spatrick   return get();
48061da546Spatrick }
49061da546Spatrick 
50061da546Spatrick CFStringRef
SetFileSystemRepresentationFromCFType(CFTypeRef cf_type)51061da546Spatrick CFCString::SetFileSystemRepresentationFromCFType(CFTypeRef cf_type) {
52061da546Spatrick   CFStringRef new_value = NULL;
53061da546Spatrick   if (cf_type != NULL) {
54061da546Spatrick     CFTypeID cf_type_id = ::CFGetTypeID(cf_type);
55061da546Spatrick 
56061da546Spatrick     if (cf_type_id == ::CFStringGetTypeID()) {
57061da546Spatrick       // Retain since we are using the existing object
58061da546Spatrick       new_value = (CFStringRef)::CFRetain(cf_type);
59061da546Spatrick     } else if (cf_type_id == ::CFURLGetTypeID()) {
60061da546Spatrick       new_value =
61061da546Spatrick           ::CFURLCopyFileSystemPath((CFURLRef)cf_type, kCFURLPOSIXPathStyle);
62061da546Spatrick     }
63061da546Spatrick   }
64061da546Spatrick   reset(new_value);
65061da546Spatrick   return get();
66061da546Spatrick }
67061da546Spatrick 
68061da546Spatrick CFStringRef
SetFileSystemRepresentationAndExpandTilde(const char * path)69061da546Spatrick CFCString::SetFileSystemRepresentationAndExpandTilde(const char *path) {
70061da546Spatrick   std::string expanded_path;
71061da546Spatrick   if (CFCString::ExpandTildeInPath(path, expanded_path))
72061da546Spatrick     SetFileSystemRepresentation(expanded_path.c_str());
73061da546Spatrick   else
74061da546Spatrick     reset();
75061da546Spatrick   return get();
76061da546Spatrick }
77061da546Spatrick 
UTF8(std::string & str)78061da546Spatrick const char *CFCString::UTF8(std::string &str) {
79061da546Spatrick   return CFCString::UTF8(get(), str);
80061da546Spatrick }
81061da546Spatrick 
82061da546Spatrick // Static function that puts a copy of the UTF8 contents of CF_STR into STR and
83061da546Spatrick // returns the C string pointer that is contained in STR when successful, else
84061da546Spatrick // NULL is returned. This allows the std::string parameter to own the extracted
85061da546Spatrick // string,
86061da546Spatrick // and also allows that string to be returned as a C string pointer that can be
87061da546Spatrick // used.
88061da546Spatrick 
UTF8(CFStringRef cf_str,std::string & str)89061da546Spatrick const char *CFCString::UTF8(CFStringRef cf_str, std::string &str) {
90061da546Spatrick   if (cf_str) {
91061da546Spatrick     const CFStringEncoding encoding = kCFStringEncodingUTF8;
92061da546Spatrick     CFIndex max_utf8_str_len = CFStringGetLength(cf_str);
93061da546Spatrick     max_utf8_str_len =
94061da546Spatrick         CFStringGetMaximumSizeForEncoding(max_utf8_str_len, encoding);
95061da546Spatrick     if (max_utf8_str_len > 0) {
96061da546Spatrick       str.resize(max_utf8_str_len);
97061da546Spatrick       if (!str.empty()) {
98061da546Spatrick         if (CFStringGetCString(cf_str, &str[0], str.size(), encoding)) {
99061da546Spatrick           str.resize(strlen(str.c_str()));
100061da546Spatrick           return str.c_str();
101061da546Spatrick         }
102061da546Spatrick       }
103061da546Spatrick     }
104061da546Spatrick   }
105061da546Spatrick   return NULL;
106061da546Spatrick }
107061da546Spatrick 
ExpandTildeInPath(const char * path,std::string & expanded_path)108061da546Spatrick const char *CFCString::ExpandTildeInPath(const char *path,
109061da546Spatrick                                          std::string &expanded_path) {
110061da546Spatrick   glob_t globbuf;
111061da546Spatrick   if (::glob(path, GLOB_TILDE, NULL, &globbuf) == 0) {
112061da546Spatrick     expanded_path = globbuf.gl_pathv[0];
113061da546Spatrick     ::globfree(&globbuf);
114061da546Spatrick   } else
115061da546Spatrick     expanded_path.clear();
116061da546Spatrick 
117061da546Spatrick   return expanded_path.c_str();
118061da546Spatrick }
119061da546Spatrick 
120061da546Spatrick // Static function that puts a copy of the file system representation of CF_STR
121061da546Spatrick // into STR and returns the C string pointer that is contained in STR when
122061da546Spatrick // successful, else NULL is returned. This allows the std::string parameter to
123061da546Spatrick // own the extracted string, and also allows that string to be returned as a C
124061da546Spatrick // string pointer that can be used.
125061da546Spatrick 
FileSystemRepresentation(CFStringRef cf_str,std::string & str)126061da546Spatrick const char *CFCString::FileSystemRepresentation(CFStringRef cf_str,
127061da546Spatrick                                                 std::string &str) {
128061da546Spatrick   if (cf_str) {
129061da546Spatrick     CFIndex max_length =
130061da546Spatrick         ::CFStringGetMaximumSizeOfFileSystemRepresentation(cf_str);
131061da546Spatrick     if (max_length > 0) {
132061da546Spatrick       str.resize(max_length);
133061da546Spatrick       if (!str.empty()) {
134061da546Spatrick         if (::CFStringGetFileSystemRepresentation(cf_str, &str[0],
135061da546Spatrick                                                   str.size())) {
136061da546Spatrick           str.erase(::strlen(str.c_str()));
137061da546Spatrick           return str.c_str();
138061da546Spatrick         }
139061da546Spatrick       }
140061da546Spatrick     }
141061da546Spatrick   }
142061da546Spatrick   str.erase();
143061da546Spatrick   return NULL;
144061da546Spatrick }
145061da546Spatrick 
GetLength() const146061da546Spatrick CFIndex CFCString::GetLength() const {
147061da546Spatrick   CFStringRef str = get();
148061da546Spatrick   if (str)
149061da546Spatrick     return CFStringGetLength(str);
150061da546Spatrick   return 0;
151061da546Spatrick }
152