/* KqueueSelectionKeyImpl.java -- selection key for kqueue/kevent.
   Copyright (C) 2006 Free Software Foundation, Inc.

This file is part of GNU Classpath.

GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

GNU Classpath 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 for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */


package gnu.java.nio;


import java.nio.channels.SelectableChannel;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.spi.AbstractSelectionKey;

/**
 * @author Casey Marshall (csm@gnu.org)
 */
public class KqueueSelectionKeyImpl extends AbstractSelectionKey
{
  int interestOps;
  int readyOps;
  int activeOps = 0;
  int key;
  int fd;

  /** The selector we were created for. */
  private final KqueueSelectorImpl selector;
  
  /** The channel we are attached to. */
  private final SelectableChannel channel;
  
  private final VMChannelOwner natChannel;
  
  public KqueueSelectionKeyImpl(KqueueSelectorImpl selector,
                                SelectableChannel channel)
  {
    this.selector = selector;
    this.channel = channel;
    natChannel = (VMChannelOwner) channel;
    interestOps = 0;
    readyOps = 0;
  }

  /* (non-Javadoc)
   * @see java.nio.channels.SelectionKey#channel()
   */
  //@Override
  public SelectableChannel channel()
  {
    return channel;
  }

  /* (non-Javadoc)
   * @see java.nio.channels.SelectionKey#interestOps()
   */
  //@Override
  public int interestOps()
  {
    return interestOps;
  }

  /* (non-Javadoc)
   * @see java.nio.channels.SelectionKey#interestOps(int)
   */
  //@Override
  public SelectionKey interestOps(int ops)
  {
    if (!isValid())
      throw new IllegalStateException("key is invalid");
    if ((ops & ~channel.validOps()) != 0)
      throw new IllegalArgumentException("channel does not support all operations");
    
    selector.setInterestOps(this, ops);
    return this;
  }

  /* (non-Javadoc)
   * @see java.nio.channels.SelectionKey#readyOps()
   */
  //@Override
  public int readyOps()
  {
    return readyOps;
  }

  /* (non-Javadoc)
   * @see java.nio.channels.SelectionKey#selector()
   */
  //@Override
  public Selector selector()
  {
    return selector;
  }
  
  public String toString()
  {
    if (!isValid())
      return super.toString() + " [ fd: " + fd + " <<invalid>> ]";
    return super.toString() + " [ fd: " + fd + " interest ops: {"
      + ((interestOps & OP_ACCEPT) != 0 ? " OP_ACCEPT" : "")
      + ((interestOps & OP_CONNECT) != 0 ? " OP_CONNECT" : "")
      + ((interestOps & OP_READ) != 0 ? " OP_READ" : "")
      + ((interestOps & OP_WRITE) != 0 ? " OP_WRITE" : "")
      + " }; ready ops: {"
      + ((readyOps & OP_ACCEPT) != 0 ? " OP_ACCEPT" : "")
      + ((readyOps & OP_CONNECT) != 0 ? " OP_CONNECT" : "")
      + ((readyOps & OP_READ) != 0 ? " OP_READ" : "")
      + ((readyOps & OP_WRITE) != 0 ? " OP_WRITE" : "")
      + " } ]";
  }
  
  public int hashCode()
  {
    return fd;
  }
  
  public boolean equals(Object o)
  {
    if (!(o instanceof KqueueSelectionKeyImpl))
      return false;
    KqueueSelectionKeyImpl that = (KqueueSelectionKeyImpl) o;
    return that.fd == this.fd && that.channel.equals(this.channel);
  }
  
  
  boolean isReadActive()
  {
    return (activeOps & (OP_READ | OP_ACCEPT)) != 0;
  }

  boolean isReadInterested()
  {
    return (interestOps & (OP_READ | OP_ACCEPT)) != 0;
  }
  
  boolean isWriteActive()
  {
    return (activeOps & (OP_WRITE | OP_CONNECT)) != 0;
  }
  
  boolean isWriteInterested()
  {
    return (interestOps & (OP_WRITE | OP_CONNECT)) != 0;
  }
  
  boolean needCommitRead()
  {
    return isReadActive() == (!isReadInterested());
  }

  boolean needCommitWrite()
  {
    return isWriteActive() == (!isWriteInterested());
  }
}
