1 /*
2  * @(#) $Id: ASN1Seq.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.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}