KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > lowagie > bc > asn1 > BERInputStream


1 package com.lowagie.bc.asn1;
2
3 import java.io.ByteArrayOutputStream;
4 import java.io.EOFException;
5 import java.io.IOException;
6 import java.io.InputStream;
7 import java.util.Vector;
8
9 public class BERInputStream
10     extends DERInputStream
11 {
12     private DERObject END_OF_STREAM = new DERObject() {
13                                         void encode(
14                                             DEROutputStream out)
15                                         throws IOException
16                                         {
17                                             throw new IOException("Eeek!");
18                                         }
19
20                                     };
21     public BERInputStream(
22         InputStream is)
23     {
24         super(is);
25     }
26
27     /**
28      * read a string of bytes representing an indefinite length object.
29      */

30     private byte[] readIndefiniteLengthFully()
31         throws IOException
32     {
33         ByteArrayOutputStream bOut = new ByteArrayOutputStream();
34         int b, b1;
35
36         b1 = read();
37
38         while ((b = read()) >= 0)
39         {
40             if (b1 == 0 && b == 0)
41             {
42                 break;
43             }
44
45             bOut.write(b1);
46             b1 = b;
47         }
48
49         return bOut.toByteArray();
50     }
51
52     private BERConstructedOctetString buildConstructedOctetString()
53         throws IOException
54     {
55         Vector octs = new Vector();
56
57         for (;;)
58         {
59             DERObject o = readObject();
60
61             if (o == END_OF_STREAM)
62             {
63                 break;
64             }
65
66             octs.addElement(o);
67         }
68
69         return new BERConstructedOctetString(octs);
70     }
71
72     public DERObject readObject()
73         throws IOException
74     {
75         int tag = read();
76         if (tag == -1)
77         {
78             throw new EOFException();
79         }
80     
81         int length = readLength();
82
83         if (length < 0) // indefinite length method
84
{
85             switch (tag)
86             {
87             case NULL:
88                 return null;
89             case SEQUENCE | CONSTRUCTED:
90                 BERConstructedSequence seq = new BERConstructedSequence();
91     
92                 for (;;)
93                 {
94                     DERObject obj = readObject();
95
96                     if (obj == END_OF_STREAM)
97                     {
98                         break;
99                     }
100
101                     seq.addObject(obj);
102                 }
103                 return seq;
104             case OCTET_STRING | CONSTRUCTED:
105                 return buildConstructedOctetString();
106             case SET | CONSTRUCTED:
107                 ASN1EncodableVector v = new ASN1EncodableVector();
108     
109                 for (;;)
110                 {
111                     DERObject obj = readObject();
112
113                     if (obj == END_OF_STREAM)
114                     {
115                         break;
116                     }
117
118                     v.add(obj);
119                 }
120                 return new BERSet(v);
121             default:
122                 //
123
// with tagged object tag number is bottom 5 bits
124
//
125
if ((tag & TAGGED) != 0)
126                 {
127                     if ((tag & 0x1f) == 0x1f)
128                     {
129                         throw new IOException("unsupported high tag encountered");
130                     }
131
132                     //
133
// simple type - implicit... return an octet string
134
//
135
if ((tag & CONSTRUCTED) == 0)
136                     {
137                         byte[] bytes = readIndefiniteLengthFully();
138
139                         return new BERTaggedObject(false, tag & 0x1f, new DEROctetString(bytes));
140                     }
141
142                     //
143
// either constructed or explicitly tagged
144
//
145
DERObject dObj = readObject();
146
147                     if (dObj == END_OF_STREAM) // empty tag!
148
{
149                         return new DERTaggedObject(tag & 0x1f);
150                     }
151
152                     DERObject next = readObject();
153
154                     //
155
// explicitly tagged (probably!) - if it isn't we'd have to
156
// tell from the context
157
//
158
if (next == END_OF_STREAM)
159                     {
160                         return new BERTaggedObject(tag & 0x1f, dObj);
161                     }
162
163                     //
164
// another implicit object, we'll create a sequence...
165
//
166
seq = new BERConstructedSequence();
167
168                     seq.addObject(dObj);
169
170                     do
171                     {
172                         seq.addObject(next);
173                         next = readObject();
174                     }
175                     while (next != END_OF_STREAM);
176
177                     return new BERTaggedObject(false, tag & 0x1f, seq);
178                 }
179
180                 throw new IOException("unknown BER object encountered");
181             }
182         }
183         else
184         {
185             if (tag == 0 && length == 0) // end of contents marker.
186
{
187                 return END_OF_STREAM;
188             }
189
190             byte[] bytes = new byte[length];
191     
192             readFully(bytes);
193     
194             return buildObject(tag, bytes);
195         }
196     }
197 }
198
Popular Tags