summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/main/java/org/uic/barcode/asn1/datatypes/Alphabet.java1
-rw-r--r--src/main/java/org/uic/barcode/asn1/datatypes/AlphabetBuilder.java32
-rw-r--r--src/main/java/org/uic/barcode/asn1/datatypes/Bitstring.java2
-rw-r--r--src/main/java/org/uic/barcode/asn1/datatypes/Optional.java96
-rw-r--r--src/main/java/org/uic/barcode/asn1/uper/BitStringCoder.java50
-rw-r--r--src/test/java/org/uic/barcode/asn1/test/GenAlphabet.java11
-rw-r--r--src/test/java/org/uic/barcode/asn1/test/UperEncodeBitStringTest.java27
-rw-r--r--src/test/java/org/uic/barcode/asn1/test/UperEncodeStringCustomAlphabetTest.java82
-rw-r--r--src/test/java/org/uic/barcode/asn1/test/UperEncodeVarBitStringTest.java81
9 files changed, 218 insertions, 164 deletions
diff --git a/src/main/java/org/uic/barcode/asn1/datatypes/Alphabet.java b/src/main/java/org/uic/barcode/asn1/datatypes/Alphabet.java
index 2b153ae..0202e16 100644
--- a/src/main/java/org/uic/barcode/asn1/datatypes/Alphabet.java
+++ b/src/main/java/org/uic/barcode/asn1/datatypes/Alphabet.java
@@ -3,7 +3,6 @@ package org.uic.barcode.asn1.datatypes;
/**
* Alphabet class for Restricted Strings.
*
- * Use {@link AlphabetBuilder} for convenient construction of restriction alphabets.
*/
public abstract class Alphabet {
diff --git a/src/main/java/org/uic/barcode/asn1/datatypes/AlphabetBuilder.java b/src/main/java/org/uic/barcode/asn1/datatypes/AlphabetBuilder.java
deleted file mode 100644
index b768897..0000000
--- a/src/main/java/org/uic/barcode/asn1/datatypes/AlphabetBuilder.java
+++ /dev/null
@@ -1,32 +0,0 @@
-package org.uic.barcode.asn1.datatypes;
-
-
-public class AlphabetBuilder {
-
- private final StringBuilder sb = new StringBuilder();
-
- public AlphabetBuilder() {}
-
- public String chars() {
- return sb.toString();
- }
-
- public AlphabetBuilder withRange(char from, char to) {
- for (char c = from; c <= to; c++) {
- sb.append(c);
- }
- return this;
- }
-
- public AlphabetBuilder withChars(String str) {
- sb.append(str);
- return this;
- }
-
- public AlphabetBuilder withChars(Character... chars) {
- for (char c : chars) {
- sb.append(c);
- }
- return this;
- }
-}
diff --git a/src/main/java/org/uic/barcode/asn1/datatypes/Bitstring.java b/src/main/java/org/uic/barcode/asn1/datatypes/Bitstring.java
index 1543f64..4771931 100644
--- a/src/main/java/org/uic/barcode/asn1/datatypes/Bitstring.java
+++ b/src/main/java/org/uic/barcode/asn1/datatypes/Bitstring.java
@@ -9,7 +9,7 @@ import java.lang.annotation.Target;
* In UPER, a SEQUENCE OF Booleans would look exactly as bitstring, so this annotation can be
* omitted for {@code List<Boolean>}.
*/
-@Target({ElementType.TYPE})
+@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Bitstring {
diff --git a/src/main/java/org/uic/barcode/asn1/datatypes/Optional.java b/src/main/java/org/uic/barcode/asn1/datatypes/Optional.java
deleted file mode 100644
index 757ba29..0000000
--- a/src/main/java/org/uic/barcode/asn1/datatypes/Optional.java
+++ /dev/null
@@ -1,96 +0,0 @@
-package org.uic.barcode.asn1.datatypes;
-
-import java.util.NoSuchElementException;
-import java.util.Objects;
-
-/** Represents optional values.
- *
- * Should be replaced by java.util.Optional from Java 8, when project moves to Java 8.
- *
- * @param <T> type of contained elements */
-public class Optional<T> {
-
- private final T element;
- private final boolean isPresent;
-
- private Optional(T element, boolean isPresent) {
- this.element = element;
- this.isPresent = isPresent;
- }
-
- /** @return true if the Option contains a value */
- public boolean isPresent() {
- return isPresent;
- }
-
- /** @return the element if the option is not empty
- * @throws java.util.NoSuchElementException if the option is empty */
- public T get() {
- if (isPresent) {
- return element;
- } else {
- throw new NoSuchElementException("None.get");
- }
- }
-
- /** @return the value, if present, otherwise return {@code other}
- * @param other the value to be returned if there is no value present */
- public T orElse(T other) {
- return isPresent() ? get() : other;
- }
-
- /**
- * Indicates whether some other object is "equal to" this Optional. The
- * other object is considered equal if:
- * <ul>
- * <li>it is also an {@code Optional} and;
- * <li>both instances have no value present or;
- * <li>the present values are "equal to" each other via {@code equals()}.
- * </ul>
- *
- * @param obj an object to be tested for equality
- * @return {code true} if the other object is "equal to" this object
- * otherwise {@code false}
- */
- @Override
- public boolean equals(Object obj) {
- if (this == obj) {
- return true;
- }
-
- if (!(obj instanceof Optional)) {
- return false;
- }
-
- Optional<?> other = (Optional<?>) obj;
- return Objects.equals(element, other.element);
- }
-
- /**
- * Returns the hash code value of the present value, if any, or 0 (zero) if
- * no value is present.
- *
- * @return hash code value of the present value or 0 if no value is present
- */
- @Override
- public int hashCode() {
- return Objects.hashCode(element);
- }
-
- /** Returns an Option containing the value.
- *
- * @param <A> the type of the value
- * @param element contained value
- * @return a new Option that contains the value */
- public static <A> Optional<A> of(final A element) {
- return new Optional<A>(element, true);
- }
-
- /** Returns an empty option.
- *
- * @param <A>
- * @return an empty Option */
- public static <A> Optional<A> empty() {
- return new Optional<A>(null, false);
- }
-}
diff --git a/src/main/java/org/uic/barcode/asn1/uper/BitStringCoder.java b/src/main/java/org/uic/barcode/asn1/uper/BitStringCoder.java
index ba1692c..19aac9b 100644
--- a/src/main/java/org/uic/barcode/asn1/uper/BitStringCoder.java
+++ b/src/main/java/org/uic/barcode/asn1/uper/BitStringCoder.java
@@ -4,12 +4,12 @@ import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
+import java.util.List;
import org.uic.barcode.asn1.datatypes.Asn1VarSizeBitstring;
import org.uic.barcode.asn1.datatypes.Bitstring;
import org.uic.barcode.asn1.datatypes.FixedSize;
import org.uic.barcode.asn1.datatypes.SizeRange;
-import org.uic.barcode.asn1.uper.UperEncoder.Asn1ContainerFieldSorter;
class BitStringCoder implements Decoder, Encoder {
@@ -29,18 +29,24 @@ class BitStringCoder implements Decoder, Encoder {
throw new UnsupportedOperationException(
"Bitstring with extensions is not implemented yet");
}
- FixedSize size = type.getAnnotation(FixedSize.class);
+ FixedSize size = annotations.getAnnotation(FixedSize.class);
int position = bitbuffer.position();
if (size != null) {
- Asn1ContainerFieldSorter sorter = new Asn1ContainerFieldSorter(type);
- if (sorter.ordinaryFields.size() != size.value()) { throw new AssertionError(
+ if (!List.class.isAssignableFrom(type)) {
+ throw new AssertionError("Field should be a list of booleans!");
+ }
+
+ List<Boolean> list = (List<Boolean>)obj;
+ if (list.size() != size.value()) {
+ throw new AssertionError(
"Declared size (" + size.value() +
- ") and number of fields (" + sorter.ordinaryFields.size() +
- ") do not match!"); }
- for (Field f : sorter.ordinaryFields) {
+ ") and number of fields (" + list.size() +
+ ") do not match!");
+ }
+ for (Boolean f : list) {
try {
- bitbuffer.put(f.getBoolean(obj));
- } catch (IllegalArgumentException | IllegalAccessException e) {
+ bitbuffer.put(f);
+ } catch (IllegalArgumentException e) {
throw new IllegalArgumentException("can't encode" + obj, e);
}
}
@@ -100,26 +106,28 @@ class BitStringCoder implements Decoder, Encoder {
if (fixedSize == null) { throw new UnsupportedOperationException(
"bitstrings of non-fixed size that do not extend Asn1VarSizeBitstring are not supported yet");
}
- Asn1ContainerFieldSorter sorter = new Asn1ContainerFieldSorter(classOfT);
- if (fixedSize.value() != sorter.ordinaryFields.size()) { throw new IllegalArgumentException(
- "Fixed size annotation " + fixedSize.value()
- + " does not match the number of fields "
- + sorter.ordinaryFields.size() + " in " + classOfT.getName()); }
if (UperEncoder.hasExtensionMarker(annotations)) {
boolean extensionPresent = bitbuffer.get();
if (extensionPresent) { throw new UnsupportedOperationException(
"extensions in fixed-size bitlist are not supported yet"); }
}
T result = UperEncoder.instantiate(classOfT);
- for (Field f : sorter.ordinaryFields) {
- boolean value = bitbuffer.get();
- UperEncoder.logger.debug(String.format("Field %s set to %s", f.getName(), value));
+
+ Method addBooleanMethod;
+ try {
+ addBooleanMethod = classOfT.getDeclaredMethod("add", Object.class);
+ addBooleanMethod.setAccessible(true);
+ } catch (SecurityException | NoSuchMethodException e) {
+ throw new AssertionError("Can't find/access add " + e);
+ }
+
+ for (int i = 0; i < fixedSize.value(); i++) {
try {
- f.set(result, value);
- } catch (IllegalArgumentException | IllegalAccessException e) {
- throw new IllegalArgumentException("can't decode " + classOfT, e);
+ addBooleanMethod.invoke(result, bitbuffer.get());
+ } catch (IllegalArgumentException | InvocationTargetException | IllegalAccessException e) {
+ throw new IllegalArgumentException("Can't invoke add", e);
}
- }
+ }
return result;
} else {
UperEncoder.logger.debug("Bitlist(var-size)");
diff --git a/src/test/java/org/uic/barcode/asn1/test/GenAlphabet.java b/src/test/java/org/uic/barcode/asn1/test/GenAlphabet.java
new file mode 100644
index 0000000..a08392e
--- /dev/null
+++ b/src/test/java/org/uic/barcode/asn1/test/GenAlphabet.java
@@ -0,0 +1,11 @@
+package org.uic.barcode.asn1.test;
+
+import org.uic.barcode.asn1.datatypes.Alphabet;
+
+public class GenAlphabet extends Alphabet {
+
+ public GenAlphabet() {
+ super("ACGT");
+ }
+
+}
diff --git a/src/test/java/org/uic/barcode/asn1/test/UperEncodeBitStringTest.java b/src/test/java/org/uic/barcode/asn1/test/UperEncodeBitStringTest.java
index 574a9cf..94f29c2 100644
--- a/src/test/java/org/uic/barcode/asn1/test/UperEncodeBitStringTest.java
+++ b/src/test/java/org/uic/barcode/asn1/test/UperEncodeBitStringTest.java
@@ -3,13 +3,13 @@ package org.uic.barcode.asn1.test;
import static org.junit.Assert.assertEquals;
import java.util.ArrayList;
-import java.util.List;
import java.util.logging.Level;
import org.junit.Test;
import org.uic.barcode.asn1.datatypes.Asn1Optional;
-import org.uic.barcode.asn1.datatypes.Asn1VarSizeBitstring;
+import org.uic.barcode.asn1.datatypes.Bitstring;
import org.uic.barcode.asn1.datatypes.FieldOrder;
+import org.uic.barcode.asn1.datatypes.FixedSize;
import org.uic.barcode.asn1.datatypes.Sequence;
import org.uic.barcode.asn1.uper.UperEncoder;
@@ -22,7 +22,7 @@ public class UperEncodeBitStringTest {
World-Schema DEFINITIONS AUTOMATIC TAGS ::=
BEGIN
TestRecord ::= [APPLICATION 0] IMPLICIT SEQUENCE {
- value BIT STRING OPTIONAL,
+ value BIT STRING (SIZE(3)) OPTIONAL
}
END
@@ -39,19 +39,20 @@ public class UperEncodeBitStringTest {
public static class TestRecord {
@FieldOrder(order = 0)
- @Asn1Optional() Asn1VarSizeBitstring value;
+ @Asn1Optional()
+ @Bitstring()
+ @FixedSize(3)
+ ArrayList<Boolean> booleans = null;
public TestRecord() {
this(false,false,true);
}
public TestRecord(Boolean value1,Boolean value2,Boolean value3 ) {
- List<Boolean> booleans = new ArrayList<Boolean>();
+ booleans = new ArrayList<Boolean>();
booleans.add(value1);
booleans.add(value2);
- booleans.add(value3);
- this.value = new Asn1VarSizeBitstring(booleans);
-
+ booleans.add(value3);
}
}
@@ -61,7 +62,7 @@ public class UperEncodeBitStringTest {
byte[] encoded = UperEncoder.encode(record);
String hex = UperEncoder.hexStringFromBytes(encoded);
UperEncoder.logger.log(Level.FINEST,String.format("data hex: %s", hex));
- assertEquals("8190",hex);
+ assertEquals("90",hex);
}
@@ -70,11 +71,11 @@ public class UperEncodeBitStringTest {
byte[] encoded = UperEncoder.encode(record);
String hex = UperEncoder.hexStringFromBytes(encoded);
UperEncoder.logger.log(Level.FINEST,String.format("data hex: %s", hex));
- assertEquals("8190",hex);
+ assertEquals("90",hex);
TestRecord result = UperEncoder.decode(encoded, TestRecord.class);
- assertEquals(result.value.get(0),record.value.get(0));
- assertEquals(result.value.get(1),record.value.get(1));
- assertEquals(result.value.get(2),record.value.get(2));
+ assertEquals(result.booleans.get(0),record.booleans.get(0));
+ assertEquals(result.booleans.get(1),record.booleans.get(1));
+ assertEquals(result.booleans.get(2),record.booleans.get(2));
}
diff --git a/src/test/java/org/uic/barcode/asn1/test/UperEncodeStringCustomAlphabetTest.java b/src/test/java/org/uic/barcode/asn1/test/UperEncodeStringCustomAlphabetTest.java
new file mode 100644
index 0000000..03b8bac
--- /dev/null
+++ b/src/test/java/org/uic/barcode/asn1/test/UperEncodeStringCustomAlphabetTest.java
@@ -0,0 +1,82 @@
+package org.uic.barcode.asn1.test;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.logging.Level;
+
+import org.junit.Test;
+import org.uic.barcode.asn1.datatypes.Asn1Optional;
+import org.uic.barcode.asn1.datatypes.CharacterRestriction;
+import org.uic.barcode.asn1.datatypes.FieldOrder;
+import org.uic.barcode.asn1.datatypes.RestrictedString;
+import org.uic.barcode.asn1.datatypes.Sequence;
+import org.uic.barcode.asn1.uper.UperEncoder;
+
+
+public class UperEncodeStringCustomAlphabetTest {
+
+ /**
+ * Example from the Standard on UPER.
+ <pre>
+ World-Schema DEFINITIONS AUTOMATIC TAGS ::=
+ BEGIN
+ TestRecord ::= [APPLICATION 0] IMPLICIT SEQUENCE {
+ value1 PrintableString ( FROM ("ACGT") ) OPTIONAL,
+ value2 PrintableString ( FROM ("ACGT") ) OPTIONAL
+ }
+ END
+
+ rec1value TestRecord ::= {
+ value1 "ACGT",
+ value2 "ACTGCATCGA"
+ }
+ </pre>
+ */
+ @Sequence
+ public static class TestRecord {
+
+ @FieldOrder(order = 0)
+ @RestrictedString(value = CharacterRestriction.VisibleString, alphabet = GenAlphabet.class)
+ @Asn1Optional() String value1;
+
+ @FieldOrder(order = 1)
+ @RestrictedString(value = CharacterRestriction.VisibleString, alphabet = GenAlphabet.class)
+ @Asn1Optional() String value2;
+
+ public TestRecord() {
+ }
+
+ public TestRecord(String v1, String v2) {
+ this.value1 = v1;
+ this.value2 = v2;
+ }
+ }
+
+
+ @Test public void testEncode() throws IllegalArgumentException, IllegalAccessException {
+
+
+ TestRecord record = new TestRecord("ACGT", "ACTGCATCGA");
+ byte[] encoded = UperEncoder.encode(record);
+ String hex = UperEncoder.hexStringFromBytes(encoded);
+ UperEncoder.logger.log(Level.FINEST,String.format("data hex: %s", hex));
+ assertEquals("C106C2879360",hex);
+
+ }
+
+
+ @Test public void testDecode() throws IllegalArgumentException, IllegalAccessException {
+
+ TestRecord record = new TestRecord("ACGT", "ACTGCATCGA");
+ byte[] encoded = UperEncoder.encode(record);
+ String hex = UperEncoder.hexStringFromBytes(encoded);
+ UperEncoder.logger.log(Level.FINEST,String.format("data hex: %s", hex));
+ assertEquals("C106C2879360",hex);
+ TestRecord result = UperEncoder.decode(encoded, TestRecord.class);
+ assertEquals(result.value1,record.value1);
+ assertEquals(result.value2,record.value2);
+ }
+
+
+
+}
diff --git a/src/test/java/org/uic/barcode/asn1/test/UperEncodeVarBitStringTest.java b/src/test/java/org/uic/barcode/asn1/test/UperEncodeVarBitStringTest.java
new file mode 100644
index 0000000..d6212e2
--- /dev/null
+++ b/src/test/java/org/uic/barcode/asn1/test/UperEncodeVarBitStringTest.java
@@ -0,0 +1,81 @@
+package org.uic.barcode.asn1.test;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.logging.Level;
+
+import org.junit.Test;
+import org.uic.barcode.asn1.datatypes.Asn1Optional;
+import org.uic.barcode.asn1.datatypes.Asn1VarSizeBitstring;
+import org.uic.barcode.asn1.datatypes.FieldOrder;
+import org.uic.barcode.asn1.datatypes.Sequence;
+import org.uic.barcode.asn1.uper.UperEncoder;
+
+
+public class UperEncodeVarBitStringTest {
+
+ /**
+ * Example from the Standard on UPER.
+ <pre>
+ World-Schema DEFINITIONS AUTOMATIC TAGS ::=
+ BEGIN
+ TestRecord ::= [APPLICATION 0] IMPLICIT SEQUENCE {
+ value BIT STRING OPTIONAL,
+ }
+ END
+
+
+ rec1value TestRecord ::= {
+ value '001'B
+ }
+ </pre>
+
+
+
+ */
+ @Sequence
+ public static class TestRecord {
+
+ @FieldOrder(order = 0)
+ @Asn1Optional() Asn1VarSizeBitstring value;
+
+ public TestRecord() {
+ this(false,false,true);
+ }
+
+ public TestRecord(Boolean value1,Boolean value2,Boolean value3 ) {
+ List<Boolean> booleans = new ArrayList<Boolean>();
+ booleans.add(value1);
+ booleans.add(value2);
+ booleans.add(value3);
+ this.value = new Asn1VarSizeBitstring(booleans);
+
+ }
+ }
+
+
+ @Test public void testEncode() throws IllegalArgumentException, IllegalAccessException {
+ TestRecord record = new TestRecord(false,false,true);
+ byte[] encoded = UperEncoder.encode(record);
+ String hex = UperEncoder.hexStringFromBytes(encoded);
+ UperEncoder.logger.log(Level.FINEST,String.format("data hex: %s", hex));
+ assertEquals("8190",hex);
+ }
+
+
+ @Test public void testDecode() throws IllegalArgumentException, IllegalAccessException {
+ TestRecord record = new TestRecord(false,false,true);
+ byte[] encoded = UperEncoder.encode(record);
+ String hex = UperEncoder.hexStringFromBytes(encoded);
+ UperEncoder.logger.log(Level.FINEST,String.format("data hex: %s", hex));
+ assertEquals("8190",hex);
+ TestRecord result = UperEncoder.decode(encoded, TestRecord.class);
+ assertEquals(result.value.get(0),record.value.get(0));
+ assertEquals(result.value.get(1),record.value.get(1));
+ assertEquals(result.value.get(2),record.value.get(2));
+
+ }
+
+}