/* -*- Mode: C; c-file-style: "gnu"; indent-tabs-mode:nil -*-
   jniclass.c -- Java Native Interface methods relating to classes.
   Created: Chris Toshok <toshok@hungry.com>, 26-Jul-1997
 */
/*
  This file is part of Japhar, the GNU Virtual Machine for Java Bytecodes.
  Japhar is a project of The Hungry Programmers, GNU, and OryxSoft.

  Copyright (C) 1997, 1998, 1999 The Hungry Programmers

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

  This library 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
  Library General Public License for more details.

  You should have received a copy of the GNU Library General Public
  License along with this library; if not, write to the Free Software
  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include "jniint.h"

jclass
JNIFUNC(DefineClass)(JNIEnv *env,
                     jobject loader,
                     const jbyte* buf,
                     jsize bufLen)
{
  HungryEnv *henv = JNIEnvToHEnv(env);
  ClazzFile *cf;
  jclass cls;

  cf = HVM_ClassDefine(henv, buf, bufLen);
  cf->classloader = loader;

  cls = clazzfile_to_jclass(henv, cf);

  return cls;
}

#define ClassNotFoundException "java/lang/ClassNotFoundException"
jclass
JNIFUNC(FindClass)(JNIEnv *env,
                   const char *name)
{
  HungryEnv *henv = JNIEnvToHEnv(env);
  ClazzFile *cf;

  cf = HVM_ClassFind(henv, name);

  if (!cf)
    {
      /* XXX avoid endless recursion if ClassNotFoundException is not found */
      if (0 != PL_strcmp(name, ClassNotFoundException))
        {
          jclass class_not_found = (*env)->FindClass(env,       
                                                     ClassNotFoundException);
          if (class_not_found) /* Avoid calling class if it was not found */
            (*env)->ThrowNew(env, class_not_found, name);
        }
      return NULL;
    }
  else
    {
      return clazzfile_to_jclass(henv, cf);
    }
}

jclass
JNIFUNC(GetSuperclass)(JNIEnv *env,
                       jclass clazz)
{
  HungryEnv *henv = JNIEnvToHEnv(env);
  ClazzFile *clazzfile = jclass_to_clazzfile(henv, clazz);

  /* if clazz specifies the class Object, or clazz represents an
   * interface, this function returns NULL */
  if (clazzfile->access_flags & ACC_INTERFACE
      || clazzfile->superclass == NULL)
    return NULL;
  else
    return clazzfile_to_jclass(henv, clazzfile->superclass);
}

jboolean
JNIFUNC(IsAssignableFrom)(JNIEnv *env,
                          jclass clazz1,
                          jclass clazz2)
{
  HungryEnv *henv = JNIEnvToHEnv(env);
  ClazzFile *clazzfile1 = jclass_to_clazzfile(henv, clazz1);
  ClazzFile *clazzfile2 = jclass_to_clazzfile(henv, clazz2);

  return HVM_ClassIsAssignableFrom(henv, clazzfile1, clazzfile2);
}
