Skip to content
This repository has been archived by the owner on Feb 6, 2019. It is now read-only.

Commit

Permalink
Abstract layer for Memo
Browse files Browse the repository at this point in the history
  • Loading branch information
bartekn committed Dec 3, 2015
1 parent 51f7bf8 commit fc98733
Show file tree
Hide file tree
Showing 10 changed files with 258 additions and 94 deletions.
95 changes: 25 additions & 70 deletions src/main/java/org/stellar/base/Memo.java
Original file line number Diff line number Diff line change
@@ -1,18 +1,11 @@
package org.stellar.base;

import com.google.common.base.Strings;
import org.apache.commons.codec.DecoderException;
import org.apache.commons.codec.binary.Hex;
import org.stellar.base.xdr.MemoType;
import org.stellar.base.xdr.Uint64;

import java.nio.charset.StandardCharsets;

import static com.google.common.base.Preconditions.checkNotNull;

/**
* <p>The memo contains optional extra information. It is the responsibility of the client to interpret this value. Memos can be one of the following types:</p>
* <ul>
* <li><code>MEMO_NONE</code>: Empty memo.</li>
* <li><code>MEMO_TEXT</code>: A string up to 28-bytes long.</li>
* <li><code>MEMO_ID</code>: A 64 bit unsigned integer.</li>
* <li><code>MEMO_HASH</code>: A 32 byte hash.</li>
Expand All @@ -21,101 +14,63 @@
* <p>Use static methods to generate any of above types.</p>
* @see Transaction
*/
public class Memo {
Memo() {
}

public abstract class Memo {
/**
* Creates MEMO_NONE type memo.
* Creates new MemoNone instance.
*/
public static org.stellar.base.xdr.Memo none() {
org.stellar.base.xdr.Memo memo = new org.stellar.base.xdr.Memo();
memo.setDiscriminant(MemoType.MEMO_NONE);
return memo;
public static MemoNone none() {
return new MemoNone();
}

/**
* Creates MEMO_TEXT type memo.
* Creates new {@link MemoText} instance.
* @param text
*/
public static org.stellar.base.xdr.Memo text(String text) {
checkNotNull(text, "text cannot be null");

int length = text.getBytes((StandardCharsets.UTF_8)).length;
if (length > 28) {
throw new MemoTooLongException("text must be <= 28 bytes. length=" + String.valueOf(length));
}

org.stellar.base.xdr.Memo memo = new org.stellar.base.xdr.Memo();
memo.setDiscriminant(MemoType.MEMO_TEXT);
memo.setText(text);
return memo;
public static MemoText text(String text) {
return new MemoText(text);
}

/**
* Creates MEMO_ID type memo.
* Creates new {@link MemoId} instance.
* @param id
*/
public static org.stellar.base.xdr.Memo id(long id) {
org.stellar.base.xdr.Memo memo = new org.stellar.base.xdr.Memo();
memo.setDiscriminant(MemoType.MEMO_ID);
Uint64 idXdr = new Uint64();
idXdr.setUint64(id);
memo.setId(idXdr);
return memo;
public static MemoId id(long id) {
return new MemoId(id);
}

/**
* Creates MEMO_HASH type memo from byte array.
* Creates new {@link MemoHash} instance from byte array.
* @param bytes
*/
public static org.stellar.base.xdr.Memo hash(byte[] bytes) {
org.stellar.base.xdr.Memo memo = new org.stellar.base.xdr.Memo();
memo.setDiscriminant(MemoType.MEMO_HASH);

if (bytes.length < 32) {
bytes = Util.paddedByteArray(bytes, 32);
} else if (bytes.length > 32) {
throw new MemoTooLongException("Memo.hash can contain 32 bytes at max.");
}

org.stellar.base.xdr.Hash hash = new org.stellar.base.xdr.Hash();
hash.setHash(bytes);

memo.setHash(hash);
return memo;
public static MemoHash hash(byte[] bytes) {
return new MemoHash(bytes);
}

/**
* Creates MEMO_HASH type memo from hex-encoded string
* Creates new {@link MemoHash} instance from hex-encoded string
* @param hexString
* @throws DecoderException
*/
public static org.stellar.base.xdr.Memo hash(String hexString) throws DecoderException {
checkNotNull(hexString, "hexString cannot be null");
byte[] decoded = Hex.decodeHex(hexString.toCharArray());
return Memo.hash(decoded);
public static MemoHash hash(String hexString) throws DecoderException {
return new MemoHash(hexString);
}

/**
* Creates MEMO_RETURN type memo from byte array.
* Creates new {@link MemoReturnHash} instance from byte array.
* @param bytes
*/
public static org.stellar.base.xdr.Memo returnHash(byte[] bytes) {
org.stellar.base.xdr.Memo memo = Memo.hash(bytes);
memo.setDiscriminant(MemoType.MEMO_RETURN);
return memo;
public static MemoReturnHash returnHash(byte[] bytes) {
return new MemoReturnHash(bytes);
}

/**
* Creates MEMO_RETURN type memo from hex-encoded string.
* Creates new {@link MemoReturnHash} instance from hex-encoded string.
* @param hexString
* @throws DecoderException
*/
public static org.stellar.base.xdr.Memo returnHash(String hexString) throws DecoderException {
checkNotNull(hexString, "hexString cannot be null");
org.stellar.base.xdr.Memo memo = Memo.hash(hexString);
memo.setDiscriminant(MemoType.MEMO_RETURN);
return memo;
public static MemoReturnHash returnHash(String hexString) throws DecoderException {
return new MemoReturnHash(hexString);
}

abstract org.stellar.base.xdr.Memo toXdr();
}
29 changes: 29 additions & 0 deletions src/main/java/org/stellar/base/MemoHash.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package org.stellar.base;

import org.apache.commons.codec.DecoderException;
import org.stellar.base.xdr.MemoType;

/**
* Represents MEMO_HASH.
*/
public class MemoHash extends MemoHashAbstract {
public MemoHash(byte[] bytes) {
super(bytes);
}

public MemoHash(String hexString) throws DecoderException {
super(hexString);
}

@Override
org.stellar.base.xdr.Memo toXdr() {
org.stellar.base.xdr.Memo memo = new org.stellar.base.xdr.Memo();
memo.setDiscriminant(MemoType.MEMO_HASH);

org.stellar.base.xdr.Hash hash = new org.stellar.base.xdr.Hash();
hash.setHash(bytes);

memo.setHash(hash);
return memo;
}
}
60 changes: 60 additions & 0 deletions src/main/java/org/stellar/base/MemoHashAbstract.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package org.stellar.base;

import org.apache.commons.codec.DecoderException;
import org.apache.commons.codec.binary.Hex;

abstract class MemoHashAbstract extends Memo {
protected byte[] bytes;

public MemoHashAbstract(byte[] bytes) {
if (bytes.length < 32) {
bytes = Util.paddedByteArray(bytes, 32);
} else if (bytes.length > 32) {
throw new MemoTooLongException("MEMO_HASH can contain 32 bytes at max.");
}

this.bytes = bytes;
}

public MemoHashAbstract(String hexString) throws DecoderException {
this(Hex.decodeHex(hexString.toCharArray()));
}

/**
* Returns 32 bytes long array contained in this memo.
*/
public byte[] getBytes() {
return bytes;
}

/**
* <p>Returns hex representation of bytes contained in this memo.</p>
*
* <p>Example:</p>
* <code><pre>
* MemoHash memo = new MemoHash("4142434445");
* memo.getHexValue(); // 4142434445000000000000000000000000000000000000000000000000000000
* memo.getTrimmedHexValue(); // 4142434445
* </pre></code>
*/
public String getHexValue() {
return new String(Hex.encodeHex(this.bytes));
}

/**
* <p>Returns hex representation of bytes contained in this memo until null byte (0x00) is found.</p>
*
* <p>Example:</p>
* <code><pre>
* MemoHash memo = new MemoHash("4142434445");
* memo.getHexValue(); // 4142434445000000000000000000000000000000000000000000000000000000
* memo.getTrimmedHexValue(); // 4142434445
* </pre></code>
*/
public String getTrimmedHexValue() {
return this.getHexValue().split("00")[0];
}

@Override
abstract org.stellar.base.xdr.Memo toXdr();
}
32 changes: 32 additions & 0 deletions src/main/java/org/stellar/base/MemoId.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package org.stellar.base;

import org.stellar.base.xdr.MemoType;
import org.stellar.base.xdr.Uint64;

/**
* Represents MEMO_ID.
*/
public class MemoId extends Memo {
private long id;

public MemoId(long id) {
if (id < 0) {
throw new IllegalArgumentException("id must be a positive number");
}
this.id = id;
}

public long getId() {
return id;
}

@Override
org.stellar.base.xdr.Memo toXdr() {
org.stellar.base.xdr.Memo memo = new org.stellar.base.xdr.Memo();
memo.setDiscriminant(MemoType.MEMO_ID);
Uint64 idXdr = new Uint64();
idXdr.setUint64(id);
memo.setId(idXdr);
return memo;
}
}
15 changes: 15 additions & 0 deletions src/main/java/org/stellar/base/MemoNone.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package org.stellar.base;

import org.stellar.base.xdr.MemoType;

/**
* Represents MEMO_NONE.
*/
public class MemoNone extends Memo {
@Override
org.stellar.base.xdr.Memo toXdr() {
org.stellar.base.xdr.Memo memo = new org.stellar.base.xdr.Memo();
memo.setDiscriminant(MemoType.MEMO_NONE);
return memo;
}
}
30 changes: 30 additions & 0 deletions src/main/java/org/stellar/base/MemoReturnHash.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package org.stellar.base;

import org.apache.commons.codec.DecoderException;
import org.stellar.base.xdr.Memo;
import org.stellar.base.xdr.MemoType;

/**
* Represents MEMO_RETURN.
*/
public class MemoReturnHash extends MemoHashAbstract {
public MemoReturnHash(byte[] bytes) {
super(bytes);
}

public MemoReturnHash(String hexString) throws DecoderException {
super(hexString);
}

@Override
Memo toXdr() {
org.stellar.base.xdr.Memo memo = new org.stellar.base.xdr.Memo();
memo.setDiscriminant(MemoType.MEMO_RETURN);

org.stellar.base.xdr.Hash hash = new org.stellar.base.xdr.Hash();
hash.setHash(bytes);

memo.setHash(hash);
return memo;
}
}
35 changes: 35 additions & 0 deletions src/main/java/org/stellar/base/MemoText.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package org.stellar.base;

import org.stellar.base.xdr.MemoType;

import java.nio.charset.StandardCharsets;

import static com.google.common.base.Preconditions.checkNotNull;

/**
* Represents MEMO_TEXT.
*/
public class MemoText extends Memo {
private String text;

public MemoText(String text) {
this.text = checkNotNull(text, "text cannot be null");

int length = text.getBytes((StandardCharsets.UTF_8)).length;
if (length > 28) {
throw new MemoTooLongException("text must be <= 28 bytes. length=" + String.valueOf(length));
}
}

public String getText() {
return text;
}

@Override
org.stellar.base.xdr.Memo toXdr() {
org.stellar.base.xdr.Memo memo = new org.stellar.base.xdr.Memo();
memo.setDiscriminant(MemoType.MEMO_TEXT);
memo.setText(text);
return memo;
}
}
3 changes: 3 additions & 0 deletions src/main/java/org/stellar/base/Operation.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@

import static com.google.common.base.Preconditions.checkNotNull;

/**
* Abstract class for operations.
*/
public abstract class Operation {
Operation() {}

Expand Down
Loading

0 comments on commit fc98733

Please sign in to comment.