Skip to content

Commit

Permalink
Merge pull request #44 from Alexey-N-Chernyshov/scale-uint64-support
Browse files Browse the repository at this point in the history
Add UInt64Reader and UInt64Writer for SCALE codec
  • Loading branch information
splix authored Jan 26, 2021
2 parents 24a1b47 + ecc2aca commit b2d8775
Show file tree
Hide file tree
Showing 4 changed files with 117 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package io.emeraldpay.polkaj.scale.reader;

import io.emeraldpay.polkaj.scale.ScaleCodecReader;
import io.emeraldpay.polkaj.scale.ScaleReader;
import java.math.BigInteger;

public class UInt64Reader implements ScaleReader<BigInteger> {

@Override
public BigInteger read(ScaleCodecReader rdr) {
BigInteger result = BigInteger.ZERO;
result = result.add(BigInteger.valueOf(rdr.readUByte()));
result = result.add(BigInteger.valueOf(rdr.readUByte()).shiftLeft(8));
result = result.add(BigInteger.valueOf(rdr.readUByte()).shiftLeft(16));
result = result.add(BigInteger.valueOf(rdr.readUByte()).shiftLeft(24));
result = result.add(BigInteger.valueOf(rdr.readUByte()).shiftLeft(32));
result = result.add(BigInteger.valueOf(rdr.readUByte()).shiftLeft(40));
result = result.add(BigInteger.valueOf(rdr.readUByte()).shiftLeft(48));
result = result.add(BigInteger.valueOf(rdr.readUByte()).shiftLeft(56));
return result;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package io.emeraldpay.polkaj.scale.writer;

import io.emeraldpay.polkaj.scale.ScaleCodecWriter;
import io.emeraldpay.polkaj.scale.ScaleWriter;
import java.io.IOException;
import java.math.BigInteger;

public class UInt64Writer implements ScaleWriter<BigInteger> {

public static final BigInteger MAX_UINT64 = new BigInteger("18446744073709551615");

@Override
public void write(ScaleCodecWriter wrt, BigInteger value) throws IOException {
if (value.compareTo(BigInteger.ZERO) < 0) {
throw new IllegalArgumentException("Negative values are not supported: " + value);
}
if (value.compareTo(MAX_UINT64) > 0) {
throw new IllegalArgumentException("Value is to big for 64 bits. " + value);
}
wrt.directWrite(value.and(BigInteger.valueOf(255)).intValue());
wrt.directWrite(value.shiftRight(8).and(BigInteger.valueOf(255)).intValue());
wrt.directWrite(value.shiftRight(16).and(BigInteger.valueOf(255)).intValue());
wrt.directWrite(value.shiftRight(24).and(BigInteger.valueOf(255)).intValue());
wrt.directWrite(value.shiftRight(32).and(BigInteger.valueOf(255)).intValue());
wrt.directWrite(value.shiftRight(40).and(BigInteger.valueOf(255)).intValue());
wrt.directWrite(value.shiftRight(48).and(BigInteger.valueOf(255)).intValue());
wrt.directWrite(value.shiftRight(56).and(BigInteger.valueOf(255)).intValue());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package io.emeraldpay.polkaj.scale.reader

import io.emeraldpay.polkaj.scale.ScaleCodecReader
import org.apache.commons.codec.binary.Hex
import spock.lang.Specification

class UInt64ReaderSpec extends Specification {

UInt64Reader reader = new UInt64Reader()

def "Reads"() {
when:
def codec = new ScaleCodecReader(Hex.decodeHex("f70af5f6f3c843050000000000000000"))
then:
codec.read(reader).toString() == "379367743775116023"
}

def "Reads with zero prefix"() {
when:
def codec = new ScaleCodecReader(Hex.decodeHex("0000c52ebca2b1000000000000000000"))
then:
codec.read(reader).toString() == "50000000000000000"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package io.emeraldpay.polkaj.scale.writer

import io.emeraldpay.polkaj.scale.ScaleCodecWriter
import org.apache.commons.codec.binary.Hex
import spock.lang.Specification

class UInt64WriterSpec extends Specification {

UInt64Writer writer = new UInt64Writer()
ByteArrayOutputStream buf = new ByteArrayOutputStream()
ScaleCodecWriter codec = new ScaleCodecWriter(buf)

def "Writes"() {
when:
codec.write(writer, new BigInteger("379367743775116023"))
def act = buf.toByteArray()
then:
Hex.encodeHexString(act) == "f70af5f6f3c84305"
}

def "Writes with zero prefix"() {
when:
codec.write(writer, new BigInteger("50000000000000000"))
def act = buf.toByteArray()
then:
Hex.encodeHexString(act) == "0000c52ebca2b100"
}

def "Error for negative number"() {
when:
codec.write(writer, BigInteger.valueOf(-1))
then:
thrown(IllegalArgumentException)
}

def "Error for large number"() {
when:
codec.write(writer, UInt64Writer.MAX_UINT64 + 1)
then:
thrown(IllegalArgumentException)
}
}

0 comments on commit b2d8775

Please sign in to comment.