gcc/libjava/gnu/gcj/tools/gcj_dbtool/Main.java

273 lines
6.6 KiB
Java

/* Copyright (C) 2004 Free Software Foundation
This file is part of libgcj.
This software is copyrighted work licensed under the terms of the
Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
details. */
package gnu.gcj.tools.gcj_dbtool;
import gnu.gcj.runtime.PersistentByteMap;
import java.io.*;
import java.util.*;
import java.util.jar.*;
import java.security.MessageDigest;
import java.math.BigInteger;
public class Main
{
public static void main (String[] s)
{
insist (s.length >= 1);
if (s[0].equals("-v"))
{
insist (s.length == 1);
System.out.println("jv-dbtool ("
+ System.getProperty("java.vm.name")
+ ") "
+ System.getProperty("java.vm.version"));
System.out.println();
System.out.println("Copyright 2004 Free Software Foundation, Inc.");
System.out.println("This is free software; see the source for copying conditions. There is NO");
System.out.println("warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.");
return;
}
if (s[0].equals("-n"))
{
insist (s.length >= 2 && s.length <= 3);
int capacity = 32749;
if (s.length == 3)
{
// The user has explicitly provided a size for the table.
// We're going to make that size prime. This isn't
// strictly necessary but it can't hurt.
BigInteger size = new BigInteger(s[2], 10);
BigInteger two = BigInteger.ONE.add(BigInteger.ONE);
if (size.getLowestSetBit() != 0) // A hard way to say isEven()
size = size.add(BigInteger.ONE);
while (! size.isProbablePrime(10))
size = size.add(two);
capacity = size.intValue();
if (capacity <= 2)
{
usage();
System.exit(1);
}
}
try
{
PersistentByteMap b
= PersistentByteMap.emptyPersistentByteMap (s[1], capacity, capacity*64);
}
catch (Exception e)
{
System.err.println ("error: could not create "
+ s[1] + ": " + e.toString());
System.exit(2);
}
return;
}
if (s[0].equals("-a"))
{
try
{
insist (s.length == 4);
File jar = new File(s[2]);
PersistentByteMap b
= new PersistentByteMap(new File(s[1]),
PersistentByteMap.AccessMode.READ_WRITE);
File soFile = new File(s[3]);
if (! soFile.isFile())
throw new IllegalArgumentException(s[3] + " is not a file");
addJar(jar, b, soFile);
}
catch (Exception e)
{
System.err.println ("error: could not update " + s[1]
+ ": " + e.toString());
System.exit(2);
}
return;
}
if (s[0].equals("-t"))
{
try
{
insist (s.length == 2);
PersistentByteMap b
= new PersistentByteMap(new File(s[1]),
PersistentByteMap.AccessMode.READ_ONLY);
Iterator iterator = b.iterator(PersistentByteMap.ENTRIES);
while (iterator.hasNext())
{
PersistentByteMap.MapEntry entry
= (PersistentByteMap.MapEntry)iterator.next();
byte[] key = (byte[])entry.getKey();
byte[] value = (byte[])b.get(key);
if (! Arrays.equals (value, (byte[])entry.getValue()))
{
String err
= ("Key " + bytesToString(key) + " at bucket "
+ entry.getBucket());
throw new RuntimeException(err);
}
}
}
catch (Exception e)
{
e.printStackTrace();
System.exit(3);
}
return;
}
if (s[0].equals("-l"))
{
insist (s.length == 2);
try
{
PersistentByteMap b
= new PersistentByteMap(new File(s[1]),
PersistentByteMap.AccessMode.READ_ONLY);
System.out.println ("Capacity: " + b.capacity());
System.out.println ("Size: " + b.size());
System.out.println ();
System.out.println ("Elements: ");
Iterator iterator = b.iterator(PersistentByteMap.ENTRIES);
while (iterator.hasNext())
{
PersistentByteMap.MapEntry entry
= (PersistentByteMap.MapEntry)iterator.next();
byte[] digest = (byte[])entry.getKey();
System.out.print ("[" + entry.getBucket() + "] "
+ bytesToString(digest)
+ " -> ");
System.out.println (new String((byte[])entry.getValue()));
}
}
catch (Exception e)
{
System.err.println ("error: could not list "
+ s[1] + ": " + e.toString());
System.exit(2);
}
return;
}
if (s[0].equals("-d"))
{
insist (s.length == 2);
try
{
MessageDigest md = MessageDigest.getInstance("MD5");
PersistentByteMap b
= new PersistentByteMap(new File(s[1]),
PersistentByteMap.AccessMode.READ_WRITE);
int N = b.capacity();
byte[] bytes = new byte[1];
byte digest[] = md.digest(bytes);
for (int i = 0; i < N; i++)
{
digest = md.digest(digest);
b.put(digest, digest);
}
}
catch (Exception e)
{
e.printStackTrace();
System.exit(3);
}
return;
}
usage();
System.exit(1);
}
private static void insist(boolean ok)
{
if (! ok)
{
usage();
System.exit(1);
}
}
private static void usage()
{
System.err.println
("jv-dbtool: Manipulate gcj map database files\n"
+ "\n"
+ " Usage: \n"
+ " jv-dbtool -n file.gcjdb [size] - Create a new gcj map database\n"
+ " jv-dbtool -a file.gcjdb file.jar file.so\n"
+ " - Add the contents of file.jar to the database\n"
+ " jv-dbtool -t file.gcjdb - Test a gcj map database\n"
+ " jv-dbtool -l file.gcjdb - List a gcj map database\n");
}
private static void addJar(File f, PersistentByteMap b, File soFile)
throws Exception
{
MessageDigest md = MessageDigest.getInstance("MD5");
JarFile jar = new JarFile (f);
Enumeration entries = jar.entries();
while (entries.hasMoreElements())
{
JarEntry classfile = (JarEntry)entries.nextElement();
if (classfile.getName().endsWith(".class"))
{
InputStream str = jar.getInputStream(classfile);
long length = classfile.getSize();
if (length == -1)
throw new EOFException();
byte[] data = new byte[length];
int pos = 0;
while (length - pos > 0)
{
int len = str.read(data, pos, (int)(length - pos));
if (len == -1)
throw new EOFException("Not enough data reading from: "
+ classfile.getName());
pos += len;
}
b.put(md.digest(data),
soFile.getCanonicalPath().getBytes());
}
}
}
static String bytesToString(byte[] b)
{
StringBuffer hexBytes = new StringBuffer();
int length = b.length;
for (int i = 0; i < length; ++i)
hexBytes.append(Integer.toHexString(b[i] & 0xff));
return hexBytes.toString();
}
}