summary refs log tree commit diff
path: root/Crypto/src/asn1/BEROctetStringGenerator.cs
diff options
context:
space:
mode:
Diffstat (limited to 'Crypto/src/asn1/BEROctetStringGenerator.cs')
-rw-r--r--Crypto/src/asn1/BEROctetStringGenerator.cs121
1 files changed, 121 insertions, 0 deletions
diff --git a/Crypto/src/asn1/BEROctetStringGenerator.cs b/Crypto/src/asn1/BEROctetStringGenerator.cs
new file mode 100644

index 000000000..644060765 --- /dev/null +++ b/Crypto/src/asn1/BEROctetStringGenerator.cs
@@ -0,0 +1,121 @@ +using System; +using System.IO; + +using Org.BouncyCastle.Utilities.IO; + +namespace Org.BouncyCastle.Asn1 +{ + public class BerOctetStringGenerator + : BerGenerator + { + public BerOctetStringGenerator(Stream outStream) + : base(outStream) + { + WriteBerHeader(Asn1Tags.Constructed | Asn1Tags.OctetString); + } + + public BerOctetStringGenerator( + Stream outStream, + int tagNo, + bool isExplicit) + : base(outStream, tagNo, isExplicit) + { + WriteBerHeader(Asn1Tags.Constructed | Asn1Tags.OctetString); + } + + public Stream GetOctetOutputStream() + { + return GetOctetOutputStream(new byte[1000]); // limit for CER encoding. + } + + public Stream GetOctetOutputStream( + int bufSize) + { + return bufSize < 1 + ? GetOctetOutputStream() + : GetOctetOutputStream(new byte[bufSize]); + } + + public Stream GetOctetOutputStream( + byte[] buf) + { + return new BufferedBerOctetStream(this, buf); + } + + private class BufferedBerOctetStream + : BaseOutputStream + { + private byte[] _buf; + private int _off; + private readonly BerOctetStringGenerator _gen; + private readonly DerOutputStream _derOut; + + internal BufferedBerOctetStream( + BerOctetStringGenerator gen, + byte[] buf) + { + _gen = gen; + _buf = buf; + _off = 0; + _derOut = new DerOutputStream(_gen.Out); + } + + public override void WriteByte( + byte b) + { + _buf[_off++] = b; + + if (_off == _buf.Length) + { + DerOctetString.Encode(_derOut, _buf, 0, _off); + _off = 0; + } + } + + public override void Write( + byte[] buf, + int offset, + int len) + { + while (len > 0) + { + int numToCopy = System.Math.Min(len, _buf.Length - _off); + + if (numToCopy == _buf.Length) + { + DerOctetString.Encode(_derOut, buf, offset, numToCopy); + } + else + { + Array.Copy(buf, offset, _buf, _off, numToCopy); + + _off += numToCopy; + if (_off < _buf.Length) + break; + + DerOctetString.Encode(_derOut, _buf, 0, _off); + _off = 0; + } + + offset += numToCopy; + len -= numToCopy; + } + } + + protected override void Dispose(bool disposing) + { + if (disposing) + { + if (_off != 0) + { + DerOctetString.Encode(_derOut, _buf, 0, _off); + } + + _gen.WriteBerEnd(); + } + + base.Dispose(disposing); + } + } + } +}