Coverage Summary for Class: ABICallSpec (co.rsk.peg)

Class Method, % Line, %
ABICallSpec 0% (0/11) 0% (0/37)
ABICallSpec$1 0% (0/2) 0% (0/4)
Total 0% (0/13) 0% (0/41)


1 /* 2  * This file is part of RskJ 3  * Copyright (C) 2017 RSK Labs Ltd. 4  * 5  * This program is free software: you can redistribute it and/or modify 6  * it under the terms of the GNU Lesser General Public License as published by 7  * the Free Software Foundation, either version 3 of the License, or 8  * (at your option) any later version. 9  * 10  * This program is distributed in the hope that it will be useful, 11  * but WITHOUT ANY WARRANTY; without even the implied warranty of 12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13  * GNU Lesser General Public License for more details. 14  * 15  * You should have received a copy of the GNU Lesser General Public License 16  * along with this program. If not, see <http://www.gnu.org/licenses/>. 17  */ 18  19 package co.rsk.peg; 20  21 import com.google.common.primitives.SignedBytes; 22  23 import java.nio.charset.StandardCharsets; 24 import java.util.Arrays; 25 import java.util.Comparator; 26 import java.util.Objects; 27  28 /** 29  * Immutable representation of a function call 30  * spec to any given contract. 31  * For simplicity, each of the arguments is assumed to be a byte array. 32  * Encoding is up to the user. 33  * 34  * @author Ariel Mendelzon 35  */ 36 public final class ABICallSpec { 37  public static final Comparator<ABICallSpec> byBytesComparator = new Comparator<ABICallSpec>() { 38  @Override 39  public int compare(ABICallSpec specA, ABICallSpec specB) { 40  return SignedBytes.lexicographicalComparator().compare( 41  specA.getEncoded(), 42  specB.getEncoded() 43  ); 44  } 45  }; 46  47  private String function; 48  private byte[][] arguments; 49  50  public ABICallSpec(String function, byte[][] arguments) { 51  this.function = function; 52  // Keep internal copies, so that the instance 53  // is immutable 54  this.arguments = copy(arguments); 55  } 56  57  public String getFunction() { 58  return function; 59  } 60  61  public byte[][] getArguments() { 62  return copy(arguments); 63  } 64  65  public byte[] getEncoded() { 66  byte[] functionBytes = function.getBytes(StandardCharsets.UTF_8); 67  int totalLength = functionBytes.length; 68  for (int i = 0; i < arguments.length; i++) { 69  totalLength += arguments[i].length; 70  } 71  byte[] result = new byte[totalLength]; 72  System.arraycopy(functionBytes, 0, result, 0, functionBytes.length); 73  int offset = functionBytes.length; 74  for (int i = 0; i < arguments.length; i++) { 75  System.arraycopy(arguments[i], 0, result, offset, arguments[i].length); 76  offset += arguments[i].length; 77  } 78  return result; 79  } 80  81  @Override 82  public String toString() { 83  return String.format("Call to %s with %d arguments", function, arguments.length); 84  } 85  86  @Override 87  public boolean equals(Object other) { 88  if (this == other) { 89  return true; 90  } 91  92  if (other == null || this.getClass() != other.getClass()) { 93  return false; 94  } 95  96  ABICallSpec otherSpec = ((ABICallSpec) other); 97  return otherSpec.getFunction().equals(getFunction()) && 98  areEqual(arguments, otherSpec.arguments); 99  } 100  101  @Override 102  public int hashCode() { 103  int[] argumentsHashes = Arrays.stream(arguments).map(argument -> Arrays.hashCode(argument)).mapToInt(Integer::intValue).toArray(); 104  return Objects.hash(function, Arrays.hashCode(argumentsHashes)); 105  } 106  107  private boolean areEqual(byte[][] first, byte[][] second) { 108  if (first.length != second.length) { 109  return false; 110  } 111  112  for (int i = 0; i < first.length; i++) { 113  if (!Arrays.equals(first[i], second[i])) { 114  return false; 115  } 116  } 117  118  return true; 119  } 120  121  private byte[][] copy(byte[][] array) { 122  byte[][] result = new byte[array.length][]; 123  for (int i = 0; i < array.length; i++) { 124  result[i] = Arrays.copyOf(array[i], array[i].length); 125  } 126  return result; 127  } 128 }