130fdc8d8SChris Lattner //===-- CFString.cpp --------------------------------------------*- C++ -*-===//
230fdc8d8SChris Lattner //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
630fdc8d8SChris Lattner //
730fdc8d8SChris Lattner //===----------------------------------------------------------------------===//
830fdc8d8SChris Lattner //
930fdc8d8SChris Lattner // Created by Greg Clayton on 1/16/08.
1030fdc8d8SChris Lattner //
1130fdc8d8SChris Lattner //===----------------------------------------------------------------------===//
1230fdc8d8SChris Lattner
1330fdc8d8SChris Lattner #include "CFString.h"
1430fdc8d8SChris Lattner #include <glob.h>
15b9c1b51eSKate Stone #include <string>
1630fdc8d8SChris Lattner
1730fdc8d8SChris Lattner // CFString constructor
CFString(CFStringRef s)18b9c1b51eSKate Stone CFString::CFString(CFStringRef s) : CFReleaser<CFStringRef>(s) {}
1930fdc8d8SChris Lattner
2030fdc8d8SChris Lattner // CFString copy constructor
21*24f9a2f5SShafik Yaghmour CFString::CFString(const CFString &rhs) = default;
2230fdc8d8SChris Lattner
2330fdc8d8SChris Lattner // CFString copy constructor
operator =(const CFString & rhs)24b9c1b51eSKate Stone CFString &CFString::operator=(const CFString &rhs) {
2530fdc8d8SChris Lattner if (this != &rhs)
2630fdc8d8SChris Lattner *this = rhs;
2730fdc8d8SChris Lattner return *this;
2830fdc8d8SChris Lattner }
2930fdc8d8SChris Lattner
CFString(const char * cstr,CFStringEncoding cstr_encoding)30b9c1b51eSKate Stone CFString::CFString(const char *cstr, CFStringEncoding cstr_encoding)
31b9c1b51eSKate Stone : CFReleaser<CFStringRef>() {
32b9c1b51eSKate Stone if (cstr && cstr[0]) {
33b9c1b51eSKate Stone reset(
34b9c1b51eSKate Stone ::CFStringCreateWithCString(kCFAllocatorDefault, cstr, cstr_encoding));
3530fdc8d8SChris Lattner }
3630fdc8d8SChris Lattner }
3730fdc8d8SChris Lattner
3830fdc8d8SChris Lattner // Destructor
39*24f9a2f5SShafik Yaghmour CFString::~CFString() = default;
4030fdc8d8SChris Lattner
GetFileSystemRepresentation(std::string & s)41b9c1b51eSKate Stone const char *CFString::GetFileSystemRepresentation(std::string &s) {
4230fdc8d8SChris Lattner return CFString::FileSystemRepresentation(get(), s);
4330fdc8d8SChris Lattner }
4430fdc8d8SChris Lattner
SetFileSystemRepresentation(const char * path)45b9c1b51eSKate Stone CFStringRef CFString::SetFileSystemRepresentation(const char *path) {
4630fdc8d8SChris Lattner CFStringRef new_value = NULL;
4730fdc8d8SChris Lattner if (path && path[0])
48b9c1b51eSKate Stone new_value =
49b9c1b51eSKate Stone ::CFStringCreateWithFileSystemRepresentation(kCFAllocatorDefault, path);
5030fdc8d8SChris Lattner reset(new_value);
5130fdc8d8SChris Lattner return get();
5230fdc8d8SChris Lattner }
5330fdc8d8SChris Lattner
SetFileSystemRepresentationFromCFType(CFTypeRef cf_type)54b9c1b51eSKate Stone CFStringRef CFString::SetFileSystemRepresentationFromCFType(CFTypeRef cf_type) {
5530fdc8d8SChris Lattner CFStringRef new_value = NULL;
56b9c1b51eSKate Stone if (cf_type != NULL) {
5730fdc8d8SChris Lattner CFTypeID cf_type_id = ::CFGetTypeID(cf_type);
5830fdc8d8SChris Lattner
59b9c1b51eSKate Stone if (cf_type_id == ::CFStringGetTypeID()) {
6030fdc8d8SChris Lattner // Retain since we are using the existing object
6130fdc8d8SChris Lattner new_value = (CFStringRef)::CFRetain(cf_type);
62b9c1b51eSKate Stone } else if (cf_type_id == ::CFURLGetTypeID()) {
63b9c1b51eSKate Stone new_value =
64b9c1b51eSKate Stone ::CFURLCopyFileSystemPath((CFURLRef)cf_type, kCFURLPOSIXPathStyle);
6530fdc8d8SChris Lattner }
6630fdc8d8SChris Lattner }
6730fdc8d8SChris Lattner reset(new_value);
6830fdc8d8SChris Lattner return get();
6930fdc8d8SChris Lattner }
7030fdc8d8SChris Lattner
7130fdc8d8SChris Lattner CFStringRef
SetFileSystemRepresentationAndExpandTilde(const char * path)72b9c1b51eSKate Stone CFString::SetFileSystemRepresentationAndExpandTilde(const char *path) {
7330fdc8d8SChris Lattner std::string expanded_path;
7430fdc8d8SChris Lattner if (CFString::GlobPath(path, expanded_path))
7530fdc8d8SChris Lattner SetFileSystemRepresentation(expanded_path.c_str());
7630fdc8d8SChris Lattner else
7730fdc8d8SChris Lattner reset();
7830fdc8d8SChris Lattner return get();
7930fdc8d8SChris Lattner }
8030fdc8d8SChris Lattner
UTF8(std::string & str)81b9c1b51eSKate Stone const char *CFString::UTF8(std::string &str) {
8230fdc8d8SChris Lattner return CFString::UTF8(get(), str);
8330fdc8d8SChris Lattner }
8430fdc8d8SChris Lattner
8530fdc8d8SChris Lattner // Static function that puts a copy of the UTF8 contents of CF_STR into STR
86b9c1b51eSKate Stone // and returns the C string pointer that is contained in STR when successful,
87b9c1b51eSKate Stone // else
88b9c1b51eSKate Stone // NULL is returned. This allows the std::string parameter to own the extracted
89b9c1b51eSKate Stone // string,
90b9c1b51eSKate Stone // and also allows that string to be returned as a C string pointer that can be
91b9c1b51eSKate Stone // used.
9230fdc8d8SChris Lattner
UTF8(CFStringRef cf_str,std::string & str)93b9c1b51eSKate Stone const char *CFString::UTF8(CFStringRef cf_str, std::string &str) {
94b9c1b51eSKate Stone if (cf_str) {
9530fdc8d8SChris Lattner const CFStringEncoding encoding = kCFStringEncodingUTF8;
9630fdc8d8SChris Lattner CFIndex max_utf8_str_len = CFStringGetLength(cf_str);
97b9c1b51eSKate Stone max_utf8_str_len =
98b9c1b51eSKate Stone CFStringGetMaximumSizeForEncoding(max_utf8_str_len, encoding);
99b9c1b51eSKate Stone if (max_utf8_str_len > 0) {
10030fdc8d8SChris Lattner str.resize(max_utf8_str_len);
101b9c1b51eSKate Stone if (!str.empty()) {
102b9c1b51eSKate Stone if (CFStringGetCString(cf_str, &str[0], str.size(), encoding)) {
10330fdc8d8SChris Lattner str.resize(strlen(str.c_str()));
10430fdc8d8SChris Lattner return str.c_str();
10530fdc8d8SChris Lattner }
10630fdc8d8SChris Lattner }
10730fdc8d8SChris Lattner }
10830fdc8d8SChris Lattner }
10930fdc8d8SChris Lattner return NULL;
11030fdc8d8SChris Lattner }
11130fdc8d8SChris Lattner
11230fdc8d8SChris Lattner // Static function that puts a copy of the file system representation of CF_STR
11330fdc8d8SChris Lattner // into STR and returns the C string pointer that is contained in STR when
11430fdc8d8SChris Lattner // successful, else NULL is returned. This allows the std::string parameter
11530fdc8d8SChris Lattner // to own the extracted string, and also allows that string to be returned as
11630fdc8d8SChris Lattner // a C string pointer that can be used.
11730fdc8d8SChris Lattner
FileSystemRepresentation(CFStringRef cf_str,std::string & str)118b9c1b51eSKate Stone const char *CFString::FileSystemRepresentation(CFStringRef cf_str,
119b9c1b51eSKate Stone std::string &str) {
120b9c1b51eSKate Stone if (cf_str) {
121b9c1b51eSKate Stone CFIndex max_length =
122b9c1b51eSKate Stone ::CFStringGetMaximumSizeOfFileSystemRepresentation(cf_str);
123b9c1b51eSKate Stone if (max_length > 0) {
12430fdc8d8SChris Lattner str.resize(max_length);
125b9c1b51eSKate Stone if (!str.empty()) {
126b9c1b51eSKate Stone if (::CFStringGetFileSystemRepresentation(cf_str, &str[0],
127b9c1b51eSKate Stone str.size())) {
12830fdc8d8SChris Lattner str.erase(::strlen(str.c_str()));
12930fdc8d8SChris Lattner return str.c_str();
13030fdc8d8SChris Lattner }
13130fdc8d8SChris Lattner }
13230fdc8d8SChris Lattner }
13330fdc8d8SChris Lattner }
13430fdc8d8SChris Lattner str.erase();
13530fdc8d8SChris Lattner return NULL;
13630fdc8d8SChris Lattner }
13730fdc8d8SChris Lattner
GetLength() const138b9c1b51eSKate Stone CFIndex CFString::GetLength() const {
13930fdc8d8SChris Lattner CFStringRef str = get();
14030fdc8d8SChris Lattner if (str)
14130fdc8d8SChris Lattner return CFStringGetLength(str);
14230fdc8d8SChris Lattner return 0;
14330fdc8d8SChris Lattner }
14430fdc8d8SChris Lattner
GlobPath(const char * path,std::string & expanded_path)145b9c1b51eSKate Stone const char *CFString::GlobPath(const char *path, std::string &expanded_path) {
14630fdc8d8SChris Lattner glob_t globbuf;
147b9c1b51eSKate Stone if (::glob(path, GLOB_TILDE, NULL, &globbuf) == 0) {
14830fdc8d8SChris Lattner expanded_path = globbuf.gl_pathv[0];
14930fdc8d8SChris Lattner ::globfree(&globbuf);
150b9c1b51eSKate Stone } else
15130fdc8d8SChris Lattner expanded_path.clear();
15230fdc8d8SChris Lattner
15330fdc8d8SChris Lattner return expanded_path.c_str();
15430fdc8d8SChris Lattner }
155