//
// Copyright (c) 2007, Brian Frank and Andy Frank
// Licensed under the Academic Free License version 3.0
//
// History:
// 9 Feb 07 Brian Frank Creation
//
**
** SocketOptions groups together all the socket options used to tune a
** TcpSocket, TcpListener, or UdpSocket. See the options method of each
** of those classes for which options apply. Accessing an unsupported
** option for a particular socket type will throw UnsupportedErr.
**
final class SocketOptions
{
//////////////////////////////////////////////////////////////////////////
// Construction
//////////////////////////////////////////////////////////////////////////
**
** Attach this options instance to the specific socket (we just
** use an Obj because everything is dynamically typed)
**
internal new make(Obj socket)
{
this.socket = socket;
}
//////////////////////////////////////////////////////////////////////////
// Copy From
//////////////////////////////////////////////////////////////////////////
**
** Set all of this instance's options from the specified options.
**
Void copyFrom(SocketOptions options)
{
Type.of(this).fields.each |Field f|
{
try
{
v := f.get(options)
// Setting traffic class to zero is unreliable across OS
if (v == 0 && f.name == "trafficClass") return
f.set(this, v)
}
catch (UnsupportedErr e)
{}
}
}
//////////////////////////////////////////////////////////////////////////
// Streaming Options
//////////////////////////////////////////////////////////////////////////
**
** The size in bytes for the sys::InStream buffer. A value of 0 or
** null disables input stream buffing. This field may only be set before
** the socket is connected otherwise Err is thrown.
**
Int? inBufferSize
{
get { return (Int?)wrap |->Obj?| { return socket->getInBufferSize } }
set { newVal := it; wrap |->| { socket->setInBufferSize(newVal) } }
}
**
** The size in bytes for the sys::OutStream buffer. A value of 0 or
** null disables output stream buffing. This field may only be set before
** the socket is connected otherwise Err is thrown.
**
Int? outBufferSize
{
get { return (Int?)wrap |->Obj?| { return socket->getOutBufferSize } }
set { newVal := it; wrap |->| { socket->setOutBufferSize(newVal) } }
}
//////////////////////////////////////////////////////////////////////////
// Socket Options
//////////////////////////////////////////////////////////////////////////
**
** SO_BROADCAST socket option.
**
Bool broadcast
{
get { return (Bool)wrap |->Obj| { return socket->getBroadcast } }
set { newVal := it; wrap |->| { socket->setBroadcast(newVal) } }
}
**
** SO_KEEPALIVE socket option.
**
Bool keepAlive
{
get { return (Bool)wrap |->Obj| { return socket->getKeepAlive } }
set { newVal := it; wrap |->| { socket->setKeepAlive(newVal) } }
}
**
** SO_RCVBUF option for the size in bytes of the IP stack buffers.
**
Int receiveBufferSize
{
get { return (Int)wrap |->Obj| { return socket->getReceiveBufferSize } }
set { newVal := it; wrap |->| { socket->setReceiveBufferSize(newVal) } }
}
**
** SO_SNDBUF option for the size in bytes of the IP stack buffers.
**
Int sendBufferSize
{
get { return (Int)wrap |->Obj| { return socket->getSendBufferSize } }
set { newVal := it; wrap |->| { socket->setSendBufferSize(newVal) } }
}
**
** SO_REUSEADDR socket option is used to control the time
** wait state of a closed socket.
**
Bool reuseAddr
{
get { return (Bool)wrap |->Obj| { return socket->getReuseAddr } }
set { newVal := it; wrap |->| { socket->setReuseAddr(newVal) } }
}
**
** SO_LINGER socket option controls the linger time or set
** to null to disable linger.
**
Duration? linger
{
get { return (Duration?)wrap |->Obj?| { return socket->getLinger} }
set { newVal := it; wrap |->| { socket->setLinger(newVal) } }
}
**
** Controls default timeout used by `TcpSocket.connect`.
** A null value indicates a system default timeout.
**
@Deprecated { msg = "Use SocketConfig.connectTimeout" }
Duration? connectTimeout
**
** SO_TIMEOUT socket option controls the amount of time this socket
** will block on a read call before throwing an IOErr timeout exception.
** Null is used to indicate an infinite timeout.
**
Duration? receiveTimeout
{
get { return (Duration?)wrap |->Obj?| { return socket->getReceiveTimeout } }
set { newVal := it; wrap |->| { socket->setReceiveTimeout(newVal) } }
}
**
** TCP_NODELAY socket option specifies that send not be delayed
** to merge packets (Nagle's algorthm).
**
Bool noDelay
{
get { return (Bool)wrap |->Obj| { return socket->getNoDelay } }
set { newVal := it; wrap |->| { socket->setNoDelay(newVal) } }
}
**
** The type-of-class byte in the IP packet header.
**
** For IPv4 this value is detailed in RFC 1349 as the following bitset:
** - IPTOS_LOWCOST (0x02)
** - IPTOS_RELIABILITY (0x04)
** - IPTOS_THROUGHPUT (0x08)
** - IPTOS_LOWDELAY (0x10)
**
** For IPv6 this is the value placed into the sin6_flowinfo header field.
**
Int trafficClass
{
get { return (Int)wrap |->Obj| { return socket->getTrafficClass } }
set { newVal := it; wrap |->| { socket->setTrafficClass(newVal) } }
}
//////////////////////////////////////////////////////////////////////////
// Wrap
//////////////////////////////////////////////////////////////////////////
internal Obj? wrap(|->Obj?| m)
{
try
{
return m()
}
catch (UnknownSlotErr e)
{
throw UnsupportedErr("Option not supported for ${Type.of(socket)}")
}
}
//////////////////////////////////////////////////////////////////////////
// Fields
//////////////////////////////////////////////////////////////////////////
private Obj socket
}