copyByteTarget.ctempl 6.16 KB
Newer Older
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
/****************************************************************************
 * 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 "hdf5.h"
#include <jni.h>

extern jboolean h5JNIFatalError( JNIEnv *env, char *functName);
extern jboolean h5nullArgument( JNIEnv *env, char *functName);
extern jboolean h5badArgument( JNIEnv *env, char *functName);

#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);
 */
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
)  
{
    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)) {
        h5badArgument(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)) {
        h5badArgument(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

#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);
 */
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
  )  
{
    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)) {
        h5badArgument(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)) {
        h5badArgument(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

#ifdef __cplusplus
    env->ReleasePrimitiveArrayCritical(outData, outArray, 0);
#else
    (*env)->ReleasePrimitiveArrayCritical(env, outData, outArray, 0);
#endif

    return;
}

#ifdef __cplusplus
}
#endif