/******************************************************************
* All rights reserved � 2005 Vitaly Shelest (Javain Ltd)
*
* File name: JArrayHelper.h
*
* Last modification: 20.03.2005
*
* Description: Java Primitive Array Helper class template
*
* Authors: Vitaly Shelest
*
*****************************************************************/
#pragma once
#include "JTypeDef.h"
#include "JNIEnvHelper.h"
#pragma warning( disable : 4290 )
#pragma warning( disable : 4518 )
// Java Array Helper Template
namespace jni_helpers
{
template<class TAC, class TAJ>
class JArrayHelper: public JObject_t
{
public:
// Constructors
//
JArrayHelper() throw(BaseException)
{
jitem = 0;
m_harray = 0;
m_array = 0;
length = 0;
}
JArrayHelper(size_t len, LPCTSTR elemClassName = "java/lang/Object") throw(BaseException)
{
jitem = 0;
m_harray = 0;
m_array = 0;
length = (ULONG)len;
jobject tmpobject = (jobject)NewArray((ULONG)len, elemClassName);
Assign(tmpobject);
if(tmpobject)
jni_helpers::JNIEnvHelper::DeleteLocalRef(tmpobject);
if(len)
{
m_harray = GlobalAlloc(GHND, len*sizeof(TAC));
if(m_harray != NULL)
{
m_array = (TAC*)GlobalLock(m_harray);
if(m_array != NULL)
StoreArrayElements();
}
}
}
JArrayHelper(const long len, LPCTSTR elemClassName = "java/lang/Object") throw(BaseException)
{
jitem = 0;
m_harray = 0;
m_array = 0;
length = len;
jobject tmpobject = (jobject)NewArray(len, elemClassName);
Assign(tmpobject);
if(tmpobject)
jni_helpers::JNIEnvHelper::DeleteLocalRef(tmpobject);
if(len)
{
m_harray = GlobalAlloc(GHND, len*sizeof(TAC));
if(m_harray != NULL)
{
m_array = (TAC*)GlobalLock(m_harray);
if(m_array != NULL)
StoreArrayElements();
}
}
}
JArrayHelper(JArrayHelper& a) throw(BaseException)
{
jitem = 0;
m_harray = 0;
m_array = 0;
Assign((JObject_t&)a);
TAJ jerray = (TAJ)JObject_t::operator const jobject();
length = (jerray != 0)?jni_helpers::JNIEnvHelper::GetArrayLength(jerray):0;
}
JArrayHelper(const JObject_t& o) : JObject_t(o)
{
jitem = 0;
m_harray = 0;
m_array = 0;
TAJ jerray = (TAJ)JObject_t::operator const jobject();
length = (jerray != 0)?jni_helpers::JNIEnvHelper::GetArrayLength(jerray):0;
}
JArrayHelper(const TAC* a, const long len, LPCTSTR elemClassName = "java/lang/Object") throw(BaseException)
{
jitem = 0;
m_harray = 0;
m_array = 0;
length = len;
jobject tmpobject = (jobject)NewArray(len, elemClassName);
Assign(tmpobject);
if(tmpobject)
jni_helpers::JNIEnvHelper::DeleteLocalRef(tmpobject);
if(len)
{
//m_array = new TAC[len];
//if(m_array != NULL)
//{
// memcpy(m_array, a, len * sizeof(TAC));
// StoreArrayElements();
//}
m_harray = GlobalAlloc(GHND, len*sizeof(TAC));
if(m_harray != NULL)
{
m_array = (TAC*)GlobalLock(m_harray);
if(m_array != NULL)
{
memcpy(m_array, a, len * sizeof(TAC));
StoreArrayElements();
}
}
}
}
JArrayHelper(const TAJ ja) throw(BaseException)
{
jitem = 0;
m_harray = 0;
m_array = 0;
Assign((jobject)ja);
TAJ jerray = (TAJ)JObject_t::operator const jobject();
length = (jerray != 0)?jni_helpers::JNIEnvHelper::GetArrayLength(jerray):0;
}
// Assignment operators
//
JArrayHelper& operator=(const JArrayHelper& ja) throw(BaseException)
{
Assign((JObject_t&)ja);
m_harray = 0;
m_array = 0;
return *this;
}
JArrayHelper& operator=(const TAJ ja) throw(BaseException)
{
Assign((jobject)ja);
m_harray = 0;
m_array = 0;
jitem = 0;
return *this;
}
// Get/Put functions for array items
//
__declspec(property(get=get_item, put=put_item))
TAC item[];
void put_item(const unsigned int i, const TAC value) throw(BaseException)
{
length = Length();
if(i >= length || i < 0)
throw ArrayIndexOutOfBoundsException(i, length);
SetArrayElement(i, (TAC*)(&value));
}
TAC get_item(const unsigned int i)
{
length = Length();
if(i >= length || i < 0)
throw ArrayIndexOutOfBoundsException(i, length);
if(JObject_t::operator const jobject())
return GetArrayElement(i);
return 0;
}
// Extractors
//
operator TAC*()
{
GetArrayElements();
return const_cast<TAC*>(m_array);
};
operator const TAJ()
{
return const_cast<TAJ>(operator const jobject());
};
// Low-level helper functions
//
TAJ Copy() const
{
return 0;
}
unsigned int Length()
{
TAJ obj = (TAJ)JObject_t::operator const jobject();
if( obj == 0)
return 0;
return JNIEnvHelper::GetArrayLength(obj);
}
// Extracts data for an array object
// used as a modified function parameter
/*
void Synchronize() throw(BaseException)
{
GetArrayElements();
}
*/
void DeleteItem(){}
// Destructor
//
virtual ~JArrayHelper() throw(BaseException)
{
//if(m_array)
// delete[] m_array;
if(m_array)
GlobalUnlock(m_harray);
//delete[] m_array;
if(m_harray)
GlobalFree(m_harray);
m_harray = NULL;
m_array = NULL;
DeleteItem();
jitem = 0;
}
// For functions internal usage
private:
HGLOBAL m_harray;
TAC* m_array;
mutable unsigned long length;
TAC jitem;
/*
void UpdateJArray() throw(BaseException)
{
StoreArrayElements(m_array);
}
*/
void GetArrayElements() throw(BaseException)
{
jboolean isCopy;
TAJ tmpjarray = (TAJ)JObject_t::operator const jobject();
length = (tmpjarray != NULL)?JNIEnvHelper::GetArrayLength(tmpjarray):0;
//if(m_array)
// delete[] m_array;
if(m_array)
GlobalUnlock(m_harray);
//delete[] m_array;
if(m_harray)
GlobalFree(m_harray);
m_harray = NULL;
m_array = NULL;
if(length)
{
TAC* array = GetArrayElements(&isCopy);
//m_array = new TAC[length];
//memcpy(m_array, array, sizeof(TAC)*length);
m_harray = GlobalAlloc(GHND, length*sizeof(TAC));
if(m_harray != NULL)
{
m_array = (TAC*)GlobalLock(m_harray);
if(m_array != NULL)
memcpy(m_array, array, sizeof(TAC)*length);
}
ReleaseArrayElements(array);
}
}
void StoreArrayElements() throw(BaseException)
{
jboolean isCopy;
jobject arobj = operator const jobject();
length = (arobj != NULL)?jni_helpers::JNIEnvHelper::GetArrayLength((TAJ)arobj):0;
if(length && m_array)
{
TAC* array = GetArrayElements(&isCopy);
if(array)
{
memcpy(array, m_array, sizeof(TAC)*length);
ReleaseArrayElements(array);
}
}
}
TAC GetArrayElement(int i) throw(BaseException);
void SetArrayElement(int i, TAC* value) throw(BaseException);
TAC* GetArrayElements(jboolean* isCopy) throw(BaseException)
{
TAC* result = 0;
if(operator const jobject())
{
result = reinterpret_cast<TAC*>(JNIEnvHelper::GetPrimitiveArrayCritical((TAJ)operator const jobject(), isCopy));
jni_helpers::JNIEnvHelper::exceptionCheck();
}
return result;
}
void ReleaseArrayElements(TAC* array) throw(BaseException)
{
TAJ arobj = (TAJ)operator const jobject();
if(arobj && array)
{
jni_helpers::JNIEnvHelper::ReleasePrimitiveArrayCritical(arobj, array, NULL);
jni_helpers::JNIEnvHelper::exceptionCheck();
}
}
TAJ NewArray(long, LPCTSTR) throw(BaseException);
};
// jboolean type function
//
};
inline void jni_helpers::JArrayHelper<jstring, jobjectArray>::DeleteItem()
{
if(jitem)
JNIEnvHelper::DeleteGlobalRef(jitem);
jitem = 0;
}
//inline jni_helpers::JArrayHelper<jstring, jobjectArray>::~JArrayHelper()
//{
// if(m_array)
// delete[] m_array;
// m_array = NULL;
// DeleteItem();
// jitem = 0;
//}
inline void jni_helpers::JArrayHelper<jobject, jobjectArray>::DeleteItem()
{
if(jitem)
JNIEnvHelper::DeleteGlobalRef(jitem);
jitem = 0;
}
//inline jni_helpers::JArrayHelper<jobject, jobjectArray>::~JArrayHelper()
//{
// if(m_array)
// delete[] m_array;
// if(jitem)
// JNIEnvHelper::DeleteGlobalRef(jitem);
// m_array = NULL;
// jitem = 0;
//}
inline jbooleanArray jni_helpers::JArrayHelper<jboolean, jbooleanArray>::NewArray(long len, LPCTSTR)
{
jbooleanArray result = reinterpret_cast<jbooleanArray>(JNIEnvHelper::NewBooleanArray( len ));
return result;
};
inline jboolean jni_helpers::JArrayHelper<jboolean, jbooleanArray>::GetArrayElement(int i)
{
jboolean result = 0;
if(JObject_t::operator const jobject())
JNIEnvHelper::GetBooleanArrayRegion((jbooleanArray)JObject_t::operator const jobject(), i, 1, &result);
return result;
}
inline void jni_helpers::JArrayHelper<jboolean, jbooleanArray>::SetArrayElement(int i, jboolean* value)
{
if(JObject_t::operator const jobject())
JNIEnvHelper::SetBooleanArrayRegion((jbooleanArray)JObject_t::operator const jobject(), i, 1, value);
}
// jbyte type function
//
inline jbyteArray jni_helpers::JArrayHelper<jbyte, jbyteArray>::NewArray( long len, LPCTSTR)
{
jbyteArray result = reinterpret_cast<jbyteArray>(JNIEnvHelper::NewByteArray( len ));
return result;
};
inline jbyte jni_helpers::JArrayHelper<jbyte, jbyteArray>::GetArrayElement(int i)
{
jbyte result = 0;
if(JObject_t::operator const jobject())
JNIEnvHelper::GetByteArrayRegion((jbyteArray)JObject_t::operator const jobject(), i, 1, &result);
return result;
}
inline void jni_helpers::JArrayHelper<jbyte, jbyteArray>::SetArrayElement(int i, jbyte* value)
{
if(JObject_t::operator const jobject())
JNIEnvHelper::SetByteArrayRegion((jbyteArray)JObject_t::operator const jobject(), i, 1, value);
}
// jchar type function
//
inline jcharArray jni_helpers::JArrayHelper<jchar, jcharArray>::NewArray(long len, LPCTSTR)
{
jcharArray result = reinterpret_cast<jcharArray>(JNIEnvHelper::NewCharArray( len ));
return result;
};
inline jchar jni_helpers::JArrayHelper<jchar, jcharArray>::GetArrayElement(int i)
{
jchar result = 0;
if(JObject_t::operator const jobject())
JNIEnvHelper::GetCharArrayRegion((jcharArray)JObject_t::operator const jobject(), i, 1, &result);
return result;
}
inline void jni_helpers::JArrayHelper<jchar, jcharArray>::SetArrayElement(int i, jchar* value)
{
if(JObject_t::operator const jobject())
JNIEnvHelper::SetCharArrayRegion((jcharArray)JObject_t::operator const jobject(), i, 1, value);
}
// jshort type function
//
inline jshortArray jni_helpers::JArrayHelper<jshort, jshortArray>::NewArray(long len, LPCTSTR)
{
jshortArray result = reinterpret_cast<jshortArray>(JNIEnvHelper::NewShortArray( len ));
return result;
};
inline jshort jni_helpers::JArrayHelper<jshort, jshortArray>::GetArrayElement(int i)
{
jshort result = 0;
if(JObject_t::operator const jobject())
JNIEnvHelper::GetShortArrayRegion((jshortArray)JObject_t::operator const jobject(), i, 1, &result);
return result;
}
inline void jni_helpers::JArrayHelper<jshort, jshortArray>::SetArrayElement(int i, jshort* value)
{
if(JObject_t::operator const jobject())
JNIEnvHelper::SetShortArrayRegion((jshortArray)JObject_t::operator const jobject(), i, 1, value);
}
// jint type function
//
inline jintArray jni_helpers::JArrayHelper<jint, jintArray>::NewArray(long len, LPCTSTR)
{
jintArray result = reinterpret_cast<jintArray>(JNIEnvHelper::NewIntArray( len ));
return result;
};
inline jint jni_helpers::JArrayHelper<jint, jintArray>::GetArrayElement(int i)
{
jint result = 0;
if(JObject_t::operator const jobject())
JNIEnvHelper::GetIntArrayRegion((jintArray)JObject_t::operator const jobject(), i, 1, &result);
return result;
}
inline void jni_helpers::JArrayHelper<jint, jintArray>::SetArrayElement(int i, jint* value)
{
if(JObject_t::operator const jobject())
JNIEnvHelper::SetIntArrayRegion((jintArray)JObject_t::operator const jobject(), i, 1, value);
}
inline void jni_helpers::JArrayHelper<jobject, jobjectArray>::SetArrayElement(int i, jobject* value)
{
if(JObject_t::operator const jobject())
JNIEnvHelper::SetObjectArrayElement((jobjectArray)JObject_t::operator const jobject(), i, *value);
}
inline jobject jni_helpers::JArrayHelper<jobject, jobjectArray>::GetArrayElement(int i)
{
if(JObject_t::operator const jobject())
return JNIEnvHelper::GetObjectArrayElement((jobjectArray)JObject_t::operator const jobject(), i);
return 0;
}
// jlong type function
//
inline jlongArray jni_helpers::JArrayHelper<jlong, jlongArray>::NewArray(long len, LPCTSTR)
{
jlongArray result = reinterpret_cast<jlongArray>(JNIEnvHelper::NewLongArray( len ));
return result;
};
inline jlong jni_helpers::JArrayHelper<jlong, jlongArray>::GetArrayElement(int i)
{
jlong result = 0;
if(JObject_t::operator const jobject())
JNIEnvHelper::GetLongArrayRegion((jlongArray)JObject_t::operator const jobject(), i, 1, &result);
return result;
}
inline void jni_helpers::JArrayHelper<jlong, jlongArray>::SetArrayElement(int i, jlong* value)
{
if(JObject_t::operator const jobject())
JNIEnvHelper::SetLongArrayRegion((jlongArray)JObject_t::operator const jobject(), i, 1, value);
}
// jfloat type function
//
inline jfloatArray jni_helpers::JArrayHelper<jfloat, jfloatArray>::NewArray(long len, LPCTSTR)
{
jfloatArray result = reinterpret_cast<jfloatArray>(JNIEnvHelper::NewFloatArray( len ));
return result;
};
inline jfloat jni_helpers::JArrayHelper<jfloat, jfloatArray>::GetArrayElement(int i)
{
jfloat result = 0;
if(JObject_t::operator const jobject())
JNIEnvHelper::GetFloatArrayRegion((jfloatArray)JObject_t::operator const jobject(), i, 1, &result);
return result;
}
inline void jni_helpers::JArrayHelper<jfloat, jfloatArray>::SetArrayElement(int i, jfloat* value)
{
if(JObject_t::operator const jobject())
JNIEnvHelper::SetFloatArrayRegion((jfloatArray)JObject_t::operator const jobject(), i, 1, value);
}
// jdouble type function
//
inline jdoubleArray jni_helpers::JArrayHelper<jdouble, jdoubleArray>::NewArray(long len, LPCTSTR)
{
jdoubleArray result = reinterpret_cast<jdoubleArray>(JNIEnvHelper::NewDoubleArray( len ));
return result;
};
inline jdouble jni_helpers::JArrayHelper<jdouble, jdoubleArray>::GetArrayElement(int i)
{
jdouble result = 0;
if(JObject_t::operator const jobject())
JNIEnvHelper::GetDoubleArrayRegion((jdoubleArray)JObject_t::operator const jobject(), i, 1, &result);
return result;
}
inline void jni_helpers::JArrayHelper<jdouble, jdoubleArray>::SetArrayElement(int i, jdouble* value)
{
if(JObject_t::operator const jobject())
JNIEnvHelper::SetDoubleArrayRegion((jdoubleArray)JObject_t::operator const jobject(), i, 1, value);
}
//////////////////////////////////////////////////
// Some specific template function implementations
//////////////////////////////////////////////////
// jstring type functions
//
inline jni_helpers::JArrayHelper<jstring, jobjectArray>& jni_helpers::JArrayHelper<jstring, jobjectArray>::operator=(const jobjectArray ja)
{
if(jitem)
JNIEnvHelper::DeleteGlobalRef(jitem);
Assign((jobject)ja);
m_harray = 0;
m_array = 0;
jitem = 0;
return *this;
}
inline jstring* jni_helpers::JArrayHelper<jstring, jobjectArray>::GetArrayElements(jboolean* isCopy)
{
return NULL;
}
inline void jni_helpers::JArrayHelper<jstring, jobjectArray>::ReleaseArrayElements(jstring* array)
{
}
inline void jni_helpers::JArrayHelper<jstring, jobjectArray>::put_item(const unsigned int i, const jstring value)
{
if(JObject_t::operator const jobject() && i < Length() && value)
{
jni_helpers::JNIEnvHelper::SetObjectArrayElement((jobjectArray)JObject_t::operator const jobject(), i, value);
jni_helpers::JNIEnvHelper::exceptionCheck();
}
}
inline jstring jni_helpers::JArrayHelper<jstring, jobjectArray>::get_item(const unsigned int i)
{
if(JObject_t::operator const jobject() && i < Length())
{
jobject tmpobject = jni_helpers::JNIEnvHelper::GetObjectArrayElement((jobjectArray)JObject_t::operator const jobject(), i);
if(jitem)
{
jni_helpers::JNIEnvHelper::DeleteGlobalRef(jitem);
jitem = 0;
}
if(tmpobject)
{
jitem = (jstring)jni_helpers::JNIEnvHelper::NewGlobalRef(tmpobject);
jni_helpers::JNIEnvHelper::DeleteLocalRef(tmpobject);
}
return jitem;
}
return 0;
}
inline jobjectArray jni_helpers::JArrayHelper<jstring, jobjectArray>::NewArray(long length, LPCTSTR)
{
jclass clazz = reinterpret_cast<jclass> (jni_helpers::JNIEnvHelper::getEnv() -> FindClass("java/lang/String"));
jobjectArray result = reinterpret_cast<jobjectArray>(jni_helpers::JNIEnvHelper::NewObjectArray( length, clazz, NULL ));
jni_helpers::JNIEnvHelper::getEnv() -> DeleteLocalRef(clazz);
jni_helpers::JNIEnvHelper::exceptionCheck();
return result;
}
// jobject type functions
//
inline jni_helpers::JArrayHelper<jobject, jobjectArray>& jni_helpers::JArrayHelper<jobject, jobjectArray>::operator=(const jobjectArray ja)
{
if(jitem)
JNIEnvHelper::DeleteGlobalRef(jitem);
Assign((jobject)ja);
m_harray = 0;
m_array = 0;
jitem = 0;
return *this;
}
inline jobject* jni_helpers::JArrayHelper<jobject, jobjectArray>::GetArrayElements(jboolean* isCopy)
{
return NULL;
}
inline void jni_helpers::JArrayHelper<jobject, jobjectArray>::ReleaseArrayElements(jobject* array)
{
}
inline void jni_helpers::JArrayHelper<jobject, jobjectArray>::put_item(const unsigned int i, const jobject value)
{
if(JObject_t::operator const jobject() &&
i < Length() && value)
{
jni_helpers::JNIEnvHelper::SetObjectArrayElement((jobjectArray)JObject_t::operator const jobject(), i, value);
jni_helpers::JNIEnvHelper::exceptionCheck();
}
}
inline jobject jni_helpers::JArrayHelper<jobject, jobjectArray>::get_item(const unsigned int i)
{
if(JObject_t::operator const jobject() && i < Length())
{
jobject tmpobject = jni_helpers::JNIEnvHelper::GetObjectArrayElement((jobjectArray)JObject_t::operator const jobject(), i);
if(jitem)
{
jni_helpers::JNIEnvHelper::DeleteGlobalRef(jitem);
jitem = 0;
}
if(tmpobject)
{
jitem = jni_helpers::JNIEnvHelper::NewGlobalRef(tmpobject);
jni_helpers::JNIEnvHelper::DeleteLocalRef(tmpobject);
}
return (jstring)jitem;
}
return 0;
}
inline jobjectArray jni_helpers::JArrayHelper<jobject, jobjectArray>::NewArray(long len, LPCTSTR elemClassName)
{
jclass clazz = reinterpret_cast<jclass> (jni_helpers::JNIEnvHelper::getEnv() -> FindClass(elemClassName));
jobjectArray result = reinterpret_cast<jobjectArray>(jni_helpers::JNIEnvHelper::NewObjectArray(len, clazz, NULL));
jni_helpers::JNIEnvHelper::getEnv() -> DeleteLocalRef(clazz);
jni_helpers::JNIEnvHelper::exceptionCheck();
return result;
}
// JArray helper definitions
//
namespace jni_helpers
{
typedef JArrayHelper< jboolean, jbooleanArray >JBooleanArrayHelper;
typedef JArrayHelper< jbyte, jbyteArray >JByteArrayHelper;
typedef JArrayHelper< jchar, jcharArray >JCharArrayHelper;
typedef JArrayHelper< jshort, jshortArray >JShortArrayHelper;
typedef JArrayHelper< jint, jintArray >JIntArrayHelper;
typedef JArrayHelper< jlong, jlongArray >JLongArrayHelper;
typedef JArrayHelper< jfloat, jfloatArray >JFloatArrayHelper;
typedef JArrayHelper< jdouble, jdoubleArray >JDoubleArrayHelper;
typedef JArrayHelper< jstring, jobjectArray >JStringArrayHelper;
typedef JArrayHelper< jobject, jobjectArray >JObjectArrayHelper;
}