StructureNIOCore

    ByteBuffer

    ByteBuffer stores contiguously allocated raw bytes. It is a random and sequential accessible sequence of zero or more bytes (octets).

    struct ByteBuffer

    Overview

    Allocation

    Use allocator.buffer(capacity: desiredCapacity) to allocate a new ByteBuffer.

    Supported types

    A variety of types can be read/written from/to a ByteBuffer. Using Swift’s extension mechanism you can easily create ByteBuffer support for your own data types. Out of the box, ByteBuffer supports for example the following types (non-exhaustive list):

    • String/StaticString

    • Swift’s various (unsigned) integer types

    • Foundation’s Data

    • [UInt8] and generally any Collection of UInt8

    Random Access

    For every supported type ByteBuffer usually contains two methods for random access:

    1. get<Type>(at: Int, length: Int) where <type> is for example String, Data, Bytes (for [UInt8])

    2. set<Type>(at: Int)

    Example:

    var buf = ...
    buf.setString("Hello World", at: 0)
    buf.moveWriterIndex(to: 11)
    let helloWorld = buf.getString(at: 0, length: 11)
    
    let written = buf.setInteger(17 as Int, at: 11)
    buf.moveWriterIndex(forwardBy: written)
    let seventeen: Int? = buf.getInteger(at: 11)

    If needed, ByteBuffer will automatically resize its storage to accommodate your set request.

    Sequential Access

    ByteBuffer provides two properties which are indices into the ByteBuffer to support sequential access:

    • readerIndex, the index of the next readable byte

    • writerIndex, the index of the next byte to write

    For every supported type ByteBuffer usually contains two methods for sequential access:

    1. read<Type>(length: Int) to read length bytes from the current readerIndex (and then advance the reader index by length bytes)

    2. write<Type>(Type) to write, advancing the writerIndex by the appropriate amount

    Example:

     var buf = ...
     buf.writeString("Hello World")
     buf.writeInteger(17 as Int)
     let helloWorld = buf.readString(length: 11)
     let seventeen: Int = buf.readInteger()

    Layout

    +-------------------+------------------+------------------+
    | discardable bytes |  readable bytes  |  writable bytes  |
    |                   |     (CONTENT)    |                  |
    +-------------------+------------------+------------------+
    |                   |                  |                  |
    0      <=      readerIndex   <=   writerIndex    <=    capacity

    The ‘discardable bytes’ are usually bytes that have already been read, they can however still be accessed using the random access methods. ‘Readable bytes’ are the bytes currently available to be read using the sequential access interface (read<Type>/write<Type>). Getting writableBytes (bytes beyond the writer index) is undefined behaviour and might yield arbitrary bytes (not 0 initialised).

    Slicing

    ByteBuffer supports slicing a ByteBuffer without copying the underlying storage.

    Example:

    var buf = ...
    let dataBytes: [UInt8] = [0xca, 0xfe, 0xba, 0xbe]
    let dataBytesLength = UInt32(dataBytes.count)
    buf.writeInteger(dataBytesLength) /* the header */
    buf.writeBytes(dataBytes) /* the data */
    let bufDataBytesOnly = buf.getSlice(at: 4, length: dataBytes.count)
    /* `bufDataByteOnly` and `buf` will share their storage */

    Notes

    All ByteBuffer methods that don’t contain the word ‘unsafe’ will only allow you to access the ‘readable bytes’.

    Members

    Initializers

    NIOFoundationCompat

    Instance Properties

    • var capacity: Int

      The current capacity of the storage of this ByteBuffer, this is not constant and does not signify the number of bytes that have been written to this ByteBuffer.

    • var debugDescription: String

      A String describing this ByteBuffer with some portion of the readable bytes dumped too. Example:

    • var description: String

      A String describing this ByteBuffer. Example:

    • var halfWidthCornerQuoted: String
    • var readableBytes: Int

      The number of bytes readable (readableBytes = writerIndex - readerIndex).

    • var readableBytesView: ByteBufferView

      A view into the readable bytes of the ByteBuffer.

    • var readerIndex: Int

      The reader index or the number of bytes previously read from this ByteBuffer. readerIndex is 0 for a newly allocated ByteBuffer.

    • var storageCapacity: Int

      The current capacity of the underlying storage of this ByteBuffer. A COW slice of the buffer (e.g. readSlice(length: x)) will posses the same storageCapacity as the original buffer until new data is written.

    • var writableBytes: Int

      The number of bytes writable until ByteBuffer will need to grow its underlying storage which will likely trigger a copy of the bytes.

    • var writerIndex: Int

      The write index or the number of bytes previously written to this ByteBuffer. writerIndex is 0 for a newly allocated ByteBuffer.

    Type Methods

      DNSClient

      Instance Methods

      NIOFoundationCompat

      NIOWebSocket

      MongoCore

      Type Operators

      Enumerations

        NIOFoundationCompat

        Structures

        Removed Members

        Instance Methods