/* * Created on Nov 24, 2004 */ package fr.lifl.stc.stan.execution.stack; import java.util.HashSet; import java.util.Iterator; import fr.lifl.stc.stan.execution.Interpreter; import org.apache.bcel.SignatureConstants; import org.apache.bcel.generic.Type; /** * @author yann * @author dorina */ public class MultiObject { private HashSet m_set; /** * */ public MultiObject() { super(); m_set = new HashSet(); } public void add(JvmType t) { /* if(t instanceof Reference){ Reference rt = (Reference)t; Reference whole = rt.getAll(); if(contains(whole)) return; if( (rt.isSecretPart() && contains(whole.getPublic())) || (rt.isPublicPart() && contains(whole.getSecret()))) { this.m_set.remove(whole.getPublic()); this.m_set.remove(whole.getSecret()); this.m_set.add(whole); } else this.m_set.add(t); }else */ m_set.add(t); } public boolean contains(JvmType t) { return m_set.contains(t); } public Object clone() { MultiObject c = new MultiObject(); Iterator it = m_set.iterator(); while(it.hasNext()) { c.m_set.add(it.next()); } return c; } public int size() { return m_set.size(); } public boolean equals(Object o) { if(!(o instanceof MultiObject)) return false; MultiObject obj = (MultiObject)o; if (size() != obj.size()) return false; Iterator it = m_set.iterator(); while (it.hasNext()){ if( !obj.m_set.contains(it.next()) ) return false; } return true; } public boolean merge(MultiObject o) { boolean res = false; Iterator it = o.m_set.iterator(); while(it.hasNext()) { JvmType t = it.next(); if (!contains(t)) { res = true; add(t); } } return res; } public JvmType[] content() { JvmType[] res = new JvmType[m_set.size()]; Iterator it = m_set.iterator(); int i = 0; while(it.hasNext()) { res[i] = it.next(); i++; } return res; // return (JvmType[])m_set.toArray(); } public int typeSize() { Iterator it = m_set.iterator(); return it.next().typeSize(); } public String toString() { String res = "(:"; Iterator it = m_set.iterator(); while(it.hasNext()) { res += it.next() + ":"; } return res + ")"; } public Type getReferenceType() { if(m_set.size() == 0) return null; Iterator it = m_set.iterator(); JvmType type = it.next(); if(type instanceof Reference) { return ((Reference)type).getType(); } else return null; } public boolean hasExactType() { if(m_set.size() == 0) return false; Iterator it = m_set.iterator(); JvmType type = it.next(); if(type instanceof Reference) { String typename = ((Reference) type).getTypeName(); boolean exact = ((Reference) type).isExactType(); if(!exact) return false; while(it.hasNext()) { type = it.next(); if(type instanceof Reference) { Reference r = (Reference) type; if(!r.isExactType() || (!r.getTypeName().equals(typename))) return false; } } return true; } else return true; } public Type getExactType() { if(!hasExactType()) return null; Iterator it = m_set.iterator(); JvmType type = it.next(); return type.getType(); } /** * * @param codification * @param interpreter * @return an array of bytes representing the format used in .class file. * The format of the array: * total_size array_of_jvmTypes */ public byte[] toBytes(int codification, Interpreter interpreter){ byte[] output = null; int length = 0; int index; //computes length byte[] arrayTmp = SignatureConstants.toByteArray(this.size(), SignatureConstants.MULTIOBJECT_LENGTH_SIZE); length += arrayTmp.length; length += this.size()* JvmType.toBytesLength(codification);// SignatureConstants.JVMTYPE_SIZE; output = new byte[length]; //puts size in front of array of bytes index = 0; System.arraycopy( arrayTmp, 0, output, index, arrayTmp.length ); index += arrayTmp.length; //puts the contents JvmType [] content = this.content(); for(int i = 0; i < content.length; i++) { arrayTmp = content[i].toBytes(codification, interpreter); System.arraycopy(arrayTmp, 0, output, index, arrayTmp.length); index += arrayTmp.length; } return output; } public int toBytesSize(int codification , Interpreter intr) { return toBytes(codification, intr).length; } /** * codification of an array of multiObjects * length array_of_multiObject * * codification: number of bytes to use for op (1 or 2) * @return */ public static byte[] toBytes(MultiObject[] input, int input_size, int codification, Interpreter intr){ byte[] output = null; int length = 0; int index; if(input_size>input.length) input_size = input.length; //System.out.println("=============inout_size="+input_size); //computes length byte[] arrayTmp = SignatureConstants.toByteArray(input_size, SignatureConstants.MULTIOBJECT_LENGTH_SIZE); length += arrayTmp.length; for(int i = 0 ; i < input_size; i++) { MultiObject mo = input[i]; length += mo.toBytesSize(codification, intr); } output = new byte[length]; //puts size in front of array of bytes index = 0; System.arraycopy( arrayTmp, 0, output, index, arrayTmp.length ); index += arrayTmp.length; //puts multiobjects for(int i = 0 ; i < input_size; i++) { MultiObject mo = input[i]; arrayTmp = mo.toBytes(codification, intr); System.arraycopy(arrayTmp, 0, output, index, arrayTmp.length); index += arrayTmp.length; } return output; } }