155 lines · cpp
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-exception6//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 constructor18CFString::CFString(CFStringRef s) : CFReleaser<CFStringRef>(s) {}19 20// CFString copy constructor21CFString::CFString(const CFString &rhs) = default;22 23// CFString copy constructor24CFString &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// Destructor39CFString::~CFString() = default;40 41const char *CFString::GetFileSystemRepresentation(std::string &s) {42 return CFString::FileSystemRepresentation(get(), 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 object61 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 71CFStringRef72CFString::SetFileSystemRepresentationAndExpandTilde(const char *path) {73 std::string expanded_path;74 if (CFString::GlobPath(path, expanded_path))75 SetFileSystemRepresentation(expanded_path.c_str());76 else77 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 STR86// and returns the C string pointer that is contained in STR when successful,87// else88// NULL is returned. This allows the std::string parameter to own the extracted89// string,90// and also allows that string to be returned as a C string pointer that can be91// 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_STR113// into STR and returns the C string pointer that is contained in STR when114// successful, else NULL is returned. This allows the std::string parameter115// to own the extracted string, and also allows that string to be returned as116// 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(path, GLOB_TILDE, NULL, &globbuf) == 0) {148 expanded_path = globbuf.gl_pathv[0];149 ::globfree(&globbuf);150 } else151 expanded_path.clear();152 153 return expanded_path.c_str();154}155