connected_udp_runtime_backend.pony

use @pony_os_udp_connect[I32](fd: U32,
  host: Pointer[U8] tag,
  port: Pointer[U8] tag)
use @pony_os_udp_connect4[I32](fd: U32,
  host: Pointer[U8] tag,
  port: Pointer[U8] tag)
use @pony_os_udp_connect6[I32](fd: U32,
  host: Pointer[U8] tag,
  port: Pointer[U8] tag)
use @pony_os_udp_send[U8](fd: U32,
  data: Pointer[U8] tag,
  size: USize,
  count_out: Pointer[USize])

class ConnectedUDPRuntimeBackend is ConnectedUDPBackend
  """
  Wrappers for the runtime's `pony_os_*` connected UDP functions.
  """
  new create() => None

  fun ref bind(the_actor: AsioEventNotify,
    host: String,
    port: String,
    ip_version: IPVersion = DualStack)
    : AsioEventID
  =>
    match \exhaustive\ ip_version
    | IP4 =>
      @pony_os_listen_udp4(the_actor, host.cstring(), port.cstring())
    | IP6 =>
      @pony_os_listen_udp6(the_actor, host.cstring(), port.cstring())
    | DualStack =>
      @pony_os_listen_udp(the_actor, host.cstring(), port.cstring())
    end

  fun ref connect(fd: U32,
    host: String,
    port: String,
    ip_version: IPVersion = DualStack)
    : Bool
  =>
    let result: I32 =
      match \exhaustive\ ip_version
      | IP4 =>
        @pony_os_udp_connect4(fd, host.cstring(), port.cstring())
      | IP6 =>
        @pony_os_udp_connect6(fd, host.cstring(), port.cstring())
      | DualStack =>
        @pony_os_udp_connect(fd, host.cstring(), port.cstring())
      end
    result == 0

  fun ref close(fd: U32) =>
    @pony_os_socket_close(fd)

  fun ref recvfrom(event: AsioEventID,
    buffer: Pointer[U8] tag,
    size: USize)
    : (SocketResult, USize, NetAddress iso^)
  =>
    """
    Read one datagram via `@pony_os_recvfrom`.
    """
    var count: USize = 0
    let from = recover iso NetAddress end
    let result =
      SocketResultDecoder(
        @pony_os_recvfrom(event, buffer, size, from, addressof count))
    (result, count, consume from)

  fun ref send(fd: U32, data: ByteSeq): SocketResult =>
    var count: USize = 0
    SocketResultDecoder(
      @pony_os_udp_send(fd, data.cpointer(), data.size(), addressof count))

  fun ref sockname(fd: U32, ip: NetAddress tag): Bool =>
    @pony_os_sockname(fd, ip)

  fun ref peername(fd: U32, ip: NetAddress tag): Bool =>
    @pony_os_peername(fd, ip)