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

Code before:

    /// Returns a `String` of hexadecimal digits of bytes in the Buffer,
    /// with formatting compatible with output of `hexdump -C`.
    func hexDumpLong() -> String {
        var result = self._hexDumpLines(offset: 0)
        result += String(byte: self.readableBytes, padding: 8)
        return result
    }

    /// Returns a `String` of hexadecimal digits of bytes in this ByteBuffer
    /// with formatting sort of compatible with `hexdump -C`, but clipped on length.
    /// Dumps limit/2 first and limit/2 last bytes, with a separator line in between.
    ///
    /// - parameters:
    ///     - limit: Max bytes to dump.
    func hexDumpLong(limit: Int) -> String {
        guard readableBytes > limit else {
            return self.hexDumpLong()
        }

        let separator = "                                     ...                                      \n"
        var result = ""

        var buffer = self
        let front = buffer.readSlice(length: limit / 2)!
        buffer.moveReaderIndex(forwardBy: buffer.readableBytes - limit / 2)
        let back = buffer.readSlice(length: buffer.readableBytes)!

        result += front._hexDumpLines(offset: 0)
        result += separator
        result += back._hexDumpLines(offset: self.readableBytes - limit/2)
        result += String(byte: self.readableBytes, padding: 8)
        return result
    }

    /// hexDump this `ByteBuffer` in a preferred `HexDumpFormat`.
    /// hexDump will dump only the readable bytes, from `readerIndex` to `writerIndex`. You're responsible for setting those indices or slicing into the part that you want to be dumped.
    ///
    /// - parameters:
    ///     - format: ``HexDumpFormat`` to use for the dump.
    public func hexDump(format: HexDumpFormat) -> String {
        switch(format.value) {
        case .xxdCompatible(let maxLength):
            if let maxLength {
                return self.hexDumpShort(limit: maxLength)
            } else {
                return self.hexDumpShort()
            }

        case .hexDumpCompatible(let maxLength):
            if let maxLength {

Review comment (suggestion):
Same note here about maybe using a `moveReaderIndex(to:)`.

Code after:
        result += String(repeating: " ", count: 60 - result.count)

        // Right column renders the 16 bytes line as ASCII characters, or "." if the character is not printable.
        let printableRange = UInt8(ascii: " ") ..< UInt8(ascii: "~")
        let printableBytes = self.readableBytesView.map {
            printableRange.contains($0) ? $0 : UInt8(ascii: ".")
        }

        result += "|"
        result += String(repeating: " ", count: paddingBefore)
        result += String(decoding: printableBytes, as: UTF8.self)
        result += String(repeating: " ", count: paddingAfter)
        result += "|\n"
        return result
    }

    /// Returns a `String` of hexadecimal digits of bytes in the Buffer,
    /// with formatting compatible with output of `hexdump -C`.
    private func hexdumpDetailed() -> String {
        if self.readableBytes == 0 {
            return ""
        }

        var result = ""
        result.reserveCapacity(self.readableBytes / 16 * 79 + 8)

        var buffer = self

        var lineOffset = 0
        while buffer.readableBytes > 0 {
            // Safe to force-unwrap because we're in a loop that guarantees there's at least one byte to read.
            let slice = buffer.readSlice(length: min(16, buffer.readableBytes))!
            result += slice._hexDumpLine(lineOffset: lineOffset)
            lineOffset += slice.readableBytes
        }

        result += String(self.readableBytes, radix: 16, padding: 8)
        return result
    }

    /// Returns a `String` of hexadecimal digits of bytes in this ByteBuffer
    /// with formatting sort of compatible with `hexdump -C`, but clipped on length.
    /// Dumps limit/2 first and limit/2 last bytes, with a separator line in between.
    ///
    /// - parameters:
    ///     - maxBytes: Max bytes to dump.
    private func hexDumpDetailed(maxBytes: Int) -> String {
        if self.readableBytes <= maxBytes {
            return self.hexdumpDetailed()
        }