OLD | NEW |
| (Empty) |
1 /* Licensed to the Apache Software Foundation (ASF) under one or more | |
2 * contributor license agreements. See the NOTICE file distributed with | |
3 * this work for additional information regarding copyright ownership. | |
4 * The ASF licenses this file to You under the Apache License, Version 2.0 | |
5 * (the "License"); you may not use this file except in compliance with | |
6 * the License. You may obtain a copy of the License at | |
7 * | |
8 * http://www.apache.org/licenses/LICENSE-2.0 | |
9 * | |
10 * Unless required by applicable law or agreed to in writing, software | |
11 * distributed under the License is distributed on an "AS IS" BASIS, | |
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
13 * See the License for the specific language governing permissions and | |
14 * limitations under the License. | |
15 */ | |
16 | |
17 /* | |
18 * | |
19 * @author Mladen Turk | |
20 * @version $Id: info.c 1442587 2013-02-05 13:49:48Z rjung $ | |
21 */ | |
22 | |
23 #include "tcn.h" | |
24 #include "apr_file_io.h" | |
25 | |
26 #define DECLARE_FINFO_FIELD(name) static jfieldID _fid##name = NULL | |
27 #define FINFO_FIELD(name) _fid##name | |
28 | |
29 #define GET_FINFO_I(N) \ | |
30 _fid##N = (*e)->GetFieldID(e, finfo, #N, "I"); \ | |
31 if (_fid##N == NULL) { \ | |
32 (*e)->ExceptionClear(e); \ | |
33 goto cleanup; \ | |
34 } else (void)(0) | |
35 | |
36 #define GET_FINFO_J(N) \ | |
37 _fid##N = (*e)->GetFieldID(e, finfo, #N, "J"); \ | |
38 if (_fid##N == NULL) { \ | |
39 (*e)->ExceptionClear(e); \ | |
40 goto cleanup; \ | |
41 } else (void)(0) | |
42 | |
43 #define GET_FINFO_S(N) \ | |
44 _fid##N = (*e)->GetFieldID(e, finfo, #N, \ | |
45 "Ljava/lang/String;"); \ | |
46 if (_fid##N == NULL) { \ | |
47 (*e)->ExceptionClear(e); \ | |
48 goto cleanup; \ | |
49 } else (void)(0) | |
50 | |
51 #define SET_FINFO_I(N, V) \ | |
52 (*e)->SetIntField(e, obj, _fid##N, (jint)(V)) | |
53 | |
54 #define SET_FINFO_J(N, V) \ | |
55 (*e)->SetLongField(e, obj, _fid##N, (jlong)(V)) | |
56 | |
57 #define SET_FINFO_S(N, V) \ | |
58 (*e)->SetObjectField(e, obj, _fid##N, \ | |
59 (V) ? AJP_TO_JSTRING((V)) : NULL) | |
60 | |
61 | |
62 #define DECLARE_AINFO_FIELD(name) static jfieldID _aid##name = NULL | |
63 #define AINFO_FIELD(name) _aid##name | |
64 | |
65 #define GET_AINFO_I(N) \ | |
66 _aid##N = (*e)->GetFieldID(e, ainfo, #N, "I"); \ | |
67 if (_aid##N == NULL) { \ | |
68 (*e)->ExceptionClear(e); \ | |
69 goto cleanup; \ | |
70 } else (void)(0) | |
71 | |
72 #define GET_AINFO_J(N) \ | |
73 _aid##N = (*e)->GetFieldID(e, ainfo, #N, "J"); \ | |
74 if (_aid##N == NULL) { \ | |
75 (*e)->ExceptionClear(e); \ | |
76 goto cleanup; \ | |
77 } else (void)(0) | |
78 | |
79 #define GET_AINFO_S(N) \ | |
80 _aid##N = (*e)->GetFieldID(e, ainfo, #N, \ | |
81 "Ljava/lang/String;"); \ | |
82 if (_aid##N == NULL) { \ | |
83 (*e)->ExceptionClear(e); \ | |
84 goto cleanup; \ | |
85 } else (void)(0) | |
86 | |
87 #define SET_AINFO_I(N, V) \ | |
88 (*e)->SetIntField(e, obj, _aid##N, (jint)(V)) | |
89 | |
90 #define SET_AINFO_J(N, V) \ | |
91 (*e)->SetLongField(e, obj, _aid##N, (jlong)(V)) | |
92 | |
93 #define SET_AINFO_S(N, V) \ | |
94 (*e)->SetObjectField(e, obj, _aid##N, \ | |
95 (V) ? AJP_TO_JSTRING((V)) : NULL) | |
96 | |
97 | |
98 DECLARE_FINFO_FIELD(pool); | |
99 DECLARE_FINFO_FIELD(valid); | |
100 DECLARE_FINFO_FIELD(protection); | |
101 DECLARE_FINFO_FIELD(filetype); | |
102 DECLARE_FINFO_FIELD(user); | |
103 DECLARE_FINFO_FIELD(group); | |
104 DECLARE_FINFO_FIELD(inode); | |
105 DECLARE_FINFO_FIELD(device); | |
106 DECLARE_FINFO_FIELD(nlink); | |
107 DECLARE_FINFO_FIELD(size); | |
108 DECLARE_FINFO_FIELD(csize); | |
109 DECLARE_FINFO_FIELD(atime); | |
110 DECLARE_FINFO_FIELD(mtime); | |
111 DECLARE_FINFO_FIELD(ctime); | |
112 DECLARE_FINFO_FIELD(fname); | |
113 DECLARE_FINFO_FIELD(name); | |
114 DECLARE_FINFO_FIELD(filehand); | |
115 | |
116 DECLARE_AINFO_FIELD(pool); | |
117 DECLARE_AINFO_FIELD(hostname); | |
118 DECLARE_AINFO_FIELD(servname); | |
119 DECLARE_AINFO_FIELD(port); | |
120 DECLARE_AINFO_FIELD(family); | |
121 DECLARE_AINFO_FIELD(next); | |
122 | |
123 static int finfo_class_initialized = 0; | |
124 static int ainfo_class_initialized = 0; | |
125 static jmethodID finfo_class_init = NULL; | |
126 static jmethodID ainfo_class_init = NULL; | |
127 static jclass finfo_class = NULL; | |
128 static jclass ainfo_class = NULL; | |
129 | |
130 apr_status_t tcn_load_finfo_class(JNIEnv *e, jclass finfo) | |
131 { | |
132 GET_FINFO_J(pool); | |
133 GET_FINFO_I(valid); | |
134 GET_FINFO_I(protection); | |
135 GET_FINFO_I(filetype); | |
136 GET_FINFO_I(user); | |
137 GET_FINFO_I(group); | |
138 GET_FINFO_I(inode); | |
139 GET_FINFO_I(device); | |
140 GET_FINFO_I(nlink); | |
141 GET_FINFO_J(size); | |
142 GET_FINFO_J(csize); | |
143 GET_FINFO_J(atime); | |
144 GET_FINFO_J(mtime); | |
145 GET_FINFO_J(ctime); | |
146 GET_FINFO_S(fname); | |
147 GET_FINFO_S(name); | |
148 GET_FINFO_J(filehand); | |
149 | |
150 finfo_class_init = (*e)->GetMethodID(e, finfo, | |
151 "<init>", "()V"); | |
152 if (finfo_class_init == NULL) | |
153 goto cleanup; | |
154 finfo_class_initialized = 1; | |
155 finfo_class = finfo; | |
156 cleanup: | |
157 return APR_SUCCESS; | |
158 } | |
159 | |
160 apr_status_t tcn_load_ainfo_class(JNIEnv *e, jclass ainfo) | |
161 { | |
162 GET_AINFO_J(pool); | |
163 GET_AINFO_S(hostname); | |
164 GET_AINFO_S(servname); | |
165 GET_AINFO_I(port); | |
166 GET_AINFO_I(family); | |
167 GET_AINFO_J(next); | |
168 ainfo_class_init = (*e)->GetMethodID(e, ainfo, | |
169 "<init>", "()V"); | |
170 | |
171 if (ainfo_class_init == NULL) | |
172 goto cleanup; | |
173 ainfo_class_initialized = 1; | |
174 ainfo_class = ainfo; | |
175 cleanup: | |
176 return APR_SUCCESS; | |
177 } | |
178 | |
179 static void fill_finfo(JNIEnv *e, jobject obj, apr_finfo_t *info) | |
180 { | |
181 | |
182 SET_FINFO_J(pool, P2J(info->pool)); | |
183 SET_FINFO_I(valid, info->valid); | |
184 SET_FINFO_I(protection, info->protection); | |
185 SET_FINFO_I(filetype, info->filetype); | |
186 SET_FINFO_I(user, ((jlong)info->user)); | |
187 SET_FINFO_I(group, ((jlong)info->group)); | |
188 SET_FINFO_I(inode, info->inode); | |
189 SET_FINFO_I(device, info->device); | |
190 SET_FINFO_I(nlink, info->nlink); | |
191 SET_FINFO_J(size, info->size); | |
192 SET_FINFO_J(csize, info->csize); | |
193 SET_FINFO_J(atime, info->atime); | |
194 SET_FINFO_J(mtime, info->mtime); | |
195 SET_FINFO_J(ctime, info->ctime); | |
196 SET_FINFO_S(fname, info->fname); | |
197 SET_FINFO_S(name, info->name); | |
198 SET_FINFO_J(filehand, P2J(info->filehand)); | |
199 } | |
200 | |
201 static void fill_ainfo(JNIEnv *e, jobject obj, apr_sockaddr_t *info) | |
202 { | |
203 apr_int32_t f; | |
204 if (info->family == APR_UNSPEC) f = 0; | |
205 else if (info->family == APR_INET) f = 1; | |
206 else if (info->family == APR_INET6) f = 2; | |
207 else f = info->family; | |
208 | |
209 SET_AINFO_J(pool, P2J(info->pool)); | |
210 SET_AINFO_S(hostname, info->hostname); | |
211 SET_AINFO_S(servname, info->servname); | |
212 SET_AINFO_I(port, info->port); | |
213 SET_AINFO_I(family, f); | |
214 SET_AINFO_J(next, P2J(info->next)); | |
215 | |
216 } | |
217 | |
218 TCN_IMPLEMENT_CALL(jint, File, stat)(TCN_STDARGS, jobject finfo, | |
219 jstring fname, jint wanted, | |
220 jlong pool) | |
221 { | |
222 apr_pool_t *p = J2P(pool, apr_pool_t *); | |
223 TCN_ALLOC_CSTRING(fname); | |
224 apr_status_t rv; | |
225 apr_finfo_t info; | |
226 | |
227 UNREFERENCED(o); | |
228 | |
229 if ((rv = apr_stat(&info, J2S(fname), wanted, p)) == APR_SUCCESS) { | |
230 jobject io = (*e)->NewLocalRef(e, finfo); | |
231 fill_finfo(e, io, &info); | |
232 (*e)->DeleteLocalRef(e, io); | |
233 } | |
234 TCN_FREE_CSTRING(fname); | |
235 return (jint)rv; | |
236 } | |
237 | |
238 TCN_IMPLEMENT_CALL(jobject, File, getStat)(TCN_STDARGS, jstring fname, | |
239 jint wanted, jlong pool) | |
240 { | |
241 apr_pool_t *p = J2P(pool, apr_pool_t *); | |
242 TCN_ALLOC_CSTRING(fname); | |
243 apr_status_t rv; | |
244 apr_finfo_t info; | |
245 jobject finfo = NULL; | |
246 | |
247 UNREFERENCED(o); | |
248 | |
249 if ((rv = apr_stat(&info, J2S(fname), wanted, p)) == APR_SUCCESS) { | |
250 finfo = (*e)->NewObject(e, finfo_class, finfo_class_init); | |
251 if (finfo == NULL) | |
252 goto cleanup; | |
253 fill_finfo(e, finfo, &info); | |
254 } | |
255 else | |
256 tcn_ThrowAPRException(e, rv); | |
257 cleanup: | |
258 TCN_FREE_CSTRING(fname); | |
259 return finfo; | |
260 } | |
261 | |
262 TCN_IMPLEMENT_CALL(jint, File, infoGet)(TCN_STDARGS, jobject finfo, | |
263 jint wanted, jlong file) | |
264 { | |
265 apr_file_t *f = J2P(file, apr_file_t *); | |
266 apr_status_t rv; | |
267 apr_finfo_t info; | |
268 | |
269 UNREFERENCED(o); | |
270 | |
271 if ((rv = apr_file_info_get(&info, wanted, f)) == APR_SUCCESS) { | |
272 jobject io = (*e)->NewLocalRef(e, finfo); | |
273 fill_finfo(e, io, &info); | |
274 (*e)->DeleteLocalRef(e, io); | |
275 } | |
276 return (jint)rv; | |
277 } | |
278 | |
279 TCN_IMPLEMENT_CALL(jobject, File, getInfo)(TCN_STDARGS, jint wanted, jlong file) | |
280 { | |
281 apr_file_t *f = J2P(file, apr_file_t *); | |
282 apr_status_t rv; | |
283 apr_finfo_t info; | |
284 | |
285 UNREFERENCED(o); | |
286 | |
287 if ((rv = apr_file_info_get(&info, wanted, f)) == APR_SUCCESS) { | |
288 jobject finfo; | |
289 finfo = (*e)->NewObject(e, finfo_class, finfo_class_init); | |
290 if (finfo == NULL) | |
291 return NULL; | |
292 fill_finfo(e, finfo, &info); | |
293 return finfo; | |
294 } | |
295 else | |
296 tcn_ThrowAPRException(e, rv); | |
297 return NULL; | |
298 } | |
299 | |
300 TCN_IMPLEMENT_CALL(jint, Directory, read)(TCN_STDARGS, jobject finfo, | |
301 jint wanted, jlong dir) | |
302 { | |
303 apr_dir_t *d = J2P(dir, apr_dir_t *); | |
304 apr_status_t rv; | |
305 apr_finfo_t info; | |
306 | |
307 UNREFERENCED(o); | |
308 | |
309 if ((rv = apr_dir_read(&info, wanted, d)) == APR_SUCCESS) { | |
310 jobject io = (*e)->NewLocalRef(e, finfo); | |
311 fill_finfo(e, io, &info); | |
312 if ((*e)->ExceptionCheck(e)) { | |
313 (*e)->ExceptionClear(e); | |
314 } | |
315 else | |
316 rv = APR_EGENERAL; | |
317 (*e)->DeleteLocalRef(e, io); | |
318 } | |
319 return (jint)rv; | |
320 } | |
321 | |
322 TCN_IMPLEMENT_CALL(jboolean, Address, fill)(TCN_STDARGS, | |
323 jobject addr, jlong info) | |
324 { | |
325 apr_sockaddr_t *i = J2P(info, apr_sockaddr_t *); | |
326 jobject ao; | |
327 jboolean rv = JNI_FALSE; | |
328 | |
329 UNREFERENCED(o); | |
330 | |
331 if (i) { | |
332 ao = (*e)->NewLocalRef(e, addr); | |
333 fill_ainfo(e, ao, i); | |
334 if ((*e)->ExceptionCheck(e)) { | |
335 (*e)->ExceptionClear(e); | |
336 } | |
337 else | |
338 rv = JNI_TRUE; | |
339 (*e)->DeleteLocalRef(e, ao); | |
340 } | |
341 return rv; | |
342 } | |
343 | |
344 TCN_IMPLEMENT_CALL(jobject, Address, getInfo)(TCN_STDARGS, jlong info) | |
345 { | |
346 apr_sockaddr_t *i = J2P(info, apr_sockaddr_t *); | |
347 jobject sockaddrObj = NULL; | |
348 | |
349 UNREFERENCED(o); | |
350 | |
351 /* Create the APR Error object */ | |
352 sockaddrObj = (*e)->NewObject(e, ainfo_class, ainfo_class_init); | |
353 if (sockaddrObj == NULL) | |
354 return NULL; | |
355 fill_ainfo(e, sockaddrObj, i); | |
356 return sockaddrObj; | |
357 } | |
OLD | NEW |