FileDocCategorySizeDatePackage
DBM.javaAPI DocExample3702Sat Jun 24 20:10:14 BST 2000None

DBM.java

import java.io.*;

/** This class provides a dbm-compatible interface to the UNIX-style
 * database access methods described in dbm(3) (which is on some UNIXes
 * a front-end to db(3).
 * <P>Each unique record in the database is a unique key/value pair,
 * similar to a java.util.Hashtable but stored on persistent medium, not
 * kept in memory. Dbm was originally optimized for UNIX for fast
 * access to individual key/value pairs.
 *
 * @author This Java/C hookup by Ian F. Darwin, ian@darwinsys.com
 * @version $Id: DBM.java,v 1.12 2000/06/24 23:10:14 ian Exp $
 */
public class DBM {
	/** Since you can only have one DBM database in use at a time due
	 * to implementation restrictions, we enforce this rule with a
	 * class-wide boolean.
	 */
	protected static boolean inuse = false;

	/** Save the filename for messages, etc. */
	protected String fileName;

	/** Construct a DBM given its filename */
	public DBM(String file) {
		synchronized(this) {
			if (inuse)
				throw new IllegalArgumentException(
					"Only one DBM object at a time per Java Machine");
			inuse = true;
		}
		fileName = file;
		int retCode = dbminit(fileName);
		if (retCode < 0)
			throw new IllegalArgumentException(
				"dbminit failed, code = " + retCode);
	}

	// Static code blocks are executed once, when class file is loaded.
	// This is here to ensure that the shared library gets loaded.
	static {
		System.loadLibrary("jdbm");
	}

	protected ByteArrayOutputStream bo;

	/** serialize an Object to byte array. */
	protected byte[] toByteArray(Object o) throws IOException {
		if (bo == null)
			bo = new ByteArrayOutputStream(1024);
		bo.reset();
		ObjectOutputStream os = new ObjectOutputStream(bo);
		os.writeObject(o);
		os.close();
		return bo.toByteArray();
	}

	/** un-serialize an Object from a byte array. */
	protected Object toObject(byte[] b) throws IOException {
		Object o;

		ByteArrayInputStream bi = new ByteArrayInputStream(b);
		ObjectInputStream os = new ObjectInputStream(bi);
		try {
			o = os.readObject();
		} catch (ClassNotFoundException ex) {
			// Convert ClassNotFoundException to I/O error
			throw new IOException(ex.getMessage());
		}
		os.close();
		return o;
	}

	protected native int dbminit(String file);

	protected native int dbmclose();

	/** Public wrapper for close method. */
	public void close() {
		this.dbmclose();
		inuse = false;
	}

	protected void checkInUse() {
		if (!inuse)
			throw new IllegalStateException("Method called when DBM not open");
	}

	protected native byte[] dbmfetch(byte[] key);

	/** Fetch using byte arrays */
	public byte[] fetch(byte[] key) throws IOException {
		checkInUse();
		return dbmfetch(key);
	}

	/** Fetch using Objects */
	public Object fetch(Object key) throws IOException {
		checkInUse();
		byte[] datum = dbmfetch(toByteArray(key));
		return toObject(datum);
	}

	protected native int dbmstore(byte[] key, byte[] content);

	/** Store using byte arrays */
	public void store(byte[] key, byte[] value) throws IOException {
		checkInUse();
		dbmstore(key, value);
	}

	/** Store using Objects */
	public void store(Object key, Object value) throws IOException {
		checkInUse();
		dbmstore(toByteArray(key), toByteArray(value));
	}

	protected native int delete(Object key);

	public native byte[] firstkey() throws IOException;

	public Object firstkeyObject() throws IOException {
		return toObject(firstkey());
	}

	public native byte[] nextkey(byte[] key) throws IOException;

	public Object nextkey(Object key) throws IOException {
		byte[] ba = nextkey(toByteArray(key));
		if (ba == null)
			return null;
		return toObject(ba);
	}

	public String toString() {
		return "DBM@" + hashCode() + "[" + fileName + "]";
	}
}