using System;
using System.IO;
using Org.BouncyCastle.Asn1.Utilities;
namespace Org.BouncyCastle.Asn1{
public class DerOutputStream
: FilterStream
{
public DerOutputStream(Stream os)
: base(os)
{
}
private void WriteLength(
int length)
{
if (length > 127)
{
int size = 1;
uint val = (uint) length;
while ((val >>= 8) != 0)
{
size++;
}
WriteByte((byte)(size | 0x80));
for (int i = (size - 1) * 8; i >= 0; i -= 8)
{
WriteByte((byte)(length >> i));
}
}
else
{
WriteByte((byte)length);
}
}
internal void WriteEncoded(
int tag,
byte[] bytes)
{
WriteByte((byte) tag);
WriteLength(bytes.Length);
Write(bytes, 0, bytes.Length);
}
internal void WriteEncoded(
int tag,
byte[] bytes,
int offset,
int length)
{
WriteByte((byte) tag);
WriteLength(length);
Write(bytes, offset, length);
}
internal void WriteTag(
int flags,
int tagNo)
{
if (tagNo < 31)
{
WriteByte((byte)(flags | tagNo));
}
else
{
WriteByte((byte)(flags | 0x1f));
if (tagNo < 128)
{
WriteByte((byte)tagNo);
}
else
{
byte[] stack = new byte[5];
int pos = stack.Length;
stack[--pos] = (byte)(tagNo & 0x7F);
do
{
tagNo >>= 7;
stack[--pos] = (byte)(tagNo & 0x7F | 0x80);
}
while (tagNo > 127);
Write(stack, pos, stack.Length - pos);
}
}
}
internal void WriteEncoded(
int flags,
int tagNo,
byte[] bytes)
{
WriteTag(flags, tagNo);
WriteLength(bytes.Length);
Write(bytes, 0, bytes.Length);
}
protected void WriteNull()
{
WriteByte(Asn1Tags.Null);
WriteByte(0x00);
}
[Obsolete("Use version taking an Asn1Encodable arg instead")]
public virtual void WriteObject(
object obj)
{
if (obj == null)
{
WriteNull();
}
else if (obj is Asn1Object)
{
((Asn1Object)obj).Encode(this);
}
else if (obj is Asn1Encodable)
{
((Asn1Encodable)obj).ToAsn1Object().Encode(this);
}
else
{
throw new IOException("object not Asn1Object");
}
}
public virtual void WriteObject(
Asn1Encodable obj)
{
if (obj == null)
{
WriteNull();
}
else
{
obj.ToAsn1Object().Encode(this);
}
}
public virtual void WriteObject(
Asn1Object obj)
{
if (obj == null)
{
WriteNull();
}
else
{
obj.Encode(this);
}
}
}
}
|