/* ArrayReferenceCommandSet.java -- class to implement the Array
   Reference Command Set
   Copyright (C) 2005 Free Software Foundation

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
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.classpath.jdwp.processor;

import gnu.classpath.jdwp.JdwpConstants;
import gnu.classpath.jdwp.exception.InvalidObjectException;
import gnu.classpath.jdwp.exception.JdwpException;
import gnu.classpath.jdwp.exception.JdwpInternalErrorException;
import gnu.classpath.jdwp.exception.NotImplementedException;
import gnu.classpath.jdwp.id.ObjectId;
import gnu.classpath.jdwp.value.Value;
import gnu.classpath.jdwp.value.ValueFactory;

import java.io.DataOutputStream;
import java.io.IOException;
import java.lang.reflect.Array;
import java.nio.ByteBuffer;

/**
 * A class representing the ArrayReference Command Set.
 * 
 * @author Aaron Luchko <aluchko@redhat.com>
 */
public class ArrayReferenceCommandSet
  extends CommandSet
{
  public boolean runCommand(ByteBuffer bb, DataOutputStream os, byte command)
    throws JdwpException
  {
    try
      {
        switch (command)
          {
          case JdwpConstants.CommandSet.ArrayReference.LENGTH:
            executeLength(bb, os);
            break;
          case JdwpConstants.CommandSet.ArrayReference.GET_VALUES:
            executeGetValues(bb, os);
            break;
          case JdwpConstants.CommandSet.ArrayReference.SET_VALUES:
            executeSetValues(bb, os);
            break;
          default:
            throw new NotImplementedException("Command " + command +
              " not found in Array Reference Command Set.");
          }
      }
    catch (IOException ex)
      {
        // The DataOutputStream we're using isn't talking to a socket at all
        // So if we throw an IOException we're in serious trouble
        throw new JdwpInternalErrorException(ex);
      }

    return false;
  }

  private void executeLength(ByteBuffer bb, DataOutputStream os)
    throws InvalidObjectException, IOException
  {
    ObjectId oid = idMan.readObjectId(bb);
    Object array = oid.getObject();
    os.writeInt(Array.getLength(array));
  }

  private void executeGetValues(ByteBuffer bb, DataOutputStream os)
    throws JdwpException, IOException
  {
    ObjectId oid = idMan.readObjectId(bb);
    Object array = oid.getObject();
    int first = bb.getInt();
    int length = bb.getInt();

    // We need to write out the byte signifying the type of array first
    Class clazz = array.getClass().getComponentType();

    // Uugh, this is a little ugly but it's the only time we deal with
    // arrayregions
    if (clazz == byte.class)
      os.writeByte(JdwpConstants.Tag.BYTE);
    else if (clazz == char.class)
      os.writeByte(JdwpConstants.Tag.CHAR);
    else if (clazz == float.class)
      os.writeByte(JdwpConstants.Tag.FLOAT);
    else if (clazz == double.class)
      os.writeByte(JdwpConstants.Tag.DOUBLE);
    else if (clazz == int.class)
      os.writeByte(JdwpConstants.Tag.BYTE);
    else if (clazz == long.class)
      os.writeByte(JdwpConstants.Tag.LONG);
    else if (clazz == short.class)
      os.writeByte(JdwpConstants.Tag.SHORT);
    else if (clazz == void.class)
      os.writeByte(JdwpConstants.Tag.VOID);
    else if (clazz == boolean.class)
      os.writeByte(JdwpConstants.Tag.BOOLEAN);
    else if (clazz.isArray())
      os.writeByte(JdwpConstants.Tag.ARRAY);
    else if (String.class.isAssignableFrom(clazz))
      os.writeByte(JdwpConstants.Tag.STRING);
    else if (Thread.class.isAssignableFrom(clazz))
      os.writeByte(JdwpConstants.Tag.THREAD);
    else if (ThreadGroup.class.isAssignableFrom(clazz))
      os.writeByte(JdwpConstants.Tag.THREAD_GROUP);
    else if (ClassLoader.class.isAssignableFrom(clazz))
      os.writeByte(JdwpConstants.Tag.CLASS_LOADER);
    else if (Class.class.isAssignableFrom(clazz))
      os.writeByte(JdwpConstants.Tag.CLASS_OBJECT);
    else
      os.writeByte(JdwpConstants.Tag.OBJECT);

    // Write all the values, primitives should be untagged and Objects must be
    // tagged
    for (int i = first; i < first + length; i++)
      {
        Value val = ValueFactory.createFromObject(Array.get(array, i), clazz);
        if (clazz.isPrimitive())
          val.writeUntagged(os);
        else
          val.writeTagged(os);
      }
  }

  private void executeSetValues(ByteBuffer bb, DataOutputStream os)
    throws IOException, JdwpException
  {
    ObjectId oid = idMan.readObjectId(bb);
    Object array = oid.getObject();
    int first = bb.getInt();
    int length = bb.getInt();
    Class type = array.getClass().getComponentType();
    for (int i = first; i < first + length; i++)
      {
        Object value = Value.getUntaggedObject(bb, type);
        Array.set(array, i, value);
      }
  }
}
