From 7ec0281c1fde432356d7893ba86008cf63f11891 Mon Sep 17 00:00:00 2001 From: Gwynne Raskind Date: Mon, 7 Feb 2022 08:24:48 -0600 Subject: [PATCH] `Substring.UTF8View` began implementing `Collection.withContiguousStorageIfAvailable(_:)` starting in Swift 5.3. Update `ByteBuffer.setSubstring(_:at:)` to use it to avoid a conversion to `String` in the common case. (#1975) Co-authored-by: George Barnett Co-authored-by: Cory Benfield --- Sources/NIOCore/ByteBuffer-aux.swift | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/Sources/NIOCore/ByteBuffer-aux.swift b/Sources/NIOCore/ByteBuffer-aux.swift index cff549d38f..fee72661b7 100644 --- a/Sources/NIOCore/ByteBuffer-aux.swift +++ b/Sources/NIOCore/ByteBuffer-aux.swift @@ -125,9 +125,9 @@ extension ByteBuffer { @discardableResult @inlinable public mutating func setString(_ string: String, at index: Int) -> Int { - // Do not implement setString via setSubstring. As of Swift version 5.1.3, - // Substring.UTF8View does not implement withContiguousStorageIfAvailable - // and therefore has no fast access to the backing storage. + // Do not implement setString via setSubstring. Before Swift version 5.3, + // Substring.UTF8View did not implement withContiguousStorageIfAvailable + // and therefore had no fast access to the backing storage. if let written = string.utf8.withContiguousStorageIfAvailable({ utf8Bytes in self.setBytes(utf8Bytes, at: index) }) { @@ -236,16 +236,22 @@ extension ByteBuffer { /// /// - parameters: /// - substring: The substring to write. - /// - index: The index for the first serilized byte. + /// - index: The index for the first serialized byte. /// - returns: The number of bytes written @discardableResult @inlinable public mutating func setSubstring(_ substring: Substring, at index: Int) -> Int { - // As of Swift 5.1.3, Substring.UTF8View does not implement - // withContiguousStorageIfAvailable and therefore has no fast access - // to the backing storage. For now, convert to a String and call - // setString instead. - return self.setString(String(substring), at: index) + // Substring.UTF8View implements withContiguousStorageIfAvailable starting with + // Swift version 5.3. + if let written = substring.utf8.withContiguousStorageIfAvailable({ utf8Bytes in + self.setBytes(utf8Bytes, at: index) + }) { + // fast path, directly available + return written + } else { + // slow path, convert to string + return self.setString(String(substring), at: index) + } } // MARK: DispatchData APIs