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