mirror of
https://github.com/apple/swift.git
synced 2026-06-20 15:42:51 +02:00
453277eb74
Functions like withUnsafeBufferPointer are, by themselves, safe to call. It's only the operations on the unsafe pointers passed into the closure that are the safety issue. This was the intent spelled out in SE-0458 but was not fully realized in the library. Fixes rdar://174519372.
75 lines
2.6 KiB
Swift
75 lines
2.6 KiB
Swift
//===--- String+EncodeAs.swift - PDB support for Swift --------------------===//
|
|
//
|
|
// This source file is part of the Swift.org open source project
|
|
//
|
|
// Copyright (c) 2025 Apple Inc. and the Swift project authors
|
|
// Licensed under Apache License v2.0 with Runtime Library Exception
|
|
//
|
|
// See https://swift.org/LICENSE.txt for license information
|
|
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// Extends `String` to add support for encoding.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
import Swift
|
|
|
|
extension String {
|
|
/// Calls a closure with a pointer to a buffer containing an encoded
|
|
/// version of this string.
|
|
///
|
|
/// - Parameters:
|
|
/// - encodedAs: The encoding to use.
|
|
/// - trailingNul: If `true`, append a NUL to the end of the encoded result.
|
|
/// - body: The closure to call.
|
|
///
|
|
/// - Returns: The resutn value, if any, of the `body` closure parameeter.
|
|
func withString<Result, TargetEncoding: Unicode.Encoding>(
|
|
encodedAs targetEncoding: TargetEncoding.Type,
|
|
trailingNul: Bool = false,
|
|
_ body: (UnsafeBufferPointer<TargetEncoding.CodeUnit>) throws -> Result
|
|
) rethrows -> Result {
|
|
var copy = self
|
|
return try copy.withUTF8 { utf8 in
|
|
var arg = Array<TargetEncoding.CodeUnit>()
|
|
arg.reserveCapacity(1 &+ utf8.count / 4)
|
|
let repaired = unsafe transcode(
|
|
utf8.makeIterator(),
|
|
from: UTF8.self,
|
|
to: targetEncoding,
|
|
stoppingOnError: false,
|
|
into: { arg.append($0) })
|
|
if trailingNul {
|
|
arg.append(TargetEncoding.CodeUnit(0))
|
|
}
|
|
if repaired {
|
|
fatalError("Encoding failed")
|
|
}
|
|
return try arg.withUnsafeBufferPointer {
|
|
return try unsafe body($0)
|
|
}
|
|
}
|
|
}
|
|
|
|
/// Calls a closure with a pointer to a buffer containing the raw
|
|
/// bytes of an encoded version of this string.
|
|
///
|
|
/// - Parameters:
|
|
/// - encodedAs: The encoding to use.
|
|
/// - trailingNul: If `true`, append a NUL to the end of the encoded result.
|
|
/// - body: The closure to call.
|
|
///
|
|
/// - Returns: The resutn value, if any, of the `body` closure parameeter.
|
|
func withBytes<Result, TargetEncoding: Unicode.Encoding>(
|
|
encodedAs targetEncoding: TargetEncoding.Type,
|
|
trailingNul: Bool = false,
|
|
_ body: (UnsafeRawBufferPointer) throws -> Result
|
|
) rethrows -> Result {
|
|
return try withString(encodedAs: targetEncoding) {
|
|
return try unsafe body(UnsafeRawBufferPointer($0))
|
|
}
|
|
}
|
|
}
|