/**********************************************************************
 * Copyright (c) 2005, 2007 IBM Corporation and others.
 * All rights reserved.   This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 * $Id: utility.h,v 1.2 2007/04/06 00:59:27 jkubasta Exp $
 *
 * Contributors:
 * IBM - Initial API and implementation
 **********************************************************************/

#ifndef __UTILITY_H__
#define __UTILITY_H__ 1

#ifdef _WIN32
	#include <winsock2.h> /* Bug 134924 */
	#include <Windows.h>
	#include <Winbase.h>
	#ifndef PATH_MAX
		#define PATH_MAX (10 * _MAX_PATH)
		char *realpath(const char* fileName, char * buf) ;
	#endif
#elif defined(__OS400__)
	char *realpath(const char* fileName, char * buf) ;
#endif

#ifndef PATH_MAX
#define PATH_MAX 2048
#endif

#if defined __cplusplus && defined _HPUX
	#define ENV(e) e
	#define ENVPARM(e)
#else
	#define ENV(e) (*e)
	#define ENVPARM(e) e,
#endif

/** Macros used to simplify the use of JNI *************************/


/* Calling instance methods */
#define CALL_OBJ_METHOD0(env, classInstance, methodId) (jstring)(ENV(env)->CallObjectMethod(ENVPARM(env) classInstance, methodId))
#define CALL_OBJ_METHOD1(env, classInstance, methodId, param1) (jstring)(ENV(env)->CallObjectMethod(ENVPARM(env) classInstance, methodId, param1))
#define CALL_OBJ_METHOD2(env, classInstance, methodId, param1, param2) (jstring)(ENV(env)->CallObjectMethod(ENVPARM(env) classInstance, methodId, param1, param2))

/* Calling static methods */
#define CALL_OBJ_SMETHOD0(env, classAssociated, methodId) (jstring)(ENV(env)->CallStaticObjectMethod(ENVPARM(env) classAssociated, methodId))
#define CALL_OBJ_SMETHOD1(env, classAssociated, methodId, param1) (jstring)(ENV(env)->CallStaticObjectMethod(ENVPARM(env) classAssociated, methodId, param1))


#define CREATE_JSTRING(env, text) ENV(env)->NewStringUTF(ENVPARM(env) text)
#define FIND_CLASS(env, className) ENV(env)->FindClass(ENVPARM(env) className)

/* Get ID operations */
#define GET_METHODID(env, classAssociated, methodName, methodSig) ENV(env)->GetMethodID(ENVPARM(env) classAssociated, methodName, methodSig)
#define GET_SMETHODID(env, classAssociated, methodName, methodSig) ENV(env)->GetStaticMethodID(ENVPARM(env) classAssociated, methodName, methodSig)
#define GET_FIELDID(env, classAssociated, name, signature) ENV(env)->GetFieldID(ENVPARM(env) classAssociated, name, signature)
#define GET_SFIELDID(env, classAssociated, name, signature) ENV(env)->GetStaticFieldID(ENVPARM(env) classAssociated, name, signature)


#define GET_SFIELD(env, classAssociated, fieldId) ENV(env)->GetStaticObjectField(ENVPARM(env) classAssociated, fieldId)
#define NEW_ARRAY(env, size, classAssociated, initialValue) ENV(env)->NewObjectArray(ENVPARM(env) size, classAssociated, initialValue)
#define GET_ARRAY_SIZE(env, array) ENV(env)->GetArrayLength(ENVPARM(env) array)
#define GET_ARRAY_ELEM(env, array, index) ENV(env)->GetObjectArrayElement(ENVPARM(env) array, index)
#define ADD_TO_ARRAY(env, array, index, obj) ENV(env)->SetObjectArrayElement(ENVPARM(env) array, index, obj)

/* String operations */
#define CONVERT_TO_UTF(env, jstr) ENV(env)->GetStringUTFChars(ENVPARM(env) (jstring)jstr, NULL)
#define RELEASE_UTF_CHARS(env, jstr, chrs) ENV(env)->ReleaseStringUTFChars(ENVPARM(env) (jstring)jstr, chrs)


/* Exception checks and clears */
#if defined __cplusplus && defined _HPUX
	#define CHECK_EXCEPTION(env) ENV(env)->ExceptionOccurred()
#else
	#define CHECK_EXCEPTION(env) ENV(env)->ExceptionOccurred(env)
#endif


#if defined __cplusplus && defined _HPUX
	#define CLEAR_EXCEPTIONS(env) ENV(env)->ExceptionClear()
#else
	#define CLEAR_EXCEPTIONS(env) ENV(env)->ExceptionClear(env)
#endif


/** CALLOC  *************************************************************
  * Allocate some memory from the heap.  If there is no more memory left
  * the VM will exit gracefully.
  */
extern void* jvmpiAgent_Calloc(unsigned int size);

/********************************************************
 * strcpyrealloc()
 * 
 * Copy one string to the other, first reallocating the 
 * space pointed to by the destination so that the src
 * can comfortably fit in it. 
 * @param dest pointer to pointer to destination 
 * @param src the source string 
 * @return 0 if successful, -1 otherwise 
 */ 

int strcpyrealloc(char **dest, const char *src); 

/*********************************************************
 * double2string()
 *
 * Take a value of type double and convert it into a string, 
 * using '.' (period) as the decimal symbol (i.e. ignore what
 * the locale setting uses for a decimal place). 
 *
 * The method further assumes val is non-negative. 
 * 
 * @param val the double value to be converted into a string (non-negative value) 
 * @param buffer the buffer into which the string should be put
 * @param offset the offset into the buffer where to start writing
 * @param precision the number of digits to appear after the decimal place
 * @return the offset just past the last written position in buffer
 */ 
unsigned short double2string(double val, char *buffer, unsigned short offset, int precision); 

#endif
