summary refs log tree commit diff
path: root/crypto/src/cms/CMSCompressedDataStreamGenerator.cs
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/src/cms/CMSCompressedDataStreamGenerator.cs')
-rw-r--r--crypto/src/cms/CMSCompressedDataStreamGenerator.cs140
1 files changed, 140 insertions, 0 deletions
diff --git a/crypto/src/cms/CMSCompressedDataStreamGenerator.cs b/crypto/src/cms/CMSCompressedDataStreamGenerator.cs
new file mode 100644
index 000000000..db0d19845
--- /dev/null
+++ b/crypto/src/cms/CMSCompressedDataStreamGenerator.cs
@@ -0,0 +1,140 @@
+using System;
+using System.IO;
+
+using Org.BouncyCastle.Asn1;
+using Org.BouncyCastle.Asn1.Cms;
+using Org.BouncyCastle.Asn1.X509;
+using Org.BouncyCastle.Utilities.IO;
+using Org.BouncyCastle.Utilities.Zlib;
+
+namespace Org.BouncyCastle.Cms
+{
+	/**
+	* General class for generating a compressed CMS message stream.
+	* <p>
+	* A simple example of usage.
+	* </p>
+	* <pre>
+	*      CMSCompressedDataStreamGenerator gen = new CMSCompressedDataStreamGenerator();
+	*
+	*      Stream cOut = gen.Open(outputStream, CMSCompressedDataStreamGenerator.ZLIB);
+	*
+	*      cOut.Write(data);
+	*
+	*      cOut.Close();
+	* </pre>
+	*/
+	public class CmsCompressedDataStreamGenerator
+	{
+		public const string ZLib = "1.2.840.113549.1.9.16.3.8";
+
+		private int _bufferSize;
+		
+		/**
+		* base constructor
+		*/
+		public CmsCompressedDataStreamGenerator()
+		{
+		}
+
+		/**
+		* Set the underlying string size for encapsulated data
+		*
+		* @param bufferSize length of octet strings to buffer the data.
+		*/
+		public void SetBufferSize(
+			int bufferSize)
+		{
+			_bufferSize = bufferSize;
+		}
+
+		public Stream Open(
+			Stream	outStream,
+			string	compressionOID)
+		{
+			return Open(outStream, CmsObjectIdentifiers.Data.Id, compressionOID);
+		}
+
+		public Stream Open(
+			Stream	outStream,
+			string	contentOID,
+			string	compressionOID)
+		{
+			BerSequenceGenerator sGen = new BerSequenceGenerator(outStream);
+
+			sGen.AddObject(CmsObjectIdentifiers.CompressedData);
+
+			//
+			// Compressed Data
+			//
+			BerSequenceGenerator cGen = new BerSequenceGenerator(
+				sGen.GetRawOutputStream(), 0, true);
+
+			// CMSVersion
+			cGen.AddObject(new DerInteger(0));
+
+			// CompressionAlgorithmIdentifier
+			cGen.AddObject(new AlgorithmIdentifier(new DerObjectIdentifier(ZLib)));
+
+			//
+			// Encapsulated ContentInfo
+			//
+			BerSequenceGenerator eiGen = new BerSequenceGenerator(cGen.GetRawOutputStream());
+
+			eiGen.AddObject(new DerObjectIdentifier(contentOID));
+
+			Stream octetStream = CmsUtilities.CreateBerOctetOutputStream(
+				eiGen.GetRawOutputStream(), 0, true, _bufferSize);
+
+			return new CmsCompressedOutputStream(
+				new ZOutputStream(octetStream, JZlib.Z_DEFAULT_COMPRESSION), sGen, cGen, eiGen);
+		}
+
+		private class CmsCompressedOutputStream
+			: BaseOutputStream
+		{
+			private ZOutputStream _out;
+			private BerSequenceGenerator _sGen;
+			private BerSequenceGenerator _cGen;
+			private BerSequenceGenerator _eiGen;
+
+			internal CmsCompressedOutputStream(
+				ZOutputStream			outStream,
+				BerSequenceGenerator	sGen,
+				BerSequenceGenerator	cGen,
+				BerSequenceGenerator	eiGen)
+			{
+				_out = outStream;
+				_sGen = sGen;
+				_cGen = cGen;
+				_eiGen = eiGen;
+			}
+
+			public override void WriteByte(
+				byte b)
+			{
+				_out.WriteByte(b);
+			}
+
+			public override void Write(
+				byte[]	bytes,
+				int		off,
+				int		len)
+			{
+				_out.Write(bytes, off, len);
+			}
+
+			public override void Close()
+			{
+				_out.Close();
+
+				// TODO Parent context(s) should really be be closed explicitly
+
+				_eiGen.Close();
+				_cGen.Close();
+				_sGen.Close();
+				base.Close();
+			}
+		}
+	}
+}