1 |
/* |
2 |
openisis - an open implementation of the CDS/ISIS database |
3 |
Version 0.8.x (patchlevel see file Version) |
4 |
Copyright (C) 2001-2003 by Erik Grziwotz, erik@openisis.org |
5 |
|
6 |
This library is free software; you can redistribute it and/or |
7 |
modify it under the terms of the GNU Lesser General Public |
8 |
License as published by the Free Software Foundation; either |
9 |
version 2.1 of the License, or (at your option) any later version. |
10 |
|
11 |
This library is distributed in the hope that it will be useful, |
12 |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
14 |
Lesser General Public License for more details. |
15 |
|
16 |
You should have received a copy of the GNU Lesser General Public |
17 |
License along with this library; if not, write to the Free Software |
18 |
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
19 |
|
20 |
see README for more information |
21 |
EOH */ |
22 |
|
23 |
/* |
24 |
$Id: openjsis.c,v 1.17 2003/04/08 00:20:53 kripke Exp $ |
25 |
main file of openjsis java native lib. |
26 |
*/ |
27 |
|
28 |
#include <stdlib.h> /* free */ |
29 |
#include <memory.h> /* memcpy */ |
30 |
|
31 |
#include "openisis.h" |
32 |
#define index stupidgcc |
33 |
/* |
34 |
java/jdk1.3/include/jni.h:607: warning: declaration of `index' shadows global declaration |
35 |
jobject (JNICALL *GetObjectArrayElement) |
36 |
(JNIEnv *env, jobjectArray array, jsize index); |
37 |
*/ |
38 |
#include "org/openisis/NativeDb.h" |
39 |
#undef index |
40 |
|
41 |
|
42 |
|
43 |
/* ************************************************************ |
44 |
private types |
45 |
*/ |
46 |
/* ************************************************************ |
47 |
private data |
48 |
*/ |
49 |
/* ************************************************************ |
50 |
private functions |
51 |
*/ |
52 |
static jobjectArray rec2bytes (JNIEnv* env, OpenIsisRec *r ) |
53 |
{ |
54 |
jobjectArray jarr = 0; |
55 |
jintArray ia; |
56 |
jint ji; |
57 |
jbyteArray ba; |
58 |
int i; |
59 |
|
60 |
if ( ! r ) |
61 |
return 0; |
62 |
|
63 |
jarr = (*env)->NewObjectArray( env, 1+r->len, |
64 |
(*env)->FindClass( env, "java/lang/Object" ), 0 ); |
65 |
if ( ! jarr ) |
66 |
return 0; |
67 |
|
68 |
ia = (*env)->NewIntArray( env, 1+r->len ); |
69 |
(*env)->SetObjectArrayElement( env, jarr, 0, ia ); |
70 |
|
71 |
ji = r->rowid; |
72 |
(*env)->SetIntArrayRegion( env, ia, 0, 1, &ji ); |
73 |
|
74 |
for ( i=0; i<r->len; i++ ) { |
75 |
OpenIsisField *f = &r->field[i]; |
76 |
ba = (*env)->NewByteArray( env, f->len ); |
77 |
if ( ! ba ) |
78 |
break; |
79 |
ji = f->tag; |
80 |
(*env)->SetIntArrayRegion( env, ia, i+1, 1, &ji ); |
81 |
(*env)->SetByteArrayRegion( env, ba, 0, f->len, (jbyte*)f->val ); |
82 |
(*env)->SetObjectArrayElement( env, jarr, i+1, ba ); |
83 |
} |
84 |
return jarr; |
85 |
} /* rec2bytes */ |
86 |
|
87 |
static OpenIsisRec* bytes2rec ( JNIEnv* env, jobjectArray arr ) { |
88 |
jsize len; |
89 |
jsize alen; |
90 |
jintArray ia; |
91 |
jbyteArray ba; |
92 |
OpenIsisRec* rec; |
93 |
int i; |
94 |
jint ji; |
95 |
jint* tags; |
96 |
char *txt; |
97 |
|
98 |
/* initialize record */ |
99 |
rec = 0; |
100 |
OPENISIS_RSPACE( rec, 8*1024, -1 ); |
101 |
|
102 |
len = (*env)->GetArrayLength( env, arr ); |
103 |
if ( 1 > len ) |
104 |
return 0; |
105 |
|
106 |
ia = (*env)->GetObjectArrayElement( env, arr, 0 ); |
107 |
if ( ! ia ) |
108 |
return 0; |
109 |
|
110 |
(*env)->GetIntArrayRegion( env, ia, 0, 1, &ji ); |
111 |
rec->rowid = ji; |
112 |
|
113 |
/* strip rowid / type description from length */ |
114 |
--len; |
115 |
tags = malloc( len * sizeof( jint ) ); |
116 |
(*env)->GetIntArrayRegion( env, ia, 1, len, tags ); |
117 |
|
118 |
for ( i = 0; i < len; i++ ) { |
119 |
ba = (*env)->GetObjectArrayElement( env, arr, i + 1 ); |
120 |
alen = (*env)->GetArrayLength( env, ba ); |
121 |
txt = malloc( alen ); |
122 |
memset( txt, 0, alen ); |
123 |
(*env)->GetByteArrayRegion( env, ba, 0, alen, (jbyte*)txt ); |
124 |
OPENISIS_RADD( rec, tags[ i ], txt, alen, 0 ); |
125 |
if ( txt ) |
126 |
free( txt ); |
127 |
} |
128 |
if ( tags ) |
129 |
free( tags ); |
130 |
return rec; |
131 |
} /* bytes2rec */ |
132 |
|
133 |
|
134 |
/* ************************************************************ |
135 |
package functions |
136 |
*/ |
137 |
/* ************************************************************ |
138 |
public functions |
139 |
*/ |
140 |
JNIEXPORT jshort JNICALL Java_org_openisis_NativeDb_nopen |
141 |
(JNIEnv* env, jclass cls, jstring jdbname, jobjectArray jargs) |
142 |
{ |
143 |
int db; |
144 |
const char *dbname = 0; |
145 |
const char **argv = 0; |
146 |
int argc = 0; |
147 |
jsize i; |
148 |
|
149 |
(void)cls; |
150 |
dbname = ! jdbname ? 0 : |
151 |
(*env)->GetStringUTFChars( env, jdbname, 0 ); |
152 |
if ( jargs ) { |
153 |
argc = (*env)->GetArrayLength( env, jargs ); |
154 |
argv = malloc( argc * sizeof(*argv) ); |
155 |
if ( argv ) |
156 |
for ( i=0; i<argc; i++ ) |
157 |
argv[i] = (*env)->GetStringUTFChars( env, |
158 |
(*env)->GetObjectArrayElement( env, jargs, i ), 0 ); |
159 |
} |
160 |
db = openIsisOpen( dbname, argv, argc ); |
161 |
if ( dbname ) |
162 |
(*env)->ReleaseStringUTFChars( env, jdbname, dbname ); |
163 |
if ( argv ) |
164 |
for ( i=0; i<argc; i++ ) |
165 |
if ( argv[i] ) |
166 |
(*env)->ReleaseStringUTFChars( env, |
167 |
(*env)->GetObjectArrayElement( env, jargs, i ), argv[i] ); |
168 |
return db; |
169 |
} /* Java_org_openisis_Db_open */ |
170 |
|
171 |
|
172 |
JNIEXPORT jobjectArray JNICALL Java_org_openisis_NativeDb_nreadRow |
173 |
(JNIEnv* env, jclass cls, jshort db, jint rowid, jint tag, jbyteArray txt ) |
174 |
{ |
175 |
OpenIsisRec *r; |
176 |
jobjectArray jarr = 0; |
177 |
(void)cls; |
178 |
if ( ! txt ) |
179 |
r = openIsisReadRow( db, rowid ); |
180 |
else { |
181 |
jsize l = (*env)->GetArrayLength( env, txt ); |
182 |
char *search = malloc( l+1 ); |
183 |
(*env)->GetByteArrayRegion( env, txt, 0, l, (jbyte*)search ); |
184 |
search[l] = 0; |
185 |
r = openIsisScan( db, rowid, tag, search ); |
186 |
free( search ); |
187 |
} |
188 |
jarr = rec2bytes( env, r ); |
189 |
if ( r ) free( r ); |
190 |
#ifndef NDEBUG |
191 |
fflush( stderr ); |
192 |
#endif |
193 |
return jarr; |
194 |
} /* Java_org_openisis_Db_readRow */ |
195 |
|
196 |
/* |
197 |
* please leave me in for debugging ;) |
198 |
* static int print ( OpenIsisRec *r ) |
199 |
{ |
200 |
int i; |
201 |
if ( r ) { |
202 |
for ( i=0; i<r->len; i++ ) { |
203 |
if ( ! r->field[i].val ) { |
204 |
openIsisSMsg( 1, "%d.?=%d\n", r->rowid, r->field[i].len ); |
205 |
continue; |
206 |
} |
207 |
openIsisSMsg( 1, "%d.%d=%.*s\n", r->rowid, r->field[i].tag, |
208 |
(int)r->field[i].len, r->field[i].val ); |
209 |
if ( r->field[i].len && '^' == *r->field[i].val ) { |
210 |
OpenIsisRec *rf = openIsisReadField( 0, r->field+i ); |
211 |
if ( rf ) { |
212 |
int j; |
213 |
for ( j=0; j<rf->len; j++ ) |
214 |
openIsisSMsg( 1, "%d.%d.%c=%.*s\n", |
215 |
r->rowid, r->field[i].tag, |
216 |
(0x60 & (int)rf->field[j].tag ) ? |
217 |
(int)rf->field[j].tag : ' ', |
218 |
(int)rf->field[j].len, rf->field[j].val ); |
219 |
free( rf ); |
220 |
} |
221 |
} |
222 |
} |
223 |
} |
224 |
return ! r ? -1 : r->rowid; |
225 |
} */ |
226 |
|
227 |
JNIEXPORT jshort JNICALL Java_org_openisis_NativeDb_nwriteRow |
228 |
(JNIEnv* env, jclass cls, jshort db, jobjectArray arr ) |
229 |
{ |
230 |
OpenIsisRec *r; |
231 |
jint result; |
232 |
/* no warning */ |
233 |
(void) cls; |
234 |
if ( ! arr ) |
235 |
return -1; |
236 |
r = bytes2rec( env, arr ); |
237 |
if ( ! r ) |
238 |
return -1; |
239 |
result = openIsisWrite( db, r ); |
240 |
if ( r ) |
241 |
free( r ); |
242 |
return result; |
243 |
} |
244 |
|
245 |
JNIEXPORT jshort JNICALL Java_org_openisis_NativeDb_nwriteXRow |
246 |
(JNIEnv* env, jclass cls, jshort db, jobjectArray arr, jobjectArray idx ) |
247 |
{ |
248 |
OpenIsisRec *r; |
249 |
OpenIsisRec *i; |
250 |
jint result; |
251 |
/* no warning */ |
252 |
(void) cls; |
253 |
if ( ! arr || ! idx ) |
254 |
return -1; |
255 |
r = bytes2rec( env, arr ); |
256 |
i = bytes2rec( env, idx ); |
257 |
if ( ! r || ! i ) |
258 |
return -1; |
259 |
result = openIsisWritex( db, r, i ); |
260 |
if ( r ) |
261 |
free( r ); |
262 |
if ( i ) |
263 |
free( i ); |
264 |
return result; |
265 |
} |
266 |
|
267 |
JNIEXPORT jobjectArray JNICALL Java_org_openisis_NativeDb_nTerms |
268 |
(JNIEnv* env, jclass cls, jshort db, jbyteArray term, jbyteArray start ) |
269 |
{ |
270 |
OpenIsisRec *r; |
271 |
jobjectArray jarr = 0; |
272 |
jsize lterm = (*env)->GetArrayLength( env, term ); |
273 |
char *cterm = malloc( lterm+1 ); |
274 |
union { OpenIsisRec r; char buf[4096]; } x; |
275 |
x.r.len = 0; |
276 |
x.r.bytes = sizeof(x); |
277 |
(void)cls; |
278 |
(*env)->GetByteArrayRegion( env, term, 0, lterm, (jbyte*)cterm ); |
279 |
cterm[lterm] = 0; |
280 |
if ( start ) { |
281 |
char *cstart; |
282 |
jsize lstart = (*env)->GetArrayLength( env, start ); |
283 |
if ( 128 < lstart ) |
284 |
lstart = 128; |
285 |
cstart = x.buf + sizeof(x.r); |
286 |
(*env)->GetByteArrayRegion( env, start, 0, lstart, (jbyte*)cstart ); |
287 |
x.r.field[0].val = cstart; |
288 |
x.r.field[0].len = lstart; |
289 |
x.r.len = 1; |
290 |
} |
291 |
r = openIsisTerm( &x.r, db, cterm ); |
292 |
free( cterm ); |
293 |
jarr = rec2bytes( env, r ); |
294 |
#ifndef NDEBUG |
295 |
fflush( stderr ); |
296 |
#endif |
297 |
return jarr; |
298 |
} /* Java_org_openisis_Db_Terms */ |
299 |
|
300 |
|
301 |
|
302 |
JNIEXPORT jintArray JNICALL Java_org_openisis_NativeDb_nsearch |
303 |
(JNIEnv * env, jclass cls, jshort db, jbyteArray key, jint mode) |
304 |
{ |
305 |
jsize l; |
306 |
char *search; |
307 |
OpenIsisSet set; |
308 |
jintArray ia; |
309 |
(void)cls; |
310 |
if ( ! key ) |
311 |
return 0; |
312 |
l = (*env)->GetArrayLength( env, key ); |
313 |
search = malloc( l+1 ); |
314 |
(*env)->GetByteArrayRegion( env, key, 0, l, (jbyte*)search ); |
315 |
search[l] = 0; |
316 |
set.len = 0; |
317 |
openIsisQuery( &set, db, search, mode, 0 ); |
318 |
free( search ); |
319 |
if ( 0 >= set.len ) |
320 |
return 0; |
321 |
ia = (*env)->NewIntArray( env, set.len ); |
322 |
(*env)->SetIntArrayRegion( env, ia, 0, set.len, (jint*)set.id ); |
323 |
return ia; |
324 |
} /* Java_org_openisis_Db_search */ |