Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 5 additions & 6 deletions Sources/FoundationEssentials/URL/URL_C+Encoding.swift
Original file line number Diff line number Diff line change
Expand Up @@ -109,13 +109,13 @@ extension NSURL {
return URLEncoder.percentEncode(string: path, encoding: encoding, component: component, skipAlreadyEncoded: false)
}

static func __copySwiftEncodedFSRPath(_ path: String) -> String? {
static func __copySwiftEncodedFSRPath(_ path: String) -> Unmanaged<CFString>? {
guard !path.isEmpty else {
return path
return _createCFStringFromASCIIString(path)
}
// Convert path to its decomposed file system representation then encode
let maxFSRSize = 3 * path.utf8.count
return withUnsafeTemporaryAllocation(of: UInt8.self, capacity: maxFSRSize) { pathBuffer -> String? in
return withUnsafeTemporaryAllocation(of: UInt8.self, capacity: maxFSRSize) { pathBuffer in
guard var pathLength = path._decomposed(.hfsPlus, into: pathBuffer) else {
return nil
}
Expand All @@ -124,15 +124,14 @@ extension NSURL {
while pathLength > rootLength && pathBuffer[pathLength - 1] == UInt8(ascii: "/") {
pathLength -= 1
}
return withUnsafeTemporaryAllocation(of: UInt8.self, capacity: 3 * pathLength) { encodedBuffer in
let encodedLength = URLEncoder.percentEncodeUnchecked(
return _createCFStringFromASCIIBuffer(capacity: 3 * pathLength) { encodedBuffer in
URLEncoder.percentEncodeUnchecked(
input: UnsafeBufferPointer(rebasing: pathBuffer[..<pathLength]),
output: encodedBuffer,
// Encode ";" for compatibility
component: .pathNoSemicolon,
skipAlreadyEncoded: false
)
return String(decoding: encodedBuffer[..<encodedLength], as: UTF8.self)
}
}
}
Expand Down
13 changes: 5 additions & 8 deletions Sources/FoundationEssentials/URL/URL_C+File.swift
Original file line number Diff line number Diff line change
Expand Up @@ -35,15 +35,13 @@ extension NSURL {
assert(false, "Unexpected path style: \(pathStyle)")
return false
}
guard let urlString else {
guard let urlString, let cfString = _createCFStringFromASCIIString(urlString) else {
return false
}

assert(flags.isDisjoint(with: .nonFileImplFlags))
impl.pointee._header._flags = flags
impl.pointee._header._string = Unmanaged<CFString>.passRetained(
urlString as CFString
)
impl.pointee._header._string = cfString
return true
}

Expand All @@ -55,15 +53,14 @@ extension NSURL {

var flags = __CFURLFlags.fileImplFlags
let buffer = UnsafeBufferPointer(start: fsr, count: length)
guard let urlString = parseFileSystemRepresentation(buffer: buffer, flags: &flags, isDirectory: isDirectory) else {
guard let urlString = parseFileSystemRepresentation(buffer: buffer, flags: &flags, isDirectory: isDirectory),
let cfString = _createCFStringFromASCIIString(urlString) else {
return false
}

assert(flags.isDisjoint(with: .nonFileImplFlags))
impl.pointee._header._flags = flags
impl.pointee._header._string = Unmanaged<CFString>.passRetained(
urlString as CFString
)
impl.pointee._header._string = cfString
return true
}

Expand Down
19 changes: 19 additions & 0 deletions Sources/FoundationEssentials/URL/URL_C+Spans.swift
Original file line number Diff line number Diff line change
Expand Up @@ -160,4 +160,23 @@ internal func _createCFStringFromCharacterBuffer(
}
}

internal func _createCFStringFromASCIIString(_ string: String) -> Unmanaged<CFString>? {
let ascii = CFStringBuiltInEncodings.ASCII.rawValue
guard !string.isEmpty else {
guard let empty = CFStringCreateWithCString(kCFAllocatorDefault, "", ascii) else {
return nil
}
return Unmanaged.passRetained(empty)
}
var mut = string
return mut.withUTF8 { utf8 in
guard let result = CFStringCreateWithBytes(
kCFAllocatorDefault, utf8.baseAddress!, utf8.count, ascii, false
) else {
return nil
}
return Unmanaged.passRetained(result)
}
}

#endif // FOUNDATION_FRAMEWORK
Loading