1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241
|
/****************************************************************************
* NCSA HDF *
* National Computational Science Alliance *
* University of Illinois at Urbana-Champaign *
* 605 E. Springfield, Champaign IL 61820 *
* *
* Center for Information Sciences and Databases, ETH Zurich, Switzerland *
* *
* For conditions of distribution and use, see the accompanying *
* COPYING file. *
* *
****************************************************************************/
/*
* This module contains the implementation of all the native methods
* used for number conversion. This is represented by the Java
* class HDFNativeData.
*
* These routines convert one dimensional arrays of bytes into
* one-D arrays of other types (int, float, etc) and vice versa.
*
* These routines are called from the Java parts of the Java-C
* interface.
*
* ***Important notes:
*
* 1. These routines are designed to be portable--they use the
* C compiler to do the required native data manipulation.
* 2. These routines copy the data at least once -- a serious
* but unavoidable performance hit.
*/
#ifdef __cplusplus
extern "C" {
#endif
#include <jni.h>
extern jboolean h5JNIFatalError( JNIEnv *env, char *functName);
extern jboolean h5nullArgument( JNIEnv *env, char *functName);
extern jboolean h5badArgument( JNIEnv *env, char *functName);
extern jboolean h5indexOutOfBounds( JNIEnv *env, char *functName);
/* Change byte order for data type of length 2. */
#define CHANGE_BYTE_ORDER_2(ARRAY) {jbyte _tmp; _tmp=ARRAY[0]; ARRAY[0]=ARRAY[1]; ARRAY[1]=_tmp;}
/* Change byte order for data type of length 4. */
#define CHANGE_BYTE_ORDER_4(ARRAY) {jbyte _tmp; _tmp=ARRAY[0]; ARRAY[0]=ARRAY[3]; ARRAY[3]=_tmp; _tmp=ARRAY[1]; ARRAY[1]=ARRAY[2]; ARRAY[2]=_tmp;}
/* Change byte order for data type of length 8. */
#define CHANGE_BYTE_ORDER_8(ARRAY) {jbyte _tmp; _tmp=ARRAY[0]; ARRAY[0]=ARRAY[7]; ARRAY[7]=_tmp; _tmp=ARRAY[1]; ARRAY[1]=ARRAY[6]; ARRAY[6]=_tmp; _tmp=ARRAY[2]; ARRAY[2]=ARRAY[5]; ARRAY[5]=_tmp; _tmp=ARRAY[3]; ARRAY[3]=ARRAY[4]; ARRAY[4]=_tmp;}
#define INDATA_IS_NULL_ERR_TB METHODNAMETB ": inData is NULL"
#define OUTDATA_IS_NULL_ERR_TB METHODNAMETB ": outData is NULL"
#define OOB_IN_ERR_TB METHODNAMETB ": inStart or len is out of bounds"
#define OOB_OUT_ERR_TB METHODNAMETB ": outStart or len is out of bounds"
#define PINNING_OUT_ERR_TB METHODNAMETB ": pinning outArray failed"
#define INDATA_IS_NULL_ERR_BT METHODNAMEBT ": inData is NULL"
#define OUTDATA_IS_NULL_ERR_BT METHODNAMEBT ": outData is NULL"
#define OOB_IN_ERR_BT METHODNAMEBT ": inStart or len is out of bounds"
#define OOB_OUT_ERR_BT METHODNAMEBT ": outStart or len is out of bounds"
#define PINNING_OUT_ERR_BT METHODNAMEBT ": pinning outArray failed"
/*
* public static native void copy<TARGET_CAPT>oByte(<TARGET>[] inData, int inStart,
* byte[] outData, int outStart, int len, int byteOrder);
*/
JNIEXPORT void JNICALL FUNCTIONNAMETB
(JNIEnv *env,
jclass clss,
TARGET_ARRAY inData, /* IN: array of TARGET */
jint inStart,
jbyteArray outData, /* OUT: array of byte */
jint outStart,
jint len,
jint byteOrder
)
{
jsize inSize, outSize;
jint lenInBytes;
jbyte *outArray;
jboolean isCopy;
if (inData == NULL) {
h5nullArgument(env, INDATA_IS_NULL_ERR_BT);
return;
}
if (outData == NULL) {
h5nullArgument(env, OUTDATA_IS_NULL_ERR_TB);
return;
}
lenInBytes = len * sizeof(TARGET);
#ifdef __cplusplus
inSize = env->GetArrayLength(inData);
#else
inSize = (*env)->GetArrayLength(env, inData);
#endif
if ((inStart < 0) || (inStart + len > inSize)) {
h5indexOutOfBounds(env, OOB_IN_ERR_TB);
return;
}
#ifdef __cplusplus
outSize = env->GetArrayLength(outData);
#else
outSize = (*env)->GetArrayLength(env, outData);
#endif
if ((outStart < 0) || (outStart + lenInBytes > outSize)) {
h5indexOutOfBounds(env, OOB_OUT_ERR_TB);
return;
}
#ifdef __cplusplus
outArray = env->GetPrimitiveArrayCritical(outData, &isCopy);
#else
outArray = (*env)->GetPrimitiveArrayCritical(env, outData, &isCopy);
#endif
if (outArray == NULL) {
h5JNIFatalError(env, PINNING_OUT_ERR_TB);
return;
}
#ifdef __cplusplus
env->COPY_FUNC(inData, inStart, len, (TARGET*) (outArray + outStart));
#else
(*env)->COPY_FUNC(env, inData, inStart, len, (TARGET*) (outArray + outStart));
#endif
if (byteOrder > 0 && byteOrder != MACHINE_BYTE_ORDER)
{
jbyte *buf = outArray + outStart;
int nelmts;
for(nelmts = 0; nelmts < len; ++nelmts)
{
CHANGE_BYTE_ORDER(buf);
buf += sizeof(TARGET);
}
}
#ifdef __cplusplus
env->ReleasePrimitiveArrayCritical(outData, outArray, 0);
#else
(*env)->ReleasePrimitiveArrayCritical(env, outData,outArray, 0);
#endif
return;
}
/*
* public static native void copyByteTo<TARGET_CAP>(byte[] inData, int inStart,
* TARGET[] outData, int outStart, int len, int byteOrder);
*/
JNIEXPORT void JNICALL FUNCTIONNAMEBT
(JNIEnv *env,
jclass clss,
jbyteArray inData, /* IN: array of byte */
jint inStart,
TARGET_ARRAY outData, /* OUT: array of TAGET */
jint outStart,
jint len,
jint byteOrder
)
{
jsize inSize, outSize;
jint lenInBytes;
TARGET *outArray;
jboolean isCopy;
if (inData == NULL) {
h5nullArgument(env, INDATA_IS_NULL_ERR_BT);
return;
}
if (outData == NULL) {
h5nullArgument(env, OUTDATA_IS_NULL_ERR_BT);
return;
}
lenInBytes = len * sizeof(TARGET);
#ifdef __cplusplus
inSize = env->GetArrayLength(inData);
#else
inSize = (*env)->GetArrayLength(env, inData);
#endif
if ((inStart < 0) || (inStart + lenInBytes > inSize)) {
h5indexOutOfBounds(env, OOB_IN_ERR_BT);
return;
}
#ifdef __cplusplus
outSize = env->GetArrayLength(outData);
#else
outSize = (*env)->GetArrayLength(env, outData);
#endif
if ((outStart < 0) || (outStart + len > outSize)) {
h5indexOutOfBounds(env, OOB_OUT_ERR_BT);
return;
}
#ifdef __cplusplus
outArray = env->GetPrimitiveArrayCritical(outData, &isCopy);
#else
outArray = (*env)->GetPrimitiveArrayCritical(env, outData, &isCopy);
#endif
if (outArray == NULL) {
h5JNIFatalError(env, PINNING_OUT_ERR_BT);
return;
}
#ifdef __cplusplus
env->GetByteArrayRegion(inData, inStart, lenInBytes, outArray + outStart);
#else
(*env)->GetByteArrayRegion(env, inData, inStart, lenInBytes, (jbyte*) (outArray + outStart));
#endif
if (byteOrder > 0 && byteOrder != MACHINE_BYTE_ORDER)
{
jbyte *buf = (jbyte*) outArray + outStart;
int nelmts;
for(nelmts = 0; nelmts < len; ++nelmts)
{
CHANGE_BYTE_ORDER(buf);
buf += sizeof(TARGET);
}
}
#ifdef __cplusplus
env->ReleasePrimitiveArrayCritical(outData, outArray, 0);
#else
(*env)->ReleasePrimitiveArrayCritical(env, outData, outArray, 0);
#endif
return;
}
#ifdef __cplusplus
}
#endif
|