package org.apache.haox.asn1;
import org.apache.haox.asn1.EncodingOption;
import org.apache.haox.asn1.TaggingOption;
import org.apache.haox.asn1.type.Asn1Tagging;
import org.apache.haox.asn1.type.Asn1VisibleString;
import org.junit.Assert;
import org.junit.Test;
import java.io.IOException;
/**
Ref. X.690-0207 8.14 Encoding of a tagged value
EXAMPLE
With ASN.1 type definitions (in an explicit tagging environment) of:
Type1 ::= VisibleString
Type2 ::= [APPLICATION 3] IMPLICIT Type1
Type3 ::= [2] Type2
Type4 ::= [APPLICATION 7] IMPLICIT Type3
Type5 ::= [2] IMPLICIT Type2
a value of:
"Jones"
is encoded as follows:
For Type1:
VisibleString Length Contents
1A16 0516 4A6F6E657316
For Type2:
[Application 3] Length Contents
4316 0516 4A6F6E657316
For Type3:
[2] Length Contents
A216 0716
[APPLICATION 3] Length Contents
4316 0516 4A6F6E657316
For Type4:
[Application 7] Length Contents
6716 0716
[APPLICATION 3] Length Contents
4316 0516 4A6F6E657316
For Type5:
[2] Length Contents
8216 0516 4A6F6E657316
*/
public class TestTaggingEncoding {
static final String TEST_STRING = "Jones";
static byte[] TYPE1_EXPECTED_BYTES = new byte[] {(byte) 0x1A, (byte) 0x05, (byte) 0x4A, (byte) 0x6F, (byte) 0x6E, (byte) 0x65, (byte) 0x73};
static byte[] TYPE2_EXPECTED_BYTES = new byte[] {(byte) 0x43, (byte) 0x05, (byte) 0x4A, (byte) 0x6F, (byte) 0x6E, (byte) 0x65, (byte) 0x73};
static byte[] TYPE3_EXPECTED_BYTES = new byte[] {(byte) 0xA2, (byte) 0x07, (byte) 0x43, (byte) 0x05, (byte) 0x4A, (byte) 0x6F, (byte) 0x6E, (byte) 0x65, (byte) 0x73};
static byte[] TYPE4_EXPECTED_BYTES = new byte[] {(byte) 0x67, (byte) 0x07, (byte) 0x43, (byte) 0x05, (byte) 0x4A, (byte) 0x6F, (byte) 0x6E, (byte) 0x65, (byte) 0x73};
static byte[] TYPE5_EXPECTED_BYTES = new byte[] {(byte) 0x82, (byte) 0x05, (byte) 0x4A, (byte) 0x6F, (byte) 0x6E, (byte) 0x65, (byte) 0x73};
public static class Type1 extends Asn1VisibleString {
public Type1(String value) {
super(value);
}
public Type1() {
this(null);
}
}
public static class Type2 extends Asn1Tagging<Type1> {
public Type2(Type1 value) {
super(3, value, true);
setEncodingOption(EncodingOption.IMPLICIT);
}
public Type2() {
this(null);
}
}
public static class Type3 extends Asn1Tagging<Type2> {
public Type3(Type2 value) {
super(2, value, false);
setEncodingOption(EncodingOption.EXPLICIT);
}
public Type3() {
this(null);
}
}
public static class Type4 extends Asn1Tagging<Type3> {
public Type4(Type3 value) {
super(7, value, true);
setEncodingOption(EncodingOption.IMPLICIT);
}
public Type4() {
this(null);
}
}
public static class Type5 extends Asn1Tagging<Type2> {
public Type5(Type2 value) {
super(2, value, false);
setEncodingOption(EncodingOption.IMPLICIT);
}
public Type5() {
this(null);
}
}
@Test
public void testAsn1TaggingEncoding() {
Type1 aType1 = new Type1(TEST_STRING);
Type2 aType2 = new Type2(aType1);
Type3 aType3 = new Type3(aType2);
Type4 aType4 = new Type4(aType3);
Type5 aType5 = new Type5(aType2);
Assert.assertArrayEquals(TYPE1_EXPECTED_BYTES, aType1.encode());
Assert.assertArrayEquals(TYPE2_EXPECTED_BYTES, aType2.encode());
Assert.assertArrayEquals(TYPE3_EXPECTED_BYTES, aType3.encode());
Assert.assertArrayEquals(TYPE4_EXPECTED_BYTES, aType4.encode());
Assert.assertArrayEquals(TYPE5_EXPECTED_BYTES, aType5.encode());
}
@Test
public void testAsn1TaggingDecoding() throws IOException {
Type1 aType1 = new Type1();
aType1.decode(TYPE1_EXPECTED_BYTES);
Assert.assertEquals(TEST_STRING, aType1.getValue());
Type2 aType2 = new Type2();
aType2.decode(TYPE2_EXPECTED_BYTES);
Assert.assertEquals(TEST_STRING, aType2.getValue().getValue());
Type3 aType3 = new Type3();
aType3.decode(TYPE3_EXPECTED_BYTES);
Assert.assertEquals(TEST_STRING, aType3.getValue().getValue().getValue());
Type4 aType4 = new Type4();
aType4.decode(TYPE4_EXPECTED_BYTES);
Assert.assertEquals(TEST_STRING, aType4.getValue().getValue().getValue().getValue());
Type5 aType5 = new Type5();
aType5.decode(TYPE5_EXPECTED_BYTES);
Assert.assertEquals(TEST_STRING, aType5.getValue().getValue().getValue());
}
@Test
public void testTaggingEncodingOption() {
Type1 aType1 = new Type1(TEST_STRING);
Type2 aType2 = new Type2(aType1);
Type3 aType3 = new Type3(aType2);
Type4 aType4 = new Type4(aType3);
Type5 aType5 = new Type5(aType2);
Assert.assertArrayEquals(TYPE1_EXPECTED_BYTES, aType1.encode());
Assert.assertArrayEquals(TYPE2_EXPECTED_BYTES,
aType1.taggedEncode(TaggingOption.newImplicitAppSpecific(3))); // for Type2
Assert.assertArrayEquals(TYPE3_EXPECTED_BYTES,
aType2.taggedEncode(TaggingOption.newExplicitContextSpecific(2))); // for Type3
Assert.assertArrayEquals(TYPE4_EXPECTED_BYTES,
aType3.taggedEncode(TaggingOption.newImplicitAppSpecific(7))); // for Type4
Assert.assertArrayEquals(TYPE5_EXPECTED_BYTES,
aType2.taggedEncode(TaggingOption.newImplicitContextSpecific(2))); // for Type5
}
@Test
public void testTaggingDecodingOption() throws IOException {
Type1 aType1 = new Type1();
aType1.decode(TYPE1_EXPECTED_BYTES);
Assert.assertEquals(TEST_STRING, aType1.getValue());
// for Type2
aType1 = new Type1();
aType1.taggedDecode(TYPE2_EXPECTED_BYTES, TaggingOption.newImplicitAppSpecific(3));
Assert.assertEquals(TEST_STRING, aType1.getValue());
// for Type3
Type2 aType2 = new Type2();
aType2.taggedDecode(TYPE3_EXPECTED_BYTES, TaggingOption.newExplicitContextSpecific(2));
Assert.assertEquals(TEST_STRING, aType2.getValue().getValue());
// for Type4
Type3 aType3 = new Type3();
aType3.taggedDecode(TYPE4_EXPECTED_BYTES, TaggingOption.newImplicitAppSpecific(7));
Assert.assertEquals(TEST_STRING, aType3.getValue().getValue().getValue());
// for Type5
aType2 = new Type2();
aType2.taggedDecode(TYPE5_EXPECTED_BYTES, TaggingOption.newImplicitContextSpecific(2));
Assert.assertEquals(TEST_STRING, aType2.getValue().getValue());
}
}