1311128Sdim//===-- CFString.cpp --------------------------------------------*- C++ -*-===// 2311128Sdim// 3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4353358Sdim// See https://llvm.org/LICENSE.txt for license information. 5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6311128Sdim// 7311128Sdim//===----------------------------------------------------------------------===// 8311128Sdim// 9311128Sdim// Created by Greg Clayton on 1/16/08. 10311128Sdim// 11311128Sdim//===----------------------------------------------------------------------===// 12311128Sdim 13311128Sdim#include "CFString.h" 14311128Sdim#include <glob.h> 15311128Sdim#include <string> 16311128Sdim 17311128Sdim// CFString constructor 18311128SdimCFString::CFString(CFStringRef s) : CFReleaser<CFStringRef>(s) {} 19311128Sdim 20311128Sdim// CFString copy constructor 21311128SdimCFString::CFString(const CFString &rhs) : CFReleaser<CFStringRef>(rhs) {} 22311128Sdim 23311128Sdim// CFString copy constructor 24311128SdimCFString &CFString::operator=(const CFString &rhs) { 25311128Sdim if (this != &rhs) 26311128Sdim *this = rhs; 27311128Sdim return *this; 28311128Sdim} 29311128Sdim 30311128SdimCFString::CFString(const char *cstr, CFStringEncoding cstr_encoding) 31311128Sdim : CFReleaser<CFStringRef>() { 32311128Sdim if (cstr && cstr[0]) { 33311128Sdim reset( 34311128Sdim ::CFStringCreateWithCString(kCFAllocatorDefault, cstr, cstr_encoding)); 35311128Sdim } 36311128Sdim} 37311128Sdim 38311128Sdim// Destructor 39311128SdimCFString::~CFString() {} 40311128Sdim 41311128Sdimconst char *CFString::GetFileSystemRepresentation(std::string &s) { 42311128Sdim return CFString::FileSystemRepresentation(get(), s); 43311128Sdim} 44311128Sdim 45311128SdimCFStringRef CFString::SetFileSystemRepresentation(const char *path) { 46311128Sdim CFStringRef new_value = NULL; 47311128Sdim if (path && path[0]) 48311128Sdim new_value = 49311128Sdim ::CFStringCreateWithFileSystemRepresentation(kCFAllocatorDefault, path); 50311128Sdim reset(new_value); 51311128Sdim return get(); 52311128Sdim} 53311128Sdim 54311128SdimCFStringRef CFString::SetFileSystemRepresentationFromCFType(CFTypeRef cf_type) { 55311128Sdim CFStringRef new_value = NULL; 56311128Sdim if (cf_type != NULL) { 57311128Sdim CFTypeID cf_type_id = ::CFGetTypeID(cf_type); 58311128Sdim 59311128Sdim if (cf_type_id == ::CFStringGetTypeID()) { 60311128Sdim // Retain since we are using the existing object 61311128Sdim new_value = (CFStringRef)::CFRetain(cf_type); 62311128Sdim } else if (cf_type_id == ::CFURLGetTypeID()) { 63311128Sdim new_value = 64311128Sdim ::CFURLCopyFileSystemPath((CFURLRef)cf_type, kCFURLPOSIXPathStyle); 65311128Sdim } 66311128Sdim } 67311128Sdim reset(new_value); 68311128Sdim return get(); 69311128Sdim} 70311128Sdim 71311128SdimCFStringRef 72311128SdimCFString::SetFileSystemRepresentationAndExpandTilde(const char *path) { 73311128Sdim std::string expanded_path; 74311128Sdim if (CFString::GlobPath(path, expanded_path)) 75311128Sdim SetFileSystemRepresentation(expanded_path.c_str()); 76311128Sdim else 77311128Sdim reset(); 78311128Sdim return get(); 79311128Sdim} 80311128Sdim 81311128Sdimconst char *CFString::UTF8(std::string &str) { 82311128Sdim return CFString::UTF8(get(), str); 83311128Sdim} 84311128Sdim 85341825Sdim// Static function that puts a copy of the UTF8 contents of CF_STR into STR and 86341825Sdim// returns the C string pointer that is contained in STR when successful, else 87311128Sdim// NULL is returned. This allows the std::string parameter to own the extracted 88311128Sdim// string, 89311128Sdim// and also allows that string to be returned as a C string pointer that can be 90311128Sdim// used. 91311128Sdim 92311128Sdimconst char *CFString::UTF8(CFStringRef cf_str, std::string &str) { 93311128Sdim if (cf_str) { 94311128Sdim const CFStringEncoding encoding = kCFStringEncodingUTF8; 95311128Sdim CFIndex max_utf8_str_len = CFStringGetLength(cf_str); 96311128Sdim max_utf8_str_len = 97311128Sdim CFStringGetMaximumSizeForEncoding(max_utf8_str_len, encoding); 98311128Sdim if (max_utf8_str_len > 0) { 99311128Sdim str.resize(max_utf8_str_len); 100311128Sdim if (!str.empty()) { 101311128Sdim if (CFStringGetCString(cf_str, &str[0], str.size(), encoding)) { 102311128Sdim str.resize(strlen(str.c_str())); 103311128Sdim return str.c_str(); 104311128Sdim } 105311128Sdim } 106311128Sdim } 107311128Sdim } 108311128Sdim return NULL; 109311128Sdim} 110311128Sdim 111311128Sdim// Static function that puts a copy of the file system representation of CF_STR 112311128Sdim// into STR and returns the C string pointer that is contained in STR when 113341825Sdim// successful, else NULL is returned. This allows the std::string parameter to 114341825Sdim// own the extracted string, and also allows that string to be returned as a C 115341825Sdim// string pointer that can be used. 116311128Sdim 117311128Sdimconst char *CFString::FileSystemRepresentation(CFStringRef cf_str, 118311128Sdim std::string &str) { 119311128Sdim if (cf_str) { 120311128Sdim CFIndex max_length = 121311128Sdim ::CFStringGetMaximumSizeOfFileSystemRepresentation(cf_str); 122311128Sdim if (max_length > 0) { 123311128Sdim str.resize(max_length); 124311128Sdim if (!str.empty()) { 125311128Sdim if (::CFStringGetFileSystemRepresentation(cf_str, &str[0], 126311128Sdim str.size())) { 127311128Sdim str.erase(::strlen(str.c_str())); 128311128Sdim return str.c_str(); 129311128Sdim } 130311128Sdim } 131311128Sdim } 132311128Sdim } 133311128Sdim str.erase(); 134311128Sdim return NULL; 135311128Sdim} 136311128Sdim 137311128SdimCFIndex CFString::GetLength() const { 138311128Sdim CFStringRef str = get(); 139311128Sdim if (str) 140311128Sdim return CFStringGetLength(str); 141311128Sdim return 0; 142311128Sdim} 143311128Sdim 144311128Sdimconst char *CFString::GlobPath(const char *path, std::string &expanded_path) { 145311128Sdim glob_t globbuf; 146311128Sdim if (::glob(path, GLOB_TILDE, NULL, &globbuf) == 0) { 147311128Sdim expanded_path = globbuf.gl_pathv[0]; 148311128Sdim ::globfree(&globbuf); 149311128Sdim } else 150311128Sdim expanded_path.clear(); 151311128Sdim 152311128Sdim return expanded_path.c_str(); 153311128Sdim} 154