1 /*
2  * @(#) $Id: ASN1Set.java,v 1.3 2003/07/08 08:13:52 pankaj Exp $
3  *
4  * Copyright (c) 2002-03 by Pankaj Kumar (http://www.pankaj-k.net). 
5  * All rights reserved.
6  *
7  * The license governing the use of this file can be found in the 
8  * root directory of the containing software.
9  */
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}