package org.apache.commons.ssl.asn1;
import java.io.IOException;
import java.io.InputStream;
public class BERTaggedObjectParser
implements ASN1TaggedObjectParser {
private int _baseTag;
private int _tagNumber;
private InputStream _contentStream;
private boolean _indefiniteLength;
protected BERTaggedObjectParser(
int baseTag,
int tagNumber,
InputStream contentStream) {
_baseTag = baseTag;
_tagNumber = tagNumber;
_contentStream = contentStream;
_indefiniteLength = contentStream instanceof IndefiniteLengthInputStream;
}
public boolean isConstructed() {
return (_baseTag & DERTags.CONSTRUCTED) != 0;
}
public int getTagNo() {
return _tagNumber;
}
public DEREncodable getObjectParser(
int tag,
boolean isExplicit)
throws IOException {
if (isExplicit) {
return new ASN1StreamParser(_contentStream).readObject();
} else {
switch (tag) {
case DERTags.SET:
if (_indefiniteLength) {
return new BERSetParser(new ASN1ObjectParser(_baseTag, _tagNumber, _contentStream));
} else {
return new DERSet(loadVector(_contentStream)).parser();
}
case DERTags.SEQUENCE:
if (_indefiniteLength) {
return new BERSequenceParser(new ASN1ObjectParser(_baseTag, _tagNumber, _contentStream));
} else {
return new DERSequence(loadVector(_contentStream)).parser();
}
case DERTags.OCTET_STRING:
if (_indefiniteLength || this.isConstructed()) {
return new BEROctetStringParser(new ASN1ObjectParser(_baseTag, _tagNumber, _contentStream));
} else {
return new DEROctetString(((DefiniteLengthInputStream) _contentStream).toByteArray()).parser();
}
}
}
throw new RuntimeException("implicit tagging not implemented");
}
private ASN1EncodableVector loadVector(InputStream in)
throws IOException {
ASN1StreamParser aIn = new ASN1StreamParser(in);
ASN1EncodableVector v = new ASN1EncodableVector();
DEREncodable obj = aIn.readObject();
while (obj != null) {
v.add(obj.getDERObject());
obj = aIn.readObject();
}
return v;
}
private ASN1EncodableVector rLoadVector(InputStream in) {
try {
return loadVector(in);
}
catch (IOException e) {
throw new IllegalStateException(e.getMessage());
}
}
public DERObject getDERObject() {
if (_indefiniteLength) {
ASN1EncodableVector v = rLoadVector(_contentStream);
if (v.size() > 1) {
return new BERTaggedObject(false, _tagNumber, new BERSequence(v));
} else if (v.size() == 1) {
return new BERTaggedObject(true, _tagNumber, v.get(0));
} else {
return new BERTaggedObject(false, _tagNumber, new BERSequence());
}
} else {
if (this.isConstructed()) {
ASN1EncodableVector v = rLoadVector(_contentStream);
if (v.size() == 1) {
return new DERTaggedObject(true, _tagNumber, v.get(0));
}
return new DERTaggedObject(false, _tagNumber, new DERSequence(v));
}
try {
return new DERTaggedObject(false, _tagNumber, new DEROctetString(((DefiniteLengthInputStream) _contentStream).toByteArray()));
}
catch (IOException e) {
throw new IllegalStateException(e.getMessage());
}
}
}
}