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
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.
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.
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
20 see README for more information
25 import java.io.IOException;
26 import java.io.FileNotFoundException;
27 import java.io.UnsupportedEncodingException;
28 import java.util.Iterator;
29 import java.util.NoSuchElementException;
33 This class is the native implementation of class Db.
35 The shared library "openjsis" must be loadable.
36 On a UNIX System, make sure that the file libopenjsis.so
37 resides in a directory listed by the environment variable
38 LD_LIBRARY_PATH or in /etc/ld.so.conf.
39 If you just drop it in /usr/lib or similar dir,
40 you may have to run a command like ldconfig.
42 On Windows, put openjsis.dll somewhere in the PATH.
44 $Id: NativeDb.java,v 1.5 2003/04/08 00:20:53 kripke Exp $
45 @version $Revision: 1.5 $
46 @author $Author: kripke $
48 public class NativeDb extends Db {
50 private static synchronized native
51 short nopen ( String dbname, String[] args );
53 /** read a record by rowid.
54 * The native implementation gives character data as byte[],
55 * since we need to employ java encoding mechanisms anyway.
56 * The tag is packed as four bytes little endian.
57 * @param db a db number as returned by open
58 * @param rowid the number (aka mfn) of the row
59 * @param tag in which to look for txt, negative for any
60 * @param txt to grep from record, null for no grep
61 * @return an array of Objects:
62 * the first is an array of ints filled with rowid an tags
63 * the others are byte[] with field character data in encoding
66 private static synchronized native
67 Object[] nreadRow ( short db, int rowid, int tag, byte[] txt );
69 /** search for terms */
70 private static synchronized native
71 Object[] nTerms ( short db, byte[] term, byte[] start );
73 /** get matching rowids */
74 private static synchronized native
75 int[] nsearch ( short db, byte[] key, int mode );
78 private static synchronized native
79 short nwriteRow ( short db, Object[] data );
83 * @param db database handle returned by open
84 * @param data an Object array with an int[] on idx 0 containing
85 * rowid and tags and with byte[] containing appropriate data for
86 * the tags; thus a simple sanity check for a properly structured
87 * data is: data.length == data[ 0 ].length
88 * @param idx same as data but contains a record that holds index
91 private static synchronized native
92 short nwriteXRow ( short db, Object[] data, Object[] idx );
95 // TODO: try some explicit paths like our jar's location with System.load
96 // in order to not have to export LD_LIBRARY_PATH or so
97 System.loadLibrary( "openjsis" );
100 public byte[] cvt ( String txt ) {
102 return txt.getBytes(encoding);
103 } catch ( UnsupportedEncodingException e ) {
104 // shouldn't happen -- our fault
105 throw new Error( "failed to check for support of encoding "+encoding );
109 public String cvt ( byte[] b ) {
111 // System.err.println( "got "+b.length+" bytes "+b );
112 for ( int l=b.length; 0<l; l-- ) {
113 String s = new String( b, 0, l, encoding );
114 if ( null != s && 0 != s.length() )
116 for ( int i=0; i<l; i++ )
119 b[i] > 0 ? "0" : // 0... self-contained
120 b[i] < -64 ? "f" : // 10... six follower bits
121 b[i] < -32 ? "1" : // 110... five bits, one follower
122 b[i] < -16 ? "2" : // 1110... four bits, two followers
129 } catch ( UnsupportedEncodingException e ) {
130 // shouldn't happen -- our fault
131 throw new Error( "failed to check for support of encoding "+encoding );
136 /** Number of this db.
138 public final short db;
141 public NativeDb ( String enc, String dbname, String[] args )
145 db = nopen( dbname, args );
147 throw new FileNotFoundException();
150 Rec mkRow ( Object[] buf ) {
153 int[] ids = (int[])buf[0];
155 Field[] f = new Field[ buf.length-1 ];
156 for ( int i=1; i<buf.length; i++ )
157 f[i-1] = new Field( ids[i], cvt( (byte[])buf[i] ) );
158 return new Rec( rowid, f );
161 Object[] mkBuf ( Rec rec ) {
164 int len = rec.getLen() + 1;
165 Object[] buf = new Object[ len ];
166 int[] tags = new int[ len ];
167 for ( int i = 1; i < len; i++ ) {
168 Field f = rec.getField( i - 1 );
170 buf[ i ] = cvt( f.val );
171 String tttt = new String( cvt( f.val ) );
172 System.out.println( "field [ " + i + "] = " + tttt + " len is " + tttt.length() );
174 tags[ 0 ] = rec.getRowId();
179 public Rec readRow ( int rowid ) {
180 return mkRow( nreadRow( db, rowid, -1, null ) );
183 public short writeRow ( Rec rec ) {
184 return nwriteRow( db, mkBuf( rec ) );
187 public short writeXRow ( Rec rec, Rec idx ) {
188 return nwriteXRow( db, mkBuf( rec ), mkBuf( idx ) );
191 public Rec scanRow ( int rowid, int tag, String txt ) {
192 return mkRow( nreadRow( db, rowid, tag, cvt(txt) ) );
195 public int[] search ( String key, int mode ) {
196 return nsearch( db, cvt(key), mode );
199 public class TermIterator implements Iterator {
204 public TermIterator ( String prefix ) {
205 _prefix = cvt(prefix+"$");
208 public boolean hasNext () {
209 if ( null != buf && nxt < buf.length ) return true;
210 if ( nxt < 0 ) return false;
211 nxt = -1; // mark, just in case we bomb
212 buf = nTerms( db, _prefix,
213 null == buf ? null : (byte[])buf[buf.length-1] );
214 if ( null == buf || 1 >= buf.length ) {
222 public Object next () {
223 if ( ! hasNext() ) throw new NoSuchElementException();
224 return cvt( (byte[])buf[nxt++] );
227 public void remove () { throw new UnsupportedOperationException(); }
231 public Iterator terms ( String prefix ) {
232 return new TermIterator( prefix );