improvement: path limit in URL works without full result display
[webpac] / openisis / openjsis.c
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 */