/*
  Defines standard includes for native primitives.

  @author Jeff Schoen
  @version $Id: native.h,v 1.20 2011/12/09 19:53:26 jgs Exp $
*/
#ifndef _native_h

#ifdef __CYGWIN32__
# define __int64	long long
#endif

#include <jni.h>
#include <math.h>
#include <stdio.h>
#include <inttypes.h> /* C99 for uintptr_t to hold value of a pointer */
#if _UNIX
#include <string.h>
#include <sys/types.h>
#endif

#define jpointer uintptr_t
/* #define jpointer long  -  definition prior to 3.0.0 */

#define GetArray(A) \
  (*env)->GetPrimitiveArrayCritical (env,(jarray)A,0)
#define ReleaseArray(A,B) \
  (*env)->ReleasePrimitiveArrayCritical (env,(jarray)A,B,0)

/* jboolean *isCopy:
   If isCopy is not NULL, then *isCopy is set to JNI_TRUE if a copy is made;
   or it is set to JNI_FALSE if no copy is made.
   @since NeXtMidas 2.7.0
*/
#define GetArray1(env,A,isCopy) \
  (*env)->GetPrimitiveArrayCritical (env,(jarray)A,isCopy)
/* jint mode:
   0          = copy back the content and free the elems (B) buffer
   JNI_COMMIT = copy back the content but do not free the elems (B) buffer
   JNI_ABORT  = free the buffer (B) without copying back the possible changes
   @since NeXtMidas 2.7.0
 */
#define ReleaseArray1(env,A,B,mode) \
  (*env)->ReleasePrimitiveArrayCritical (env,(jarray)A,B,mode)
/* @since NeXtMidas 2.7.0 */
#define ReleaseArrayNoCopyBack(env,A,B) \
  (*env)->ReleasePrimitiveArrayCritical (env,(jarray)A,B,JNI_ABORT)


#define GetString(A) \
  (*env)->GetStringUTFChars(env,(jstring)A,0)
#define ReleaseString(A,B) \
  (*env)->ReleaseStringUTFChars(env,A,B)
#define NewString(A) \
  (*env)->NewStringUTF(env,A)

#define GetClass(A) \
  (*env)->GetObjectClass(env,A)
#define GetField(A,B,C) \
  (*env)->GetFieldID(env,(*env)->GetObjectClass(env,A),B,C)
#define GetClassField(A,B,C) \
  (*env)->GetFieldID(env,A,B,C)
/* since 2.7.2 to get static field from class */
#define GetStaticField(OBJ,FIELDNAME,FILEDTYPE) \
  (*env)->GetStaticFieldID(env, GetClass(OBJ), FIELDNAME, FILEDTYPE)

#define GetPointer(A,B) \
  (jint *)(jpointer)(*env)->GetLongField(env,A,GetField(A,B,"J"))
#define SetPointer(A,B,C) \
  (*env)->SetLongField(env,A,GetField(A,B,"J"),(jlong)(jpointer)C)

#define GetLong(A,B) \
  (*env)->GetLongField(env,A,GetField(A,B,"J"))
#define SetLong(A,B,C) \
  (*env)->SetLongField(env,A,GetField(A,B,"J"),(jlong)C)

#define GetInt(A,B) \
  (*env)->GetIntField(env,A,GetField(A,B,"I"))
#define SetInt(A,B,C) \
  (*env)->SetIntField(env,A,GetField(A,B,"I"),(jint)C)
/* since 2.7.2 to get static int field from class */
#define GetStaticInt(A,B) \
  (*env)->GetStaticIntField(env, GetClass(A), GetStaticField(A,B,"I"))

#define GetFloat(A,B) \
  (*env)->GetFloatField(env,A,GetField(A,B,"F"))
#define SetFloat(A,B,C) \
  (*env)->SetFloatField(env,A,GetField(A,B,"F"),(jfloat)C)

#define GetDouble(A,B) \
  (*env)->GetDoubleField(env,A,GetField(A,B,"D"))
#define SetDouble(A,B,C) \
  (*env)->SetDoubleField(env,A,GetField(A,B,"D"),(jdouble)C)

#define GetObject(A,B,C) \
  (*env)->GetObjectField(env,A,GetField(A,B,C))
#define SetObject(A,B,C,D) \
  (*env)->SetObjectField(env,A,GetField(A,B,C),(jobject)D)

#define GetStringObject(A,B) \
  (*env)->GetObjectField(env,A,GetField(A,B,"Ljava/lang/String;"))

#define GetStaticMethod(A,B,C) \
  (*env)->GetStaticMethodID(env,A,B,C)

#define GetClassMethod(A,B,C) \
  (*env)->GetMethodID(env,A,B,C)

#define GetMethod(A,B,C) \
  (*env)->GetMethodID(env,(*env)->GetObjectClass(env,A),B,C)

#define HasException() \
  (*env)->ExceptionOccurred(env)

#define _native_h
#endif
