1
10package org.jstk.asn1;
11
12import java.io.IOException;
13import java.util.Vector;
14
15public class ASN1Seq extends ASN1Type {
16 protected Vector elems = new Vector();
17 private boolean ignoreMembers = false;
18 public ASN1Seq(){
19 super(UNIVERSAL, NONE, SEQUENCE, SEQUENCE);
20 setConsMask(CONSTRUCTED);
21 }
22 public ASN1Seq(byte tagClass, int taggingMethod, int tagNumber){
23 super(tagClass, taggingMethod, tagNumber, SEQUENCE);
24 setConsMask(CONSTRUCTED);
25 }
26
27 public void setIgnoreMembers(boolean flag){
28 ignoreMembers = flag;
29 }
30 public void decode(ASN1PullParser parser) throws ASN1PullParserException, IOException {
31 logger.entering(getClass().getName(), "decode");
32 int event = parser.next();
33
34 logger.fine("[ASN1Seq.decode()] event = " + event + ", off = " + parser.getOffset() +
35 ", len = " + parser.getLength());
36 if (event != ASN1PullParser.START_SEQ)
37 throw new ASN1PullParserException("unexpected type");
38
39 consMask = parser.getConsMask();
40 int expSize = elems.size();
41 int idx = 0;
42 while ((event = parser.next()) != ASN1PullParser.END_SEQ){
43 ASN1Type elem = null;
44
45 if (idx < elems.size()){
46 elem = (ASN1Type)elems.elementAt(idx);
47 } else {
48 elem = ASN1Any.createASN1Type(event, parser.getTagClass());
49 elems.add(elem);
50 }
51 parser.prev();
52 elem.decode(parser);
53 ++idx;
54 }
55 logger.fine("configured for: " + expSize + ", found: " + elems.size());
56 logger.exiting(getClass().getName(), "decode");
57 }
58
59 public byte[] encode(){
60 logger.entering(getClass().getName(), "encode");
61 if (ignoreMembers){
62 logger.fine("Ignoring members. Perhaps the encoded value has been set ...");
63 byte[] bytes = value;
64 logger.exiting(getClass().getName(), "encode");
65 return bytes;
66 }
67
68 if (elems == null)
69 return null;
70 Vector elemEncodings = new Vector();
71 int len = 0;
72 for (int i = 0; i < elems.size(); i++){
73 ASN1Type elem = (ASN1Type)elems.elementAt(i);
74 byte[] encoded = elem.encode();
75 if (encoded != null){
76 len += encoded.length;
77 elemEncodings.add(encoded);
78 }
79 }
80 byte idOctet = (byte)(tagClass | consMask| tagNumber);
81 byte[] lenEncoding = encodeLen(len);
82 byte[] bytes = new byte[1 + lenEncoding.length + len];
83 int idx = 0;
84 bytes[idx++] = idOctet;
85 for (int i = 0; i < lenEncoding.length; i++){
86 bytes[idx++] = lenEncoding[i];
87 }
88 for (int i = 0; i < elemEncodings.size(); i++){
89 byte[] encoded = (byte[])elemEncodings.elementAt(i);
90 if (encoded != null){
91 for (int j = 0; j < encoded.length; j++){
92 bytes[idx++] = encoded[j];
93 }
94 }
95 }
96 logger.fine("[ASN1Seq.encode()] idOctet = " + Integer.toHexString(idOctet) +
97 ", #lenOctets = " + lenEncoding.length + ", len = " + len);
98 logger.exiting(getClass().getName(), "encode");
99 return bytes;
00 }
01
02 public int size(){
03 return elems.size();
04 }
05
06 public void add(Object o){
07 elems.add(o);
08 }
09
10 public Object elementAt(int idx){
11 return elems.elementAt(idx);
12 }
13
14 public String toString(){
15 StringBuffer sb = new StringBuffer();
16 sb.append("SEQ(");
17 for (int i = 0; i < elems.size(); i++){
18 if (i > 0)
19 sb.append(", ");
20 sb.append(elems.elementAt(i).toString());
21 }
22 sb.append(")");
23 return sb.toString();
24 }
25}