//===----------------------------------------------------------------------===// // Copyright © 2025-2026 Apple Inc. and the Containerization project authors. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. //===----------------------------------------------------------------------===// import Foundation package enum BindError: Error, CustomStringConvertible { case recvMarshalFailure(type: String, field: String) case sendMarshalFailure(type: String, field: String) package var description: String { switch self { case .recvMarshalFailure(let type, let field): return "failed to unmarshal \(type).\(field)" case .sendMarshalFailure(let type, let field): return "failed to marshal \(type).\(field)" } } } package protocol Bindable: Sendable { static var size: Int { get } func appendBuffer(_ buffer: inout [UInt8], offset: Int) throws -> Int mutating func bindBuffer(_ buffer: inout [UInt8], offset: Int) throws -> Int } extension ArraySlice { package func hexEncodedString() -> String { self.map { String(format: "%02hhx", $0) }.joined() } } extension [UInt8] { package func hexEncodedString() -> String { self.map { String(format: "%02hhx", $0) }.joined() } package mutating func bind(as type: T.Type, offset: Int = 0, size: Int? = nil) -> UnsafeMutablePointer? { guard self.count >= (size ?? MemoryLayout.size) + offset else { return nil } return self.withUnsafeMutableBytes { $0.baseAddress?.advanced(by: offset).assumingMemoryBound(to: T.self) } } package mutating func copyIn(as type: T.Type, value: T, offset: Int = 0, size: Int? = nil) -> Int? { let size = size ?? MemoryLayout.size guard self.count >= size + offset else { return nil } return self.withUnsafeMutableBytes { $0.baseAddress?.advanced(by: offset).assumingMemoryBound(to: T.self).pointee = value return offset + MemoryLayout.size } } package func copyOut(as type: T.Type, offset: Int = 0, size: Int? = nil) -> (Int, T)? { guard self.count >= (size ?? MemoryLayout.size) + offset else { return nil } return self.withUnsafeBytes { guard let value = $0.baseAddress?.advanced(by: offset).assumingMemoryBound(to: T.self).pointee else { return nil } return (offset + MemoryLayout.size, value) } } package mutating func copyIn(buffer: [UInt8], offset: Int = 0) -> Int? { guard offset + buffer.count <= self.count else { return nil } self[offset.. Int? { guard offset + buffer.count <= self.count else { return nil } buffer[0..