All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.godmonth.eth.rlp.RlpDecoder Maven / Gradle / Ivy

There is a newer version: 0.1.6
Show newest version
package com.godmonth.eth.rlp;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.lang3.ArrayUtils;

public class RlpDecoder {
	private RlpDecoder() {
	}

	public static RLPElement decode(byte[] input) {
		return decode(ByteBuffer.wrap(input));
	}

	public static RLPElement decode(ByteBuffer byteBuffer) {
		byte b = byteBuffer.get();
		int unsignedInt = Byte.toUnsignedInt(b);
		if (unsignedInt >= 0 && unsignedInt < 128) {
			return new RLPItem(new byte[] { b });
		} else if (unsignedInt >= 128 && unsignedInt < 184) {
			int arrayLength = unsignedInt - 128;
			if (arrayLength > byteBuffer.remaining()) {
				throw new IllegalArgumentException("arrayLength:" + arrayLength + "," + byteBuffer.toString());
			}
			byte[] subarray = new byte[arrayLength];
			byteBuffer.get(subarray);
			return new RLPItem(subarray);
		} else if (unsignedInt >= 184 && unsignedInt < 192) {
			int arrayLength = getExtendArrayLength(unsignedInt - 183, byteBuffer);
			byte[] subarray = new byte[arrayLength];
			byteBuffer.get(subarray);
			return new RLPItem(subarray);
		} else if (unsignedInt >= 192 && unsignedInt < 247) {
			int listLength = unsignedInt - 192;
			int innerLimit = byteBuffer.position() + listLength;
			List list = new ArrayList();
			while (byteBuffer.position() < innerLimit) {
				list.add(decode(byteBuffer));
			}
			return new RLPList(list);
		} else if (unsignedInt >= 247 && unsignedInt < 256) {
			int listLength = getExtendArrayLength(unsignedInt - 247, byteBuffer);
			int innerLimit = byteBuffer.position() + listLength;

			List list = new ArrayList();
			while (byteBuffer.position() < innerLimit) {
				list.add(decode(byteBuffer));
			}
			return new RLPList(list);
		} else {
			throw new IllegalArgumentException();
		}
	}

	private static int getExtendArrayLength(int arrayLengthLength, ByteBuffer byteBuffer) {
		byte[] arrayLengthArray = new byte[arrayLengthLength];
		byteBuffer.get(arrayLengthArray);
		return asIntBigEndian(arrayLengthArray);
	}

	public static int asIntBigEndian(byte[] raw) {
		if (raw.length > 4) {
			throw new IllegalArgumentException("int only");
		}
		byte[] i = raw;
		if (raw.length < 4) {
			i = ArrayUtils.addAll(new byte[4 - raw.length], raw);
		}
		ByteBuffer buffer = ByteBuffer.wrap(i, 0, 4);
		buffer.order(ByteOrder.BIG_ENDIAN);
		return buffer.getInt();
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy