Coverage Summary for Class: Value (org.ethereum.util)

Class Class, % Method, % Line, %
Value 0% (0/1) 0% (0/30) 0% (0/132)


1 /* 2  * This file is part of RskJ 3  * Copyright (C) 2017 RSK Labs Ltd. 4  * (derived from ethereumJ library, Copyright (c) 2016 <ether.camp>) 5  * 6  * This program is free software: you can redistribute it and/or modify 7  * it under the terms of the GNU Lesser General Public License as published by 8  * the Free Software Foundation, either version 3 of the License, or 9  * (at your option) any later version. 10  * 11  * This program is distributed in the hope that it will be useful, 12  * but WITHOUT ANY WARRANTY; without even the implied warranty of 13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14  * GNU Lesser General Public License for more details. 15  * 16  * You should have received a copy of the GNU Lesser General Public License 17  * along with this program. If not, see <http://www.gnu.org/licenses/>. 18  */ 19  20 package org.ethereum.util; 21  22 import org.ethereum.crypto.HashUtil; 23  24 import java.math.BigInteger; 25 import java.nio.charset.StandardCharsets; 26 import java.util.Arrays; 27 import java.util.List; 28  29 /** 30  * Class to encapsulate an object and provide utilities for conversion 31  */ 32 public class Value { 33  34  private Object value; 35  private byte[] rlp; 36  private byte[] keccak256; 37  38  public static Value fromRlpEncoded(byte[] data) { 39  if (data != null && data.length != 0) { 40  Value v = new Value(); 41  v.init(data); 42  return v; 43  } 44  return null; 45  } 46  47  public Value() { 48  } 49  50  public void init(byte[] rlp){ 51  this.rlp = rlp; 52  } 53  54  public Value(Object obj) { 55  if (obj == null) { 56  return; 57  } 58  59  if (obj instanceof Value) { 60  this.value = ((Value) obj).asObj(); 61  } else { 62  this.value = obj; 63  } 64  } 65  66  /* ***************** 67  * Convert 68  * *****************/ 69  70  public Object asObj() { 71  return value; 72  } 73  74  public List<Object> asList() { 75  Object[] valueArray = (Object[]) value; 76  return Arrays.asList(valueArray); 77  } 78  79  public int asInt() { 80  if (isInt()) { 81  return (Integer) value; 82  } else if (isBytes()) { 83  return new BigInteger(1, asBytes()).intValue(); 84  } 85  return 0; 86  } 87  88  public long asLong() { 89  if (isLong()) { 90  return (Long) value; 91  } else if (isBytes()) { 92  return new BigInteger(1, asBytes()).longValue(); 93  } 94  return 0; 95  } 96  97  public BigInteger asBigInt() { 98  return (BigInteger) value; 99  } 100  101  public String asString() { 102  if (isBytes()) { 103  return new String((byte[]) value); 104  } else if (isString()) { 105  return (String) value; 106  } 107  return ""; 108  } 109  110  public byte[] asBytes() { 111  if (isBytes()) { 112  return (byte[]) value; 113  } else if (isString()) { 114  return asString().getBytes(StandardCharsets.UTF_8); 115  } 116  return ByteUtil.EMPTY_BYTE_ARRAY; 117  } 118  119  public String getHex(){ 120  return ByteUtil.toHexString(this.encode()); 121  } 122  123  public byte[] getData(){ 124  return this.encode(); 125  } 126  127  128  public int[] asSlice() { 129  return (int[]) value; 130  } 131  132  public Value get(int index) { 133  if (isList()) { 134  // Guard for OutOfBounds 135  if (asList().size() <= index) { 136  return new Value(null); 137  } 138  if (index < 0) { 139  throw new RuntimeException("Negative index not allowed"); 140  } 141  return new Value(asList().get(index)); 142  } 143  // If this wasn't a slice you probably shouldn't be using this function 144  return new Value(null); 145  } 146  147  /* ***************** 148  * Utility 149  * *****************/ 150  151  public byte[] encode() { 152  if (rlp == null) { 153  rlp = RLP.encode(value); 154  } 155  return rlp; 156  } 157  158  public byte[] hash(){ 159  if (keccak256 == null) { 160  keccak256 = HashUtil.keccak256(encode()); 161  } 162  return keccak256; 163  } 164  165  /* ***************** 166  * Checks 167  * *****************/ 168  169  public boolean isList() { 170  return value != null && value.getClass().isArray() && !value.getClass().getComponentType().isPrimitive(); 171  } 172  173  public boolean isString() { 174  return value instanceof String; 175  } 176  177  public boolean isInt() { 178  return value instanceof Integer; 179  } 180  181  public boolean isLong() { 182  return value instanceof Long; 183  } 184  185  public boolean isBigInt() { 186  return value instanceof BigInteger; 187  } 188  189  public boolean isBytes() { 190  return value instanceof byte[]; 191  } 192  193  // it's only if the isBytes() = true 194  public boolean isReadableString() { 195  196  int readableChars = 0; 197  byte[] data = (byte[]) value; 198  199  if (data.length == 1 && data[0] > 31 && data[0] < 126) { 200  return true; 201  } 202  203  for (byte aData : data) { 204  if (aData > 32 && aData < 126) { 205  ++readableChars; 206  } 207  } 208  209  return (double) readableChars / (double) data.length > 0.55; 210  } 211  212  // it's only if the isBytes() = true 213  public boolean isHexString() { 214  215  int hexChars = 0; 216  byte[] data = (byte[]) value; 217  218  for (byte aData : data) { 219  220  if ((aData >= 48 && aData <= 57) 221  || (aData >= 97 && aData <= 102)) { 222  ++hexChars; 223  } 224  } 225  226  return (double) hexChars / (double) data.length > 0.9; 227  } 228  229  public boolean isHashCode() { 230  return this.asBytes().length == 32; 231  } 232  233  public boolean isNull() { 234  return value == null; 235  } 236  237  public boolean isEmpty() { 238  if (isNull()) { 239  return true; 240  } 241  if (isBytes() && asBytes().length == 0) { 242  return true; 243  } 244  if (isList() && asList().isEmpty()) { 245  return true; 246  } 247  if (isString() && asString().equals("")) { 248  return true; 249  } 250  251  return false; 252  } 253  254  public int length() { 255  if (isList()) { 256  return asList().size(); 257  } else if (isBytes()) { 258  return asBytes().length; 259  } else if (isString()) { 260  return asString().length(); 261  } 262  return 0; 263  } 264  265  public String toString() { 266  267  StringBuilder stringBuilder = new StringBuilder(); 268  269  if (isList()) { 270  271  Object[] list = (Object[]) value; 272  273  // special case - key/value node 274  if (list.length == 2) { 275  276  stringBuilder.append("[ "); 277  278  Value key = new Value(list[0]); 279  280  byte[] keyNibbles = CompactEncoder.binToNibblesNoTerminator(key.asBytes()); 281  String keyString = ByteUtil.nibblesToPrettyString(keyNibbles); 282  stringBuilder.append(keyString); 283  284  stringBuilder.append(","); 285  286  Value val = new Value(list[1]); 287  stringBuilder.append(val.toString()); 288  289  stringBuilder.append(" ]"); 290  return stringBuilder.toString(); 291  } 292  stringBuilder.append(" ["); 293  294  for (int i = 0; i < list.length; ++i) { 295  Value val = new Value(list[i]); 296  if (val.isString() || val.isEmpty()) { 297  stringBuilder.append("'").append(val.toString()).append("'"); 298  } else { 299  stringBuilder.append(val.toString()); 300  } 301  if (i < list.length - 1) { 302  stringBuilder.append(", "); 303  } 304  } 305  stringBuilder.append("] "); 306  307  return stringBuilder.toString(); 308  } else if (isEmpty()) { 309  return ""; 310  } else if (isBytes()) { 311  312  StringBuilder output = new StringBuilder(); 313  if (isHashCode()) { 314  output.append(ByteUtil.toHexString(asBytes())); 315  } else if (isReadableString()) { 316  output.append("'"); 317  for (byte oneByte : asBytes()) { 318  if (oneByte < 16) { 319  output.append("\\x").append(ByteUtil.oneByteToHexString(oneByte)); 320  } else { 321  output.append(Character.valueOf((char) oneByte)); 322  } 323  } 324  output.append("'"); 325  return output.toString(); 326  } 327  return ByteUtil.toHexString(this.asBytes()); 328  } else if (isString()) { 329  return asString(); 330  } 331  return "Unexpected type"; 332  } 333  334 }