Repository: apple/swift-nio
File: Sources/NIOCore/ByteBuffer-views.swift (Swift)

Code before:
    @inlinable
    public func _failEarlyRangeCheck(_ index: Index, bounds: Range<Index>) {}
    
    @inlinable
    public func _failEarlyRangeCheck(_ index: Index, bounds: ClosedRange<Index>) {}
    
    @inlinable
    public func _failEarlyRangeCheck(_ range: Range<Index>, bounds: Range<Index>) {}
}

extension ByteBufferView: MutableCollection {}

extension ByteBufferView: RangeReplaceableCollection {
    // required by `RangeReplaceableCollection`
    @inlinable
    public init() {
        self = ByteBufferView(ByteBuffer())
    }

    /// Reserves enough space in the underlying `ByteBuffer` to store the specified
    /// number of bytes.
    ///
    /// See the documentation for ``ByteBuffer.reserveCapacity(_:)`` for more details.
    @inlinable
    public mutating func reserveCapacity(_ minimumCapacity: Int) {
        self._buffer.reserveCapacity(minimumCapacity)
    }

    /// Writes a single byte to the underlying `ByteBuffer`.
    @inlinable
    public mutating func append(_ byte: UInt8) {
        self._buffer.writeBytes(CollectionOfOne<UInt8>(byte))
    }

    /// Writes a sequence of bytes to the underlying `ByteBuffer`.
    @inlinable
    public mutating func append<Bytes: Sequence>(contentsOf bytes: Bytes) where Bytes.Element == UInt8 {
        self._buffer.writeBytes(bytes)
    }

    @inlinable
    public mutating func replaceSubrange<C: Collection>(_ subrange: Range<Index>, with newElements: C) where ByteBufferView.Element == C.Element {
        precondition(subrange.startIndex >= self.startIndex && subrange.endIndex <= self.endIndex,
                     "subrange out of bounds")

        if newElements.count == subrange.count {
            self._buffer.setBytes(newElements, at: subrange.startIndex)
        } else if newElements.count < subrange.count {
            // Replace the subrange.
            self._buffer.setBytes(newElements, at: subrange.startIndex)


Review comment (suggestion):
We don't necessarily care here, but `ByteBuffer`'s `reserveCapacity` method doesn't have exactly the semantics we want. Specifically it completely disregards the reader/writer indices, so if this `ByteBufferView` is a slice of a larger buffer, we need to be a little careful. In this instance, we probably want to do something like this:

```swift
let currentBufferCapacity = self._buffer.capacity
let currentViewSize = self.count
let requestedExtraCapacity = max(minimumCapacity - currentViewSize, 0)
self._buffer.reserveCapacity(currentBufferCapacity + requestedExtraCapacity)
```

Code after:
    @inlinable
    public func _failEarlyRangeCheck(_ index: Index, bounds: Range<Index>) {}
    
    @inlinable
    public func _failEarlyRangeCheck(_ index: Index, bounds: ClosedRange<Index>) {}
    
    @inlinable
    public func _failEarlyRangeCheck(_ range: Range<Index>, bounds: Range<Index>) {}
}

extension ByteBufferView: MutableCollection {}

extension ByteBufferView: RangeReplaceableCollection {
    // required by `RangeReplaceableCollection`
    @inlinable
    public init() {
        self = ByteBufferView(ByteBuffer())
    }

    /// Reserves enough space in the underlying `ByteBuffer` such that this view can
    /// store the specified number of bytes without reallocation.
    ///
    /// See the documentation for ``ByteBuffer.reserveCapacity(_:)`` for more details.
    @inlinable
    public mutating func reserveCapacity(_ minimumCapacity: Int) {
        let additionalCapacity = minimumCapacity - self.count
        if additionalCapacity > 0 {
            self._buffer.reserveCapacity(self._buffer.capacity + additionalCapacity)
        }
    }

    /// Writes a single byte to the underlying `ByteBuffer`.
    @inlinable
    public mutating func append(_ byte: UInt8) {
        // ``CollectionOfOne`` has no witness for
        // ``Sequence.withContiguousStorageIfAvailable(_:)``. so we do this instead:
        self._buffer.setInteger(byte, at: self._range.upperBound)
        self._range = self._range.lowerBound ..< self._range.upperBound.advanced(by: 1)
        self._buffer.moveWriterIndex(to: self._range.upperBound)
    }

    /// Writes a sequence of bytes to the underlying `ByteBuffer`.
    @inlinable
    public mutating func append<Bytes: Sequence>(contentsOf bytes: Bytes) where Bytes.Element == UInt8 {
        let written = self._buffer.setBytes(bytes, at: self._range.upperBound)
        self._range = self._range.lowerBound ..< self._range.upperBound.advanced(by: written)
        self._buffer.moveWriterIndex(to: self._range.upperBound)
    }

    @inlinable
    public mutating func replaceSubrange<C: Collection>(_ subrange: Range<Index>, with newElements: C) where ByteBufferView.Element == C.Element {