/* Software Name : AsmDex * Version : 1.0 * * Copyright © 2012 France Télécom * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the copyright holders nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGE. */ package org.ow2.asmdex.encodedValue; import org.ow2.asmdex.Opcodes; import org.ow2.asmdex.lowLevelUtils.ByteVector; import org.ow2.asmdex.structureWriter.ConstantPool; import java.util.ArrayList; /** * Class representing an Encoded Array. * * @author Julien Névo */ public class EncodedValueArray extends EncodedValue { /** * The Type of the Encoded Value. */ private int type = Opcodes.VALUE_ARRAY; /** * The Encoded Values. */ private ArrayList<EncodedValue> encodedValues = new ArrayList<EncodedValue>(); // ----------------------------------------------------- // Getters and Setters. // ----------------------------------------------------- @Override public int getType() { return type; } /** * Returns the Encoded Values. * @return the Encoded Values. */ public ArrayList<EncodedValue> getEncodedValues() { return encodedValues; } /** * Returns the number of Encoded Values. * @return the number of Encoded Values. */ public int getNbEncodedValues() { return encodedValues.size(); } // ----------------------------------------------------- // Public methods. // ----------------------------------------------------- /** * Adds an Encoded Value to the list. * @param encodedValue the Encoded Value to add. */ public void addEncodedValue(EncodedValue encodedValue) { encodedValues.add(encodedValue); } @Override public byte[] encode(ConstantPool constantPool) { ByteVector out = new ByteVector(); // Encodes first the value_array. out.putByte(Opcodes.VALUE_ARRAY); // Encodes then the encoded_array format. out.putUleb128(getNbEncodedValues()); // Encodes each Encoded Value of the array. for (EncodedValue encodedValue : encodedValues) { out.putByteArray(encodedValue.encode(constantPool)); } return out.getData(); } // ----------------------------------------------------- // Overridden Methods. // ----------------------------------------------------- @Override public boolean equals(Object o) { if (this == o) { return true; } boolean result = false; if (o instanceof EncodedValueArray) { EncodedValueArray encodedValue = (EncodedValueArray)o; result = encodedValues.equals(encodedValue.encodedValues); } return result; } @Override public int hashCode() { int result = type; for (EncodedValue encodedValue : encodedValues) { result += encodedValue.hashCode(); } return result; } @Override int compareValue(EncodedValue encodedValue) { EncodedValueArray ea = (EncodedValueArray)encodedValue; int size1 = encodedValues.size(); int size2 = ea.encodedValues.size(); int size = size1 < size2 ? size1 : size2; int result = 0; int i = 0; while ((result == 0) && (i < size)) { EncodedValue v1 = encodedValues.get(i); EncodedValue v2 = ea.encodedValues.get(i); int v1Type = v1.getType(); int v2Type = v2.getType(); result = v1Type == v2Type ? 0 : (v1Type < v2Type ? -1 : 1); // Only compare the actual value if their type is the same, else it // doesn't mean anything. if (result == 0) { result = encodedValues.get(i).compareTo(ea.encodedValues.get(i)); i++; } } if (result == 0) { result = size1 == size2 ? 0 : (size1 < size2 ? -1 : 1); } return result; } @Override public String toString() { StringBuilder result = new StringBuilder(); boolean isFirst = true; for(EncodedValue ev: encodedValues) { if (isFirst) { result.append("{"); isFirst = false; } else result.append(","); result.append(ev); } result.append("}"); return result.toString(); } }