Files
swift-mirror/stdlib/public/RuntimeModule/PDB/String+EncodeAs.swift
Doug Gregor 453277eb74 Mark the various with* functions as @safe
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.
2026-04-16 22:37:54 -07:00

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))
}
}
}