/* -*- Mode: C; c-file-style: "gnu" -*-
   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 "jni.h"
#include "jniint.h"
#include "objects.h"
#include "ClazzFile.h"
#include "resolve.h"

#include <string.h>
#include <stdlib.h>
#include <assert.h>

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

  cf->classloader = loader;

  cls = clazzfile_to_jclass(env, cf);

  return cls;
}

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

  cf = find_class(env, name);

  if (!cf)
    {
      /* XXX avoid endless recursion if ClassNotFoundException is not found */
      if (0 != 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(env, cf);
    }
}

jclass
JNIFUNC(GetSuperclass)(JNIEnv *env,
		       jclass clazz)
{
  ClazzFile *clazzfile = jclass_to_clazzfile(env, 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(env, clazzfile->superclass);
}

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

  return is_assignable_from(env, clazzfile1, clazzfile2);
}
