xref: /openbsd-src/gnu/llvm/lldb/tools/debugserver/source/MacOSX/CFString.cpp (revision f6aab3d83b51b91c24247ad2c2573574de475a82)
1061da546Spatrick //===-- CFString.cpp --------------------------------------------*- C++ -*-===//
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 //  Created by Greg Clayton on 1/16/08.
10061da546Spatrick //
11061da546Spatrick //===----------------------------------------------------------------------===//
12061da546Spatrick 
13061da546Spatrick #include "CFString.h"
14061da546Spatrick #include <glob.h>
15061da546Spatrick #include <string>
16061da546Spatrick 
17061da546Spatrick // CFString constructor
CFString(CFStringRef s)18061da546Spatrick CFString::CFString(CFStringRef s) : CFReleaser<CFStringRef>(s) {}
19061da546Spatrick 
20061da546Spatrick // CFString copy constructor
21*f6aab3d8Srobert CFString::CFString(const CFString &rhs) = default;
22061da546Spatrick 
23061da546Spatrick // CFString copy constructor
operator =(const CFString & rhs)24061da546Spatrick CFString &CFString::operator=(const CFString &rhs) {
25061da546Spatrick   if (this != &rhs)
26061da546Spatrick     *this = rhs;
27061da546Spatrick   return *this;
28061da546Spatrick }
29061da546Spatrick 
CFString(const char * cstr,CFStringEncoding cstr_encoding)30061da546Spatrick CFString::CFString(const char *cstr, CFStringEncoding cstr_encoding)
31061da546Spatrick     : CFReleaser<CFStringRef>() {
32061da546Spatrick   if (cstr && cstr[0]) {
33061da546Spatrick     reset(
34061da546Spatrick         ::CFStringCreateWithCString(kCFAllocatorDefault, cstr, cstr_encoding));
35061da546Spatrick   }
36061da546Spatrick }
37061da546Spatrick 
38061da546Spatrick // Destructor
39*f6aab3d8Srobert CFString::~CFString() = default;
40061da546Spatrick 
GetFileSystemRepresentation(std::string & s)41061da546Spatrick const char *CFString::GetFileSystemRepresentation(std::string &s) {
42061da546Spatrick   return CFString::FileSystemRepresentation(get(), s);
43061da546Spatrick }
44061da546Spatrick 
SetFileSystemRepresentation(const char * path)45061da546Spatrick CFStringRef CFString::SetFileSystemRepresentation(const char *path) {
46061da546Spatrick   CFStringRef new_value = NULL;
47061da546Spatrick   if (path && path[0])
48061da546Spatrick     new_value =
49061da546Spatrick         ::CFStringCreateWithFileSystemRepresentation(kCFAllocatorDefault, path);
50061da546Spatrick   reset(new_value);
51061da546Spatrick   return get();
52061da546Spatrick }
53061da546Spatrick 
SetFileSystemRepresentationFromCFType(CFTypeRef cf_type)54061da546Spatrick CFStringRef CFString::SetFileSystemRepresentationFromCFType(CFTypeRef cf_type) {
55061da546Spatrick   CFStringRef new_value = NULL;
56061da546Spatrick   if (cf_type != NULL) {
57061da546Spatrick     CFTypeID cf_type_id = ::CFGetTypeID(cf_type);
58061da546Spatrick 
59061da546Spatrick     if (cf_type_id == ::CFStringGetTypeID()) {
60061da546Spatrick       // Retain since we are using the existing object
61061da546Spatrick       new_value = (CFStringRef)::CFRetain(cf_type);
62061da546Spatrick     } else if (cf_type_id == ::CFURLGetTypeID()) {
63061da546Spatrick       new_value =
64061da546Spatrick           ::CFURLCopyFileSystemPath((CFURLRef)cf_type, kCFURLPOSIXPathStyle);
65061da546Spatrick     }
66061da546Spatrick   }
67061da546Spatrick   reset(new_value);
68061da546Spatrick   return get();
69061da546Spatrick }
70061da546Spatrick 
71061da546Spatrick CFStringRef
SetFileSystemRepresentationAndExpandTilde(const char * path)72061da546Spatrick CFString::SetFileSystemRepresentationAndExpandTilde(const char *path) {
73061da546Spatrick   std::string expanded_path;
74061da546Spatrick   if (CFString::GlobPath(path, expanded_path))
75061da546Spatrick     SetFileSystemRepresentation(expanded_path.c_str());
76061da546Spatrick   else
77061da546Spatrick     reset();
78061da546Spatrick   return get();
79061da546Spatrick }
80061da546Spatrick 
UTF8(std::string & str)81061da546Spatrick const char *CFString::UTF8(std::string &str) {
82061da546Spatrick   return CFString::UTF8(get(), str);
83061da546Spatrick }
84061da546Spatrick 
85061da546Spatrick // Static function that puts a copy of the UTF8 contents of CF_STR into STR
86061da546Spatrick // and returns the C string pointer that is contained in STR when successful,
87061da546Spatrick // else
88061da546Spatrick // NULL is returned. This allows the std::string parameter to own the extracted
89061da546Spatrick // string,
90061da546Spatrick // and also allows that string to be returned as a C string pointer that can be
91061da546Spatrick // used.
92061da546Spatrick 
UTF8(CFStringRef cf_str,std::string & str)93061da546Spatrick const char *CFString::UTF8(CFStringRef cf_str, std::string &str) {
94061da546Spatrick   if (cf_str) {
95061da546Spatrick     const CFStringEncoding encoding = kCFStringEncodingUTF8;
96061da546Spatrick     CFIndex max_utf8_str_len = CFStringGetLength(cf_str);
97061da546Spatrick     max_utf8_str_len =
98061da546Spatrick         CFStringGetMaximumSizeForEncoding(max_utf8_str_len, encoding);
99061da546Spatrick     if (max_utf8_str_len > 0) {
100061da546Spatrick       str.resize(max_utf8_str_len);
101061da546Spatrick       if (!str.empty()) {
102061da546Spatrick         if (CFStringGetCString(cf_str, &str[0], str.size(), encoding)) {
103061da546Spatrick           str.resize(strlen(str.c_str()));
104061da546Spatrick           return str.c_str();
105061da546Spatrick         }
106061da546Spatrick       }
107061da546Spatrick     }
108061da546Spatrick   }
109061da546Spatrick   return NULL;
110061da546Spatrick }
111061da546Spatrick 
112061da546Spatrick // Static function that puts a copy of the file system representation of CF_STR
113061da546Spatrick // into STR and returns the C string pointer that is contained in STR when
114061da546Spatrick // successful, else NULL is returned. This allows the std::string parameter
115061da546Spatrick // to own the extracted string, and also allows that string to be returned as
116061da546Spatrick // a C string pointer that can be used.
117061da546Spatrick 
FileSystemRepresentation(CFStringRef cf_str,std::string & str)118061da546Spatrick const char *CFString::FileSystemRepresentation(CFStringRef cf_str,
119061da546Spatrick                                                std::string &str) {
120061da546Spatrick   if (cf_str) {
121061da546Spatrick     CFIndex max_length =
122061da546Spatrick         ::CFStringGetMaximumSizeOfFileSystemRepresentation(cf_str);
123061da546Spatrick     if (max_length > 0) {
124061da546Spatrick       str.resize(max_length);
125061da546Spatrick       if (!str.empty()) {
126061da546Spatrick         if (::CFStringGetFileSystemRepresentation(cf_str, &str[0],
127061da546Spatrick                                                   str.size())) {
128061da546Spatrick           str.erase(::strlen(str.c_str()));
129061da546Spatrick           return str.c_str();
130061da546Spatrick         }
131061da546Spatrick       }
132061da546Spatrick     }
133061da546Spatrick   }
134061da546Spatrick   str.erase();
135061da546Spatrick   return NULL;
136061da546Spatrick }
137061da546Spatrick 
GetLength() const138061da546Spatrick CFIndex CFString::GetLength() const {
139061da546Spatrick   CFStringRef str = get();
140061da546Spatrick   if (str)
141061da546Spatrick     return CFStringGetLength(str);
142061da546Spatrick   return 0;
143061da546Spatrick }
144061da546Spatrick 
GlobPath(const char * path,std::string & expanded_path)145061da546Spatrick const char *CFString::GlobPath(const char *path, std::string &expanded_path) {
146061da546Spatrick   glob_t globbuf;
147061da546Spatrick   if (::glob(path, GLOB_TILDE, NULL, &globbuf) == 0) {
148061da546Spatrick     expanded_path = globbuf.gl_pathv[0];
149061da546Spatrick     ::globfree(&globbuf);
150061da546Spatrick   } else
151061da546Spatrick     expanded_path.clear();
152061da546Spatrick 
153061da546Spatrick   return expanded_path.c_str();
154061da546Spatrick }
155