// Decompiled by Jad v1.5.8e. Copyright 2001 Pavel Kouznetsov.
// Jad home page: http://www.geocities.com/kpdus/jad.html
// Decompiler options: packimports(3) fieldsfirst 
// Source File Name:   ConstantPool.java

package lt.monarch.jasm;

import java.io.DataOutputStream;
import java.io.IOException;
import java.util.Vector;

public class ConstantPool
{

	Vector pool;
	String thisClassName;

	public void setThisClassName(String s)
	{
		thisClassName = s;
	}

	public int define(double d)
	{
		return findOrAdd(new Double(d), true);
	}

	public int define(float f)
	{
		return findOrAdd(new Float(f), true);
	}

	public int define(int i)
	{
		return findOrAdd(new Integer(i), false);
	}

	public int define(long l)
	{
		return findOrAdd(new Long(l), true);
	}

	public int define(String s)
	{
		return findOrAdd(new int[] {
			8, defineUTF8(s)
		}, false);
	}

	public int defineClass(String s)
	{
		if(s == null)
			s = thisClassName;
		return findOrAdd(new int[] {
			7, defineUTF8(s.replace('.', '/'))
		}, false);
	}

	public int defineNameAndType(String s, String s1)
	{
		return findOrAdd(new int[] {
			12, defineUTF8(s), defineUTF8(s1)
		}, false);
	}

	public int defineMethod(String s, String s1, String s2)
	{
		return findOrAdd(new int[] {
			10, defineClass(s), defineNameAndType(s1, s2)
		}, false);
	}

	public int defineField(String s, String s1, String s2)
	{
		return findOrAdd(new int[] {
			9, defineClass(s), defineNameAndType(s1, s2)
		}, false);
	}

	protected int defineUTF8(String s)
	{
		return findOrAdd(s, false);
	}

	private boolean constantsEqual(Object obj, Object obj1)
	{
		if(obj == obj1)
			return true;
		if(obj == null || obj1 == null)
			return false;
		if(obj.getClass() != obj1.getClass())
			return false;
		if(obj instanceof int[])
		{
			int ai[] = (int[])obj;
			int ai1[] = (int[])obj1;
			if(ai.length != ai1.length)
				return false;
			for(int i = 0; i < ai.length; i++)
				if(ai[i] != ai1[i])
					return false;

			return true;
		} else
		{
			return obj.equals(obj1);
		}
	}

	private int findOrAdd(Object obj, boolean flag)
	{
		for(int i = 0; i < pool.size(); i++)
			if(constantsEqual(obj, pool.elementAt(i)))
				return i + 1;

		pool.addElement(obj);
		if(flag)
		{
			pool.addElement(null);
			return pool.size() - 1;
		} else
		{
			return pool.size();
		}
	}

	void writeTo(DataOutputStream dataoutputstream)
		throws IOException
	{
		dataoutputstream.writeShort(pool.size() + 1);
		for(int i = 0; i < pool.size(); i++)
			writePoolEntry(dataoutputstream, pool.elementAt(i));

	}

	void writePoolEntry(DataOutputStream dataoutputstream, Object obj)
		throws IOException
	{
		if(obj instanceof Double)
		{
			dataoutputstream.write(6);
			dataoutputstream.writeDouble(((Double)obj).doubleValue());
		}
		if(obj instanceof Float)
		{
			dataoutputstream.write(4);
			dataoutputstream.writeFloat(((Float)obj).floatValue());
		}
		if(obj instanceof Integer)
		{
			dataoutputstream.write(3);
			dataoutputstream.writeInt(((Integer)obj).intValue());
		}
		if(obj instanceof Long)
		{
			dataoutputstream.write(5);
			dataoutputstream.writeLong(((Long)obj).longValue());
		} else
		if(obj instanceof String)
		{
			dataoutputstream.write(1);
			dataoutputstream.writeUTF((String)obj);
		} else
		if(obj instanceof int[])
		{
			int ai[] = (int[])obj;
			dataoutputstream.write(ai[0]);
			for(int i = 1; i < ai.length; i++)
				dataoutputstream.writeShort(ai[i]);

		}
	}

	public ConstantPool()
	{
		pool = new Vector();
	}
}
