blob: 183747de16d25c9a398cca448aac8d496696df6a [file] [log] [blame]
/*
* Copyright 2001 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
package sun.nio.ch;
import java.io.FileDescriptor;
import java.io.IOException;
import java.net.NetworkInterface;
import java.net.SocketOptions;
import java.nio.channels.*;
class SocketOptsImpl
implements SocketOpts
{
static abstract class Dispatcher {
abstract int getInt(int opt) throws IOException;
abstract void setInt(int opt, int arg) throws IOException;
// Others that pass addresses, etc., will come later
}
private final Dispatcher d;
SocketOptsImpl(Dispatcher d) {
this.d = d;
}
protected boolean getBoolean(int opt) throws IOException {
return d.getInt(opt) > 0;
}
protected void setBoolean(int opt, boolean b) throws IOException {
d.setInt(opt, b ? 1 : 0);
}
protected int getInt(int opt) throws IOException {
return d.getInt(opt);
}
protected void setInt(int opt, int n) throws IOException {
d.setInt(opt, n);
}
protected NetworkInterface getNetworkInterface(int opt)
throws IOException
{
throw new UnsupportedOperationException("NYI");
}
protected void setNetworkInterface(int opt, NetworkInterface ni)
throws IOException
{
throw new UnsupportedOperationException("NYI");
}
protected void addToString(StringBuffer sb, String s) {
char c = sb.charAt(sb.length() - 1);
if ((c != '[') && (c != '='))
sb.append(' ');
sb.append(s);
}
protected void addToString(StringBuffer sb, int n) {
addToString(sb, Integer.toString(n));
}
// SO_BROADCAST
public boolean broadcast() throws IOException {
return getBoolean(SocketOptions.SO_BROADCAST);
}
public SocketOpts broadcast(boolean b) throws IOException {
setBoolean(SocketOptions.SO_BROADCAST, b);
return this;
}
// SO_KEEPALIVE
public boolean keepAlive() throws IOException {
return getBoolean(SocketOptions.SO_KEEPALIVE);
}
public SocketOpts keepAlive(boolean b) throws IOException {
setBoolean(SocketOptions.SO_KEEPALIVE, b);
return this;
}
// SO_LINGER
public int linger() throws IOException {
return getInt(SocketOptions.SO_LINGER);
}
public SocketOpts linger(int n) throws IOException {
setInt(SocketOptions.SO_LINGER, n);
return this;
}
// SO_OOBINLINE
public boolean outOfBandInline() throws IOException {
return getBoolean(SocketOptions.SO_OOBINLINE);
}
public SocketOpts outOfBandInline(boolean b) throws IOException {
setBoolean(SocketOptions.SO_OOBINLINE, b);
return this;
}
// SO_RCVBUF
public int receiveBufferSize() throws IOException {
return getInt(SocketOptions.SO_RCVBUF);
}
public SocketOpts receiveBufferSize(int n) throws IOException {
if (n <= 0)
throw new IllegalArgumentException("Invalid receive size");
setInt(SocketOptions.SO_RCVBUF, n);
return this;
}
// SO_SNDBUF
public int sendBufferSize() throws IOException {
return getInt(SocketOptions.SO_SNDBUF);
}
public SocketOpts sendBufferSize(int n) throws IOException {
if (n <= 0)
throw new IllegalArgumentException("Invalid send size");
setInt(SocketOptions.SO_SNDBUF, n);
return this;
}
// SO_REUSEADDR
public boolean reuseAddress() throws IOException {
return getBoolean(SocketOptions.SO_REUSEADDR);
}
public SocketOpts reuseAddress(boolean b) throws IOException {
setBoolean(SocketOptions.SO_REUSEADDR, b);
return this;
}
// toString
protected void toString(StringBuffer sb) throws IOException {
int n;
if (broadcast())
addToString(sb, "broadcast");
if (keepAlive())
addToString(sb, "keepalive");
if ((n = linger()) > 0) {
addToString(sb, "linger=");
addToString(sb, n);
}
if (outOfBandInline())
addToString(sb, "oobinline");
if ((n = receiveBufferSize()) > 0) {
addToString(sb, "rcvbuf=");
addToString(sb, n);
}
if ((n = sendBufferSize()) > 0) {
addToString(sb, "sndbuf=");
addToString(sb, n);
}
if (reuseAddress())
addToString(sb, "reuseaddr");
}
public String toString() {
StringBuffer sb = new StringBuffer();
sb.append(this.getClass().getInterfaces()[0].getName());
sb.append('[');
int i = sb.length();
try {
toString(sb);
} catch (IOException x) {
sb.setLength(i);
sb.append("closed");
}
sb.append(']');
return sb.toString();
}
// IP-specific socket options
static class IP
extends SocketOptsImpl
implements SocketOpts.IP
{
IP(Dispatcher d) {
super(d);
}
// IP_MULTICAST_IF2
// ## Do we need IP_MULTICAST_IF also?
public NetworkInterface multicastInterface() throws IOException {
return getNetworkInterface(SocketOptions.IP_MULTICAST_IF2);
}
public SocketOpts.IP multicastInterface(NetworkInterface ni)
throws IOException
{
setNetworkInterface(SocketOptions.IP_MULTICAST_IF2, ni);
return this;
}
// IP_MULTICAST_LOOP
public boolean multicastLoop() throws IOException {
return getBoolean(SocketOptions.IP_MULTICAST_LOOP);
}
public SocketOpts.IP multicastLoop(boolean b) throws IOException {
setBoolean(SocketOptions.IP_MULTICAST_LOOP, b);
return this;
}
// IP_TOS
public int typeOfService() throws IOException {
return getInt(SocketOptions.IP_TOS);
}
public SocketOpts.IP typeOfService(int tos) throws IOException {
setInt(SocketOptions.IP_TOS, tos);
return this;
}
// toString
protected void toString(StringBuffer sb) throws IOException {
super.toString(sb);
int n;
if ((n = typeOfService()) > 0) {
addToString(sb, "tos=");
addToString(sb, n);
}
}
// TCP-specific IP options
public static class TCP
extends SocketOptsImpl.IP
implements SocketOpts.IP.TCP
{
TCP(Dispatcher d) {
super(d);
}
// TCP_NODELAY
public boolean noDelay() throws IOException {
return getBoolean(SocketOptions.TCP_NODELAY);
}
public SocketOpts.IP.TCP noDelay(boolean b) throws IOException {
setBoolean(SocketOptions.TCP_NODELAY, b);
return this;
}
// toString
protected void toString(StringBuffer sb) throws IOException {
super.toString(sb);
if (noDelay())
addToString(sb, "nodelay");
}
}
}
}