diff --git a/README.md b/README.md index fa7a85e..995aa96 100644 --- a/README.md +++ b/README.md @@ -222,6 +222,55 @@ public class Main{ ``` +- Add global context to avoid duplicated @RLPEncoding and @RLPDecoding + +```java +public class Main{ + public static class LocalDateDecoder implements RLPDecoder { + @Override + public LocalDate decode(RLPElement rlpElement) { + if(rlpElement.isNull()) return null; + int[] data = rlpElement.as(int[].class); + return LocalDate.of(data[0], data[1], data[2]); + } + } + + public class LocalDateEncoder implements RLPEncoder { + @Override + public RLPElement encode(LocalDate localDate) { + return RLPElement.readRLPTree( + new int[]{localDate.getYear(), localDate.getMonthValue(), localDate.getDayOfMonth()} + ); + } + } + + @Data + @AllArgsConstructor + @NoArgsConstructor + public static class User{ + private LocalDate birthDay; + } + + public static void main(String[] args){ + RLPContext context = RLPContext + .newInstance() + .withDecoder(LocalDate.class, new LocalDateDecoder()) + .withEncoder(LocalDate.class, new LocalDateEncoder()); + RLPMapper mapper = new RLPMapper().withContext(context); + User u = new User(); + element = mapper.readRLPTree(u); + User decoded = mapper.decode(element, User.class); + assert decoded.birthDay == null; + + u.birthDay = LocalDate.now(); + byte[] encoded = mapper.encode(u); + decoded = mapper.decode(encoded, User.class); + System.out.println(decoded.birthDay.format(DateTimeFormatter.ISO_DATE)); + } + +} +``` + ## Benchmark - see RLPTest.performanceDecode for benchmark diff --git a/build.gradle b/build.gradle index 3b32d19..bc4b3b8 100644 --- a/build.gradle +++ b/build.gradle @@ -4,7 +4,7 @@ plugins { } group 'org.tdf' -version '1.1.17' +version '1.1.18' sourceCompatibility = 1.8 @@ -22,7 +22,10 @@ ext{ dependencies { testCompile group: 'junit', name: 'junit', version: '4.12' compileOnly "org.projectlombok:lombok:${lombokVersion}" + testCompileOnly "org.projectlombok:lombok:${lombokVersion}" annotationProcessor "org.projectlombok:lombok:${lombokVersion}" + testAnnotationProcessor "org.projectlombok:lombok:${lombokVersion}" + testCompile "commons-codec:commons-codec:${commonsCodecVersion}" testCompile "com.madgag.spongycastle:core:${scastleVersion}" // for rlp encoding testCompile "com.madgag.spongycastle:prov:${scastleVersion}" // for rlp encoding diff --git a/src/main/java/org/tdf/rlp/RLPDecoder.java b/src/main/java/org/tdf/rlp/RLPDecoder.java index 3365bd5..707ea7b 100644 --- a/src/main/java/org/tdf/rlp/RLPDecoder.java +++ b/src/main/java/org/tdf/rlp/RLPDecoder.java @@ -1,7 +1,14 @@ package org.tdf.rlp; +import lombok.NonNull; + public interface RLPDecoder { - T decode(RLPElement element); + /** + * + * @param element the element may equals to RLPItem.NULL + * @return + */ + T decode(@NonNull RLPElement element); class None implements RLPDecoder { @Override diff --git a/src/main/java/org/tdf/rlp/RLPEncoder.java b/src/main/java/org/tdf/rlp/RLPEncoder.java index 0ce59c9..db9dfc8 100644 --- a/src/main/java/org/tdf/rlp/RLPEncoder.java +++ b/src/main/java/org/tdf/rlp/RLPEncoder.java @@ -1,7 +1,14 @@ package org.tdf.rlp; +import lombok.NonNull; + public interface RLPEncoder { - RLPElement encode(T o); + /** + * + * @param o non-null object + * @return encoded result + */ + RLPElement encode(@NonNull T o); class None implements RLPEncoder { @Override diff --git a/src/test/java/org/tdf/rlp/LocalDateDecoder.java b/src/test/java/org/tdf/rlp/LocalDateDecoder.java new file mode 100644 index 0000000..1e113f6 --- /dev/null +++ b/src/test/java/org/tdf/rlp/LocalDateDecoder.java @@ -0,0 +1,14 @@ +package org.tdf.rlp; + +import lombok.NonNull; + +import java.time.LocalDate; + +public class LocalDateDecoder implements RLPDecoder { + @Override + public LocalDate decode(@NonNull RLPElement rlpElement) { + if(rlpElement.isNull()) return null; + int[] data = rlpElement.as(int[].class); + return LocalDate.of(data[0], data[1], data[2]); + } +} diff --git a/src/test/java/org/tdf/rlp/LocalDateEncoder.java b/src/test/java/org/tdf/rlp/LocalDateEncoder.java new file mode 100644 index 0000000..83c7fa5 --- /dev/null +++ b/src/test/java/org/tdf/rlp/LocalDateEncoder.java @@ -0,0 +1,15 @@ +package org.tdf.rlp; + +import lombok.NonNull; + +import java.time.LocalDate; +import java.util.Arrays; + +public class LocalDateEncoder implements RLPEncoder { + @Override + public RLPElement encode(@NonNull LocalDate localDate) { + return RLPElement.readRLPTree( + Arrays.asList(localDate.getYear(), localDate.getMonthValue(), localDate.getDayOfMonth()) + ); + } +} \ No newline at end of file diff --git a/src/test/java/org/tdf/rlp/RLPTest.java b/src/test/java/org/tdf/rlp/RLPTest.java index 78601c5..fe11d75 100644 --- a/src/test/java/org/tdf/rlp/RLPTest.java +++ b/src/test/java/org/tdf/rlp/RLPTest.java @@ -1,5 +1,8 @@ package org.tdf.rlp; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; import org.apache.commons.codec.binary.Hex; import org.junit.Ignore; import org.junit.Test; @@ -13,6 +16,8 @@ import java.nio.charset.StandardCharsets; import java.nio.file.Paths; import java.security.SecureRandom; +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; import java.util.*; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -1685,4 +1690,36 @@ public void testDecodeContainer() throws Exception{ assert dummmy4.dum != null; assert dummmy4.dum.size() == 0; } + + @Test + public void testContext(){ + RLPContext context = RLPContext + .newInstance() + .withDecoder(LocalDate.class, new LocalDateDecoder()) + .withEncoder(LocalDate.class, new LocalDateEncoder()); + RLPMapper mapper = new RLPMapper().withContext(context); + LocalDate now = LocalDate.now(); + RLPElement element = mapper.readRLPTree(now); + for(long l : element.as(long[].class)){ + System.out.println(l); + } + assert now.equals(mapper.decode(element, LocalDate.class)); + + User u = new User(); + element = mapper.readRLPTree(u); + User decoded = mapper.decode(element, User.class); + assert decoded.birthDay == null; + + u.birthDay = LocalDate.now(); + byte[] encoded = mapper.encode(u); + decoded = mapper.decode(encoded, User.class); + System.out.println(decoded.birthDay.format(DateTimeFormatter.ISO_DATE)); + } + + @Data + @AllArgsConstructor + @NoArgsConstructor + public static class User{ + private LocalDate birthDay; + } }