1b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallampackage org.bouncycastle.asn1.util;
2b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
3c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstromimport java.io.IOException;
4b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport java.util.Enumeration;
5b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
6c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstromimport org.bouncycastle.asn1.ASN1OctetString;
7c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstromimport org.bouncycastle.asn1.ASN1Sequence;
8c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstromimport org.bouncycastle.asn1.ASN1Set;
9c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstromimport org.bouncycastle.asn1.BERApplicationSpecific;
10c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstromimport org.bouncycastle.asn1.BERConstructedOctetString;
11c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstromimport org.bouncycastle.asn1.BERSequence;
12c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstromimport org.bouncycastle.asn1.BERSet;
13c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstromimport org.bouncycastle.asn1.BERTaggedObject;
14c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstromimport org.bouncycastle.asn1.DERApplicationSpecific;
15c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstromimport org.bouncycastle.asn1.DERBMPString;
16c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstromimport org.bouncycastle.asn1.DERBitString;
17c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstromimport org.bouncycastle.asn1.DERBoolean;
18c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstromimport org.bouncycastle.asn1.DEREncodable;
19c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstromimport org.bouncycastle.asn1.DEREnumerated;
20c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstromimport org.bouncycastle.asn1.DERExternal;
21c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstromimport org.bouncycastle.asn1.DERGeneralizedTime;
22c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstromimport org.bouncycastle.asn1.DERIA5String;
23c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstromimport org.bouncycastle.asn1.DERInteger;
24c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstromimport org.bouncycastle.asn1.DERNull;
25c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstromimport org.bouncycastle.asn1.DERObject;
26c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstromimport org.bouncycastle.asn1.DERObjectIdentifier;
27c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstromimport org.bouncycastle.asn1.DEROctetString;
28c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstromimport org.bouncycastle.asn1.DERPrintableString;
29c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstromimport org.bouncycastle.asn1.DERSequence;
30c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstromimport org.bouncycastle.asn1.DERSet;
31c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstromimport org.bouncycastle.asn1.DERT61String;
32c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstromimport org.bouncycastle.asn1.DERTaggedObject;
33c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstromimport org.bouncycastle.asn1.DERTags;
34c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstromimport org.bouncycastle.asn1.DERUTCTime;
35c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstromimport org.bouncycastle.asn1.DERUTF8String;
36c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstromimport org.bouncycastle.asn1.DERUnknownTag;
37c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstromimport org.bouncycastle.asn1.DERVisibleString;
38b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport org.bouncycastle.util.encoders.Hex;
39b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
40b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallampublic class ASN1Dump
41b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam{
42c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    private static final String  TAB = "    ";
43c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    private static final int SAMPLE_SIZE = 32;
44b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
45b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    /**
46b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * dump a DER object as a formatted string with indentation
47b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     *
48b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * @param obj the DERObject to be dumped out.
49b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     */
50c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    static void _dumpAsString(
51b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        String      indent,
52c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        boolean     verbose,
53c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        DERObject   obj,
54c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        StringBuffer    buf)
55b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
56c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        String nl = System.getProperty("line.separator");
57b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        if (obj instanceof ASN1Sequence)
58b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
59b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            Enumeration     e = ((ASN1Sequence)obj).getObjects();
60b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            String          tab = indent + TAB;
61b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
62b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            buf.append(indent);
636e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom            if (obj instanceof BERSequence)
64b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            {
65b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                buf.append("BER Sequence");
66b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            }
67b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            else if (obj instanceof DERSequence)
68b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            {
69b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                buf.append("DER Sequence");
70b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            }
71b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            else
72b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            {
73b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                buf.append("Sequence");
74b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            }
75b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
76c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            buf.append(nl);
77b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
78b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            while (e.hasMoreElements())
79b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            {
80b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                Object  o = e.nextElement();
81b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
82b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                // BEGIN android-changed
83c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                if (o == null || o.equals(DERNull.INSTANCE))
84c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                // END android-changed
85b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                {
86b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                    buf.append(tab);
87b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                    buf.append("NULL");
88c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                    buf.append(nl);
89b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                }
90b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                else if (o instanceof DERObject)
91b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                {
92c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                    _dumpAsString(tab, verbose, (DERObject)o, buf);
93b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                }
94b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                else
95b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                {
96c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                    _dumpAsString(tab, verbose, ((DEREncodable)o).getDERObject(), buf);
97b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                }
98b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            }
99b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
100b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        else if (obj instanceof DERTaggedObject)
101b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
102b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            String          tab = indent + TAB;
103b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
104b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            buf.append(indent);
105b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            if (obj instanceof BERTaggedObject)
106b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            {
107b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                buf.append("BER Tagged [");
108b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            }
109b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            else
110b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            {
111b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                buf.append("Tagged [");
112b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            }
113b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
114b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            DERTaggedObject o = (DERTaggedObject)obj;
115b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
116b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            buf.append(Integer.toString(o.getTagNo()));
117b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            buf.append(']');
118b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
119b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            if (!o.isExplicit())
120b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            {
121b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                buf.append(" IMPLICIT ");
122b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            }
123b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
124c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            buf.append(nl);
125b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
126b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            if (o.isEmpty())
127b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            {
128b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                buf.append(tab);
129b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                buf.append("EMPTY");
130c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                buf.append(nl);
131b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            }
132b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            else
133b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            {
134c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                _dumpAsString(tab, verbose, o.getObject(), buf);
135b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            }
136b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
137b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        else if (obj instanceof BERSet)
138b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
139b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            Enumeration     e = ((ASN1Set)obj).getObjects();
140b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            String          tab = indent + TAB;
141b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
142b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            buf.append(indent);
143b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            buf.append("BER Set");
144c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            buf.append(nl);
145b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
146b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            while (e.hasMoreElements())
147b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            {
148b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                Object  o = e.nextElement();
149b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
150b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                if (o == null)
151b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                {
152b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                    buf.append(tab);
153b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                    buf.append("NULL");
154c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                    buf.append(nl);
155b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                }
156b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                else if (o instanceof DERObject)
157b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                {
158c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                    _dumpAsString(tab, verbose, (DERObject)o, buf);
159b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                }
160b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                else
161b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                {
162c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                    _dumpAsString(tab, verbose, ((DEREncodable)o).getDERObject(), buf);
163b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                }
164b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            }
165b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
166b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        else if (obj instanceof DERSet)
167b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
168b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            Enumeration     e = ((ASN1Set)obj).getObjects();
169b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            String          tab = indent + TAB;
170b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
171b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            buf.append(indent);
172b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            buf.append("DER Set");
173c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            buf.append(nl);
174b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
175b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            while (e.hasMoreElements())
176b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            {
177b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                Object  o = e.nextElement();
178b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
179b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                if (o == null)
180b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                {
181b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                    buf.append(tab);
182b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                    buf.append("NULL");
183c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                    buf.append(nl);
184b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                }
185b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                else if (o instanceof DERObject)
186b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                {
187c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                    _dumpAsString(tab, verbose, (DERObject)o, buf);
188b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                }
189b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                else
190b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                {
191c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                    _dumpAsString(tab, verbose, ((DEREncodable)o).getDERObject(), buf);
192b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                }
193b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            }
194b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
195b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        else if (obj instanceof DERObjectIdentifier)
196b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
197c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            buf.append(indent + "ObjectIdentifier(" + ((DERObjectIdentifier)obj).getId() + ")" + nl);
198b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
199b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        else if (obj instanceof DERBoolean)
200b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
201c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            buf.append(indent + "Boolean(" + ((DERBoolean)obj).isTrue() + ")" + nl);
202b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
203b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        else if (obj instanceof DERInteger)
204b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
205c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            buf.append(indent + "Integer(" + ((DERInteger)obj).getValue() + ")" + nl);
206b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
207b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        else if (obj instanceof BERConstructedOctetString)
208b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
209c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            ASN1OctetString oct = (ASN1OctetString)obj;
210c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            buf.append(indent + "BER Constructed Octet String" + "[" + oct.getOctets().length + "] ");
211c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            if (verbose)
212c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            {
213c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                buf.append(dumpBinaryDataAsString(indent, oct.getOctets()));
214c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            }
215c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            else{
216c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                buf.append(nl);
217c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            }
218b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
219b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        else if (obj instanceof DEROctetString)
220b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
221c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            ASN1OctetString oct = (ASN1OctetString)obj;
222c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            buf.append(indent + "DER Octet String" + "[" + oct.getOctets().length + "] ");
223c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            if (verbose)
224c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            {
225c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                buf.append(dumpBinaryDataAsString(indent, oct.getOctets()));
226c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            }
227c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            else{
228c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                buf.append(nl);
229c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            }
230b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
231b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        else if (obj instanceof DERBitString)
232b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
233c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            DERBitString bt = (DERBitString)obj;
234c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            buf.append(indent + "DER Bit String" + "[" + bt.getBytes().length + ", " + bt.getPadBits() + "] ");
235c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            if (verbose)
236c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            {
237c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                buf.append(dumpBinaryDataAsString(indent, bt.getBytes()));
238c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            }
239c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            else{
240c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                buf.append(nl);
241c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            }
242b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
243b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        else if (obj instanceof DERIA5String)
244b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
245c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            buf.append(indent + "IA5String(" + ((DERIA5String)obj).getString() + ") " + nl);
246b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
247b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        else if (obj instanceof DERUTF8String)
248b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
249c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            buf.append(indent + "UTF8String(" + ((DERUTF8String)obj).getString() + ") " + nl);
250b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
251b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        else if (obj instanceof DERPrintableString)
252b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
253c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            buf.append(indent + "PrintableString(" + ((DERPrintableString)obj).getString() + ") " + nl);
254b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
255b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        else if (obj instanceof DERVisibleString)
256b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
257c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            buf.append(indent + "VisibleString(" + ((DERVisibleString)obj).getString() + ") " + nl);
258b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
259b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        else if (obj instanceof DERBMPString)
260b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
261c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            buf.append(indent + "BMPString(" + ((DERBMPString)obj).getString() + ") " + nl);
262b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
263b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        else if (obj instanceof DERT61String)
264b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
265c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            buf.append(indent + "T61String(" + ((DERT61String)obj).getString() + ") " + nl);
266b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
267b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        else if (obj instanceof DERUTCTime)
268b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
269c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            buf.append(indent + "UTCTime(" + ((DERUTCTime)obj).getTime() + ") " + nl);
270b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
271b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        else if (obj instanceof DERGeneralizedTime)
272b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
273c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            buf.append(indent + "GeneralizedTime(" + ((DERGeneralizedTime)obj).getTime() + ") " + nl);
274b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
275b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        else if (obj instanceof DERUnknownTag)
276b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
277c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            buf.append(indent + "Unknown " + Integer.toString(((DERUnknownTag)obj).getTag(), 16) + " " + new String(Hex.encode(((DERUnknownTag)obj).getData())) + nl);
278c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        }
279c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        else if (obj instanceof BERApplicationSpecific)
280c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        {
281c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            buf.append(outputApplicationSpecific("BER", indent, verbose, obj, nl));
282c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        }
283c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        else if (obj instanceof DERApplicationSpecific)
284c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        {
285c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            buf.append(outputApplicationSpecific("DER", indent, verbose, obj, nl));
286c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        }
287c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        else if (obj instanceof DEREnumerated)
288c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        {
289c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            DEREnumerated en = (DEREnumerated) obj;
290c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            buf.append(indent + "DER Enumerated(" + en.getValue() + ")" + nl);
291c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        }
292c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        else if (obj instanceof DERExternal)
293c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        {
294c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            DERExternal ext = (DERExternal) obj;
295c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            buf.append(indent + "External " + nl);
296c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            String          tab = indent + TAB;
297c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            if (ext.getDirectReference() != null)
298c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            {
299c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                buf.append(tab + "Direct Reference: " + ext.getDirectReference().getId() + nl);
300c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            }
301c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            if (ext.getIndirectReference() != null)
302c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            {
303c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                buf.append(tab + "Indirect Reference: " + ext.getIndirectReference().toString() + nl);
304c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            }
305c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            if (ext.getDataValueDescriptor() != null)
306c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            {
307c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                _dumpAsString(tab, verbose, ext.getDataValueDescriptor(), buf);
308c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            }
309c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            buf.append(tab + "Encoding: " + ext.getEncoding() + nl);
310c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            _dumpAsString(tab, verbose, ext.getExternalContent(), buf);
311b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
312b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        else
313b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
314c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            buf.append(indent + obj.toString() + nl);
315c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        }
316c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    }
317c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
318c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    private static String outputApplicationSpecific(String type, String indent, boolean verbose, DERObject obj, String nl)
319c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    {
320c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        DERApplicationSpecific app = (DERApplicationSpecific)obj;
321c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        StringBuffer buf = new StringBuffer();
322c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
323c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        if (app.isConstructed())
324c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        {
325c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            try
326c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            {
327c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                ASN1Sequence s = ASN1Sequence.getInstance(app.getObject(DERTags.SEQUENCE));
328c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                buf.append(indent + type + " ApplicationSpecific[" + app.getApplicationTag() + "]" + nl);
329c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                for (Enumeration e = s.getObjects(); e.hasMoreElements();)
330c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                {
331c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                    _dumpAsString(indent + TAB, verbose, (DERObject)e.nextElement(), buf);
332c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                }
333c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            }
334c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            catch (IOException e)
335c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            {
336c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                buf.append(e);
337c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            }
338c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            return buf.toString();
339b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
340c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
341c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        return indent + type + " ApplicationSpecific[" + app.getApplicationTag() + "] (" + new String(Hex.encode(app.getContents())) + ")" + nl;
342b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
343b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
344b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    /**
345c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom     * dump out a DER object as a formatted string, in non-verbose mode.
346b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     *
347b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * @param obj the DERObject to be dumped out.
348c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom     * @return  the resulting string.
349b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     */
350b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public static String dumpAsString(
351b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        Object   obj)
352b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
353c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        return dumpAsString(obj, false);
354c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    }
355c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
356c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    /**
357c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom     * Dump out the object as a string.
358c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom     *
359c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom     * @param obj  the object to be dumped
360c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom     * @param verbose  if true, dump out the contents of octet and bit strings.
361c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom     * @return  the resulting string.
362c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom     */
363c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    public static String dumpAsString(
364c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        Object   obj,
365c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        boolean  verbose)
366c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    {
367c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        StringBuffer buf = new StringBuffer();
368c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
369b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        if (obj instanceof DERObject)
370b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
371c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            _dumpAsString("", verbose, (DERObject)obj, buf);
372b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
373b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        else if (obj instanceof DEREncodable)
374b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
375c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            _dumpAsString("", verbose, ((DEREncodable)obj).getDERObject(), buf);
376c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        }
377c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        else
378c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        {
379c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            return "unknown object type " + obj.toString();
380c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        }
381c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
382c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        return buf.toString();
383c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    }
384c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
385c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    private static String dumpBinaryDataAsString(String indent, byte[] bytes)
386c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    {
387c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        String nl = System.getProperty("line.separator");
388c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        StringBuffer buf = new StringBuffer();
389c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
390c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        indent += TAB;
391c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
392c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        buf.append(nl);
393c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        for (int i = 0; i < bytes.length; i += SAMPLE_SIZE)
394c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        {
395c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            if (bytes.length - i > SAMPLE_SIZE)
396c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            {
397c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                buf.append(indent);
398c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                buf.append(new String(Hex.encode(bytes, i, SAMPLE_SIZE)));
399c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                buf.append(TAB);
400c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                buf.append(calculateAscString(bytes, i, SAMPLE_SIZE));
401c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                buf.append(nl);
402c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            }
403c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            else
404c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            {
405c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                buf.append(indent);
406c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                buf.append(new String(Hex.encode(bytes, i, bytes.length - i)));
407c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                for (int j = bytes.length - i; j != SAMPLE_SIZE; j++)
408c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                {
409c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                    buf.append("  ");
410c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                }
411c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                buf.append(TAB);
412c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                buf.append(calculateAscString(bytes, i, bytes.length - i));
413c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                buf.append(nl);
414c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            }
415c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        }
416c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
417c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        return buf.toString();
418c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    }
419c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
420c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    private static String calculateAscString(byte[] bytes, int off, int len)
421c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    {
422c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        StringBuffer buf = new StringBuffer();
423c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
424c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        for (int i = off; i != off + len; i++)
425c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        {
426c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            if (bytes[i] >= ' ' && bytes[i] <= '~')
427c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            {
428c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                buf.append((char)bytes[i]);
429c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            }
430b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
431b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
432c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        return buf.toString();
433b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
434b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam}
435