using System;
using System.Collections.Generic;
using System.Text;
using Ionic.Zip;
using System.IO;
using System.Net;
using System.Xml;
using Microsoft.ReportingServices.Interfaces;
using Microsoft.ReportingServices.ReportRendering;
using Microsoft.ReportingServices.Rendering.CsvRenderer;
using Microsoft.ReportingServices.Rendering.ExcelRenderer;
using Microsoft.ReportingServices.Rendering.ImageRenderer;
namespace ZipRenderer
{
public class ZipRenderingProvider : IRenderingExtension
{
// The built-in renderers we're gonna use later.
private PdfReport pdfRenderer;
private CsvReport csvRenderer;
private ExcelRenderer excelRenderer;
// Stream to capture the result of the renderer later.
private CreateAndRegisterStreamStream intermediateStream;
private List<CreateAndRegisterStreamStream> intermediateStreams;
public ZipRenderingProvider()
{
csvRenderer = new CsvReport();
// Initialize the renderers.
excelRenderer = new ExcelRenderer();
pdfRenderer = new PdfReport();
intermediateStreams = new List<CreateAndRegisterStreamStream>();
}
#region IRenderingExtension Members
void IRenderingExtension.GetRenderingResource(CreateAndRegisterStream createAndRegisterStreamCallback, System.Collections.Specialized.NameValueCollection deviceInfo)
{
excelRenderer.GetRenderingResource(createAndRegisterStreamCallback, deviceInfo);
}
bool IRenderingExtension.Render(Microsoft.ReportingServices.ReportRendering.Report report, System.Collections.Specialized.NameValueCollection reportServerParameters, System.Collections.Specialized.NameValueCollection deviceInfo, System.Collections.Specialized.NameValueCollection clientCapabilities, EvaluateHeaderFooterExpressions evaluateHeaderFooterExpressions, CreateAndRegisterStream createAndRegisterStream)
{
string sessionID = reportServerParameters["SessionID"];
if (sessionID == null)
{
return RenderBuiltIn(report, reportServerParameters, deviceInfo, clientCapabilities, evaluateHeaderFooterExpressions, createAndRegisterStream);
}
else
{
return RenderReportViewer(report, reportServerParameters, deviceInfo, clientCapabilities, evaluateHeaderFooterExpressions, createAndRegisterStream);
}
}
bool IRenderingExtension.RenderStream(string streamName, Microsoft.ReportingServices.ReportRendering.Report report, System.Collections.Specialized.NameValueCollection reportServerParameters, System.Collections.Specialized.NameValueCollection deviceInfo, System.Collections.Specialized.NameValueCollection clientCapabilities, EvaluateHeaderFooterExpressions evaluateHeaderFooterExpressions, CreateAndRegisterStream createAndRegisterStream)
{
return false;
}
#endregion
bool RenderReportViewer(Microsoft.ReportingServices.ReportRendering.Report report, System.Collections.Specialized.NameValueCollection reportServerParameters, System.Collections.Specialized.NameValueCollection deviceInfo, System.Collections.Specialized.NameValueCollection clientCapabilities, EvaluateHeaderFooterExpressions evaluateHeaderFooterExpressions, CreateAndRegisterStream createAndRegisterStream)
{
string ReportFormat = deviceInfo["ZippedReportFormat"];
if (ReportFormat == null)
{
throw new System.Configuration.ConfigurationErrorsException("Missing <ZippedReportFormat> configuration entry in <DeviceInfo>");
}
string ReportExtension = deviceInfo["ZippedReportExtension"];
//THIS FAILS IF SessionID IS NOT SPECIFIED(AS IN: RUN FROM A SUBSCRIPTION OR THE LIKE.)
//CHECK FIRST, IF NO SessionID THEN RUN THROUGH WEB SERVICE OR HTTP REQUEST ON REPORTSERVER ( Pass parameters, deviceinfo etc. through..)
//TODO: RECHECK the ExcelRenderer possibility.. Re-executing an entire report sucks - should enable caching for the reports in question in that case.
string strUri = String.Concat("http://localhost/Reports/Reserved.ReportViewerWebControl.axd",
"?ReportSession=", reportServerParameters["SessionID"],
"&FileName=", report.Name,
"&ControlId=", Guid.Empty,
"&Culture=", System.Globalization.CultureInfo.CurrentCulture.LCID.ToString(System.Globalization.CultureInfo.InvariantCulture),
"&UICulture=", System.Globalization.CultureInfo.CurrentUICulture.LCID.ToString(System.Globalization.CultureInfo.InvariantCulture),
"&ReportStack=1",
"&OpType=Export",
"&ContentDisposition=OnlyHtmlInline",
"&Format=", ReportFormat);
// A buffer for copying the intermediateStream to the outputStream
// http://stackoverflow.com/questions/230128/best-way-to-copy-between-two-stream-instances-c
byte[] buffer = new byte[32768];
//Output
//streamWriter = new StreamWriter(intermediateStream);
//Input
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(strUri);
//Credentials
request.Credentials = System.Net.CredentialCache.DefaultCredentials;
//Output
HttpWebResponse response;
try
{
response = (HttpWebResponse)request.GetResponse();
}
catch (Exception ex)
{
throw new System.Configuration.ConfigurationErrorsException("Internal error while processing the request. There may be a problem in configuration e.g. an invalid <ZippedReportFormat> entry.", ex);
}
//Input
using (Stream inputStream = response.GetResponseStream())
{
//prepare outputstream. Contents of the zipstream will be written here.
Stream outputStream = createAndRegisterStream(report.Name, "zip", Encoding.UTF8, "application/zip", true, StreamOper.CreateAndRegister); //this._willSeek, this._operation);
using (MemoryStream outputMemoryStream = new MemoryStream())
{
//Create a Zip output and tell it to keep the provided stream open - we use it outside the using clause
using (ZipOutputStream zipOutput = new ZipOutputStream(outputMemoryStream, true))
{
zipOutput.PutNextEntry(report.Name + "." + ReportExtension);
// Do the actual copying.
// While the streams are copying, think of the
// possibilities: this is the place where you would
// be able to fire up that external PDF library
// and add the PDF background!
// But don't think too long, cause' computers are pretty fast
// these days and will probably have finished copying this
// stream by the time you even got to start reading.
while (true)
{
int read = inputStream.Read(buffer, 0, buffer.Length);
if (read <= 0)
{
break;
}
zipOutput.Write(buffer, 0, read);
}
}
//Write zip contents to the output
outputMemoryStream.WriteTo(outputStream);
}
}
// Return false, because:
// "A return value of true indicates that any properties added
// to the report object model are saved into the intermediate format."
// http://msdn.microsoft.com/en-us/library/microsoft.reportingservices.reportrendering.irenderingextension.render(SQL.90).aspx
// ... and we're obviously not doing that, are we? Are we? ARE WE?
return false;
}
bool RenderBuiltIn(Microsoft.ReportingServices.ReportRendering.Report report, System.Collections.Specialized.NameValueCollection reportServerParameters, System.Collections.Specialized.NameValueCollection deviceInfo, System.Collections.Specialized.NameValueCollection clientCapabilities, EvaluateHeaderFooterExpressions evaluateHeaderFooterExpressions, CreateAndRegisterStream createAndRegisterStream)
{
string ReportFormat = deviceInfo["ZippedReportFormat"];
if (ReportFormat == null)
{
throw new System.Configuration.ConfigurationErrorsException("Missing <ZippedReportFormat> configuration entry in <DeviceInfo>");
}
switch(ReportFormat)
{
case "EXCEL":
return RenderExcel(report, reportServerParameters, deviceInfo, clientCapabilities, evaluateHeaderFooterExpressions, createAndRegisterStream);
case "CSV":
return RenderCSV(report, reportServerParameters, deviceInfo, clientCapabilities, evaluateHeaderFooterExpressions, createAndRegisterStream);
case "PDF":
return RenderPDF(report, reportServerParameters, deviceInfo, clientCapabilities, evaluateHeaderFooterExpressions, createAndRegisterStream);
default:
return false; //or throw exception?
}
}
// Intermediate CreateAndRegisterStream method that matches the delegate
// Microsoft.ReportingServices.Interfaces.CreateAndRegisterStream
// It will return a reference to a new MemoryStream, so we can get to
// the results of the intermediate render-step later.
public Stream IntermediateCreateAndRegisterStreamExcel(
string name,
string extension,
Encoding encoding,
string mimeType,
bool willSeek,
StreamOper operation)
{
CreateAndRegisterStreamStream crss = new CreateAndRegisterStreamExcel(name, extension, encoding, mimeType, willSeek, operation);
if (operation == StreamOper.CreateOnly)
intermediateStreams.Add(crss);
else
intermediateStream = crss;
return crss.Stream;
}
// Intermediate CreateAndRegisterStream method that matches the delegate
// Microsoft.ReportingServices.Interfaces.CreateAndRegisterStream
// It will return a reference to a new MemoryStream, so we can get to
// the results of the intermediate render-step later.
public Stream IntermediateCreateAndRegisterStream(
string name,
string extension,
Encoding encoding,
string mimeType,
bool willSeek,
StreamOper operation)
{
// Create and return a new MemoryStream,
// which will contain the results of the PDF renderer.
CreateAndRegisterStreamStream crss = new CreateAndRegisterStreamOther(name, extension, encoding, mimeType, willSeek, operation);
intermediateStream = crss;
return crss.Stream;
}
bool RenderExcel(Microsoft.ReportingServices.ReportRendering.Report report, System.Collections.Specialized.NameValueCollection reportServerParameters, System.Collections.Specialized.NameValueCollection deviceInfo, System.Collections.Specialized.NameValueCollection clientCapabilities, EvaluateHeaderFooterExpressions evaluateHeaderFooterExpressions, CreateAndRegisterStream createAndRegisterStream)
{
excelRenderer.SetConfiguration(this.configuration);
// Let the built-in renderer do the hard work!
// After this call, the rendered file will be in the intermediateStream.
// We're just passing-through the Render parameters.
excelRenderer.Render(
report,
reportServerParameters,
deviceInfo,
clientCapabilities,
evaluateHeaderFooterExpressions,
// This is the tricky part: get a delegate method to send a stream to the
// PDF renderer, while keeping a reference to the same stream.
// (See the IntermediateCreateAndRegisterStream method above).
new CreateAndRegisterStream(IntermediateCreateAndRegisterStreamExcel)
);
// This is the actual Stream which Reporting Services uses
// to send the result to the end-user.
//Stream outputStream =
// createAndRegisterStream(_name, _extension, _encoding, _mimeType, _willSeek, _operation);
// It took us some time to figure out why the intermediateStream,
// while having a length, always returned an empty result upon
// reading from it. Well, after writing to the MemoryStream,
// the PDF renderer doesn't reset the stream's position, so
// we have to.
intermediateStream.Stream.Position = 0;
// A buffer for copying the intermediateStream to the outputStream
// http://stackoverflow.com/questions/230128/best-way-to-copy-between-two-stream-instances-c
byte[] buffer = new byte[32768];
Stream outputStream = createAndRegisterStream(report.Name, "zip", Encoding.UTF8, "application/zip", intermediateStream.WillSeek, intermediateStream.Operation);
using (MemoryStream outputMemoryStream = new MemoryStream())
{
//Create a Zip output and tell it to keep the provided stream open - we use it outside the using clause
using (ZipOutputStream zipOutput = new ZipOutputStream(outputMemoryStream, true))
{
//Read zip deviceinfo
try
{
if (deviceInfo["CompressionLevel"] != null)
zipOutput.CompressionLevel = (Ionic.Zlib.CompressionLevel)Enum.Parse(typeof(Ionic.Zlib.CompressionLevel), deviceInfo["CompressionLevel"], true);
if (deviceInfo["CompressionMethod"] != null)
zipOutput.CompressionMethod = (Ionic.Zip.CompressionMethod)Enum.Parse(typeof(Ionic.Zip.CompressionMethod), deviceInfo["CompressionMethod"], true);
if (deviceInfo["Strategy"] != null)
zipOutput.Strategy = (Ionic.Zlib.CompressionStrategy)Enum.Parse(typeof(Ionic.Zlib.CompressionStrategy), deviceInfo["Strategy"], true);
if (deviceInfo["Comment"] != null)
zipOutput.Comment = deviceInfo["Comment"];
if (deviceInfo["EnableZip64"] != null)
zipOutput.EnableZip64 = (Ionic.Zip.Zip64Option)Enum.Parse(typeof(Ionic.Zip.Zip64Option), deviceInfo["EnableZip64"], true);
if (deviceInfo["IgnoreCase"] != null)
zipOutput.IgnoreCase = Boolean.Parse(deviceInfo["IgnoreCase"]);
if (deviceInfo["Encryption"] != null)
zipOutput.Encryption = (Ionic.Zip.EncryptionAlgorithm)Enum.Parse(typeof(Ionic.Zip.EncryptionAlgorithm), deviceInfo["Encryption"], true);
if (deviceInfo["Password"] != null)
zipOutput.Password = deviceInfo["Password"];
}
catch (Exception e)
{
throw new System.Configuration.ConfigurationErrorsException("Invalid DeviceInfo configuration value", e);
}
zipOutput.PutNextEntry(intermediateStream.Name + "." + intermediateStream.Extension);
// Do the actual copying.
// While the streams are copying, think of the
// possibilities: this is the place where you would
// be able to fire up that external PDF library
// and add the PDF background!
// But don't think too long, cause' computers are pretty fast
// these days and will probably have finished copying this
// stream by the time you even got to start reading.
while (true)
{
int read = this.intermediateStream.Stream.Read(buffer, 0, buffer.Length);
if (read <= 0)
{
break;
}
zipOutput.Write(buffer, 0, read);
}
}
//Write zip contents to the output
outputMemoryStream.WriteTo(outputStream);
}
// Be nice and release some hard-needed resources.
intermediateStream.CloseStream();
// Close other streams, too.
//(What happens with these? I don't know. I figure these streams are written to by the built-in renderer, then copied to the main stream.)
foreach (CreateAndRegisterStreamStream s in intermediateStreams)
s.CloseStream();
intermediateStreams.Clear();
// Return false, because:
// "A return value of true indicates that any properties added
// to the report object model are saved into the intermediate format."
// http://msdn.microsoft.com/en-us/library/microsoft.reportingservices.reportrendering.irenderingextension.render(SQL.90).aspx
// ... and we're obviously not doing that, are we? Are we? ARE WE?
return false;
}
bool RenderCSV(Microsoft.ReportingServices.ReportRendering.Report report, System.Collections.Specialized.NameValueCollection reportServerParameters, System.Collections.Specialized.NameValueCollection deviceInfo, System.Collections.Specialized.NameValueCollection clientCapabilities, EvaluateHeaderFooterExpressions evaluateHeaderFooterExpressions, CreateAndRegisterStream createAndRegisterStream)
{
csvRenderer.SetConfiguration(this.configuration);
// Let the built-in PDF renderer do the hard work!
// After this call, the rendered PDF will be in the intermediateStream.
// We're just passing-through the Render parameters.
csvRenderer.Render(
report,
reportServerParameters,
deviceInfo,
clientCapabilities,
evaluateHeaderFooterExpressions,
// This is the tricky part: get a delegate method to send a stream to the
// PDF renderer, while keeping a reference to the same stream.
// (See the IntermediateCreateAndRegisterStream method above).
new CreateAndRegisterStream(IntermediateCreateAndRegisterStream)
);
// This is the actual Stream which Reporting Services uses
// to send the result to the end-user.
//Stream outputStream =
// createAndRegisterStream(_name, _extension, _encoding, _mimeType, _willSeek, _operation);
// It took us some time to figure out why the intermediateStream,
// while having a length, always returned an empty result upon
// reading from it. Well, after writing to the MemoryStream,
// the PDF renderer doesn't reset the stream's position, so
// we have to.
intermediateStream.Stream.Position = 0;
// A buffer for copying the intermediateStream to the outputStream
// http://stackoverflow.com/questions/230128/best-way-to-copy-between-two-stream-instances-c
byte[] buffer = new byte[32768];
Stream outputStream = createAndRegisterStream(report.Name, "zip", Encoding.UTF8, "application/zip", intermediateStream.WillSeek, intermediateStream.Operation);
using (MemoryStream outputMemoryStream = new MemoryStream())
{
//Create a Zip output and tell it to keep the provided stream open - we use it outside the using clause
using (ZipOutputStream zipOutput = new ZipOutputStream(outputMemoryStream, true))
{
//Read zip deviceinfo
try
{
if (deviceInfo["CompressionLevel"] != null)
zipOutput.CompressionLevel = (Ionic.Zlib.CompressionLevel)Enum.Parse(typeof(Ionic.Zlib.CompressionLevel), deviceInfo["CompressionLevel"], true);
if (deviceInfo["CompressionMethod"] != null)
zipOutput.CompressionMethod = (Ionic.Zip.CompressionMethod)Enum.Parse(typeof(Ionic.Zip.CompressionMethod), deviceInfo["CompressionMethod"], true);
if (deviceInfo["Strategy"] != null)
zipOutput.Strategy = (Ionic.Zlib.CompressionStrategy)Enum.Parse(typeof(Ionic.Zlib.CompressionStrategy), deviceInfo["Strategy"], true);
if (deviceInfo["Comment"] != null)
zipOutput.Comment = deviceInfo["Comment"];
if (deviceInfo["EnableZip64"] != null)
zipOutput.EnableZip64 = (Ionic.Zip.Zip64Option)Enum.Parse(typeof(Ionic.Zip.Zip64Option), deviceInfo["EnableZip64"], true);
if (deviceInfo["IgnoreCase"] != null)
zipOutput.IgnoreCase = Boolean.Parse(deviceInfo["IgnoreCase"]);
if (deviceInfo["Encryption"] != null)
zipOutput.Encryption = (Ionic.Zip.EncryptionAlgorithm)Enum.Parse(typeof(Ionic.Zip.EncryptionAlgorithm), deviceInfo["Encryption"], true);
if (deviceInfo["Password"] != null)
zipOutput.Password = deviceInfo["Password"];
}
catch (Exception e)
{
throw new System.Configuration.ConfigurationErrorsException("Invalid DeviceInfo configuration value", e);
}
zipOutput.PutNextEntry(intermediateStream.Name + "." + intermediateStream.Extension);
// Do the actual copying.
// While the streams are copying, think of the
// possibilities: this is the place where you would
// be able to fire up that external PDF library
// and add the PDF background!
// But don't think too long, cause' computers are pretty fast
// these days and will probably have finished copying this
// stream by the time you even got to start reading.
while (true)
{
int read = this.intermediateStream.Stream.Read(buffer, 0, buffer.Length);
if (read <= 0)
{
break;
}
zipOutput.Write(buffer, 0, read);
}
}
//Write zip contents to the output
outputMemoryStream.WriteTo(outputStream);
}
// Be nice and release some hard-needed resources.
intermediateStream.CloseStream();
// Close other streams, too.
//(What happens with these? I don't know. I figure these streams are written to by the built-in renderer, then copied to the main stream.)
foreach (CreateAndRegisterStreamStream s in intermediateStreams)
s.CloseStream();
intermediateStreams.Clear();
// Return false, because:
// "A return value of true indicates that any properties added
// to the report object model are saved into the intermediate format."
// http://msdn.microsoft.com/en-us/library/microsoft.reportingservices.reportrendering.irenderingextension.render(SQL.90).aspx
// ... and we're obviously not doing that, are we? Are we? ARE WE?
return false;
}
bool RenderPDF(Microsoft.ReportingServices.ReportRendering.Report report, System.Collections.Specialized.NameValueCollection reportServerParameters, System.Collections.Specialized.NameValueCollection deviceInfo, System.Collections.Specialized.NameValueCollection clientCapabilities, EvaluateHeaderFooterExpressions evaluateHeaderFooterExpressions, CreateAndRegisterStream createAndRegisterStream)
{
pdfRenderer.SetConfiguration(this.configuration);
// Let the built-in PDF renderer do the hard work!
// After this call, the rendered PDF will be in the intermediateStream.
// We're just passing-through the Render parameters.
pdfRenderer.Render(
report,
reportServerParameters,
deviceInfo,
clientCapabilities,
evaluateHeaderFooterExpressions,
// This is the tricky part: get a delegate method to send a stream to the
// PDF renderer, while keeping a reference to the same stream.
// (See the IntermediateCreateAndRegisterStream method above).
new CreateAndRegisterStream(IntermediateCreateAndRegisterStream)
);
// This is the actual Stream which Reporting Services uses
// to send the result to the end-user.
//Stream outputStream =
// createAndRegisterStream(_name, _extension, _encoding, _mimeType, _willSeek, _operation);
// It took us some time to figure out why the intermediateStream,
// while having a length, always returned an empty result upon
// reading from it. Well, after writing to the MemoryStream,
// the PDF renderer doesn't reset the stream's position, so
// we have to.
intermediateStream.Stream.Position = 0;
// A buffer for copying the intermediateStream to the outputStream
// http://stackoverflow.com/questions/230128/best-way-to-copy-between-two-stream-instances-c
byte[] buffer = new byte[32768];
Stream outputStream = createAndRegisterStream(report.Name, "zip", Encoding.UTF8, "application/zip", intermediateStream.WillSeek, intermediateStream.Operation);
using (MemoryStream outputMemoryStream = new MemoryStream())
{
//Create a Zip output and tell it to keep the provided stream open - we use it outside the using clause
using (ZipOutputStream zipOutput = new ZipOutputStream(outputMemoryStream, true))
{
//Read zip deviceinfo
try
{
if (deviceInfo["CompressionLevel"] != null)
zipOutput.CompressionLevel = (Ionic.Zlib.CompressionLevel)Enum.Parse(typeof(Ionic.Zlib.CompressionLevel), deviceInfo["CompressionLevel"], true);
if (deviceInfo["CompressionMethod"] != null)
zipOutput.CompressionMethod = (Ionic.Zip.CompressionMethod)Enum.Parse(typeof(Ionic.Zip.CompressionMethod), deviceInfo["CompressionMethod"], true);
if (deviceInfo["Strategy"] != null)
zipOutput.Strategy = (Ionic.Zlib.CompressionStrategy)Enum.Parse(typeof(Ionic.Zlib.CompressionStrategy), deviceInfo["Strategy"], true);
if (deviceInfo["Comment"] != null)
zipOutput.Comment = deviceInfo["Comment"];
if (deviceInfo["EnableZip64"] != null)
zipOutput.EnableZip64 = (Ionic.Zip.Zip64Option)Enum.Parse(typeof(Ionic.Zip.Zip64Option), deviceInfo["EnableZip64"], true);
if (deviceInfo["IgnoreCase"] != null)
zipOutput.IgnoreCase = Boolean.Parse(deviceInfo["IgnoreCase"]);
if (deviceInfo["Encryption"] != null)
zipOutput.Encryption = (Ionic.Zip.EncryptionAlgorithm)Enum.Parse(typeof(Ionic.Zip.EncryptionAlgorithm), deviceInfo["Encryption"], true);
if (deviceInfo["Password"] != null)
zipOutput.Password = deviceInfo["Password"];
}
catch (Exception e)
{
throw new System.Configuration.ConfigurationErrorsException("Invalid DeviceInfo configuration value", e);
}
zipOutput.PutNextEntry(intermediateStream.Name + "." + intermediateStream.Extension);
// Do the actual copying.
// While the streams are copying, think of the
// possibilities: this is the place where you would
// be able to fire up that external PDF library
// and add the PDF background!
// But don't think too long, cause' computers are pretty fast
// these days and will probably have finished copying this
// stream by the time you even got to start reading.
while (true)
{
int read = this.intermediateStream.Stream.Read(buffer, 0, buffer.Length);
if (read <= 0)
{
break;
}
zipOutput.Write(buffer, 0, read);
}
}
//Write zip contents to the output
outputMemoryStream.WriteTo(outputStream);
}
// Be nice and release some hard-needed resources.
intermediateStream.CloseStream();
// Close other streams, too.
//(What happens with these? I don't know. I figure these streams are written to by the built-in renderer, then copied to the main stream.)
foreach (CreateAndRegisterStreamStream s in intermediateStreams)
s.CloseStream();
intermediateStreams.Clear();
// Return false, because:
// "A return value of true indicates that any properties added
// to the report object model are saved into the intermediate format."
// http://msdn.microsoft.com/en-us/library/microsoft.reportingservices.reportrendering.irenderingextension.render(SQL.90).aspx
// ... and we're obviously not doing that, are we? Are we? ARE WE?
return false;
}
#region IExtension Members
string IExtension.LocalizedName
{
get { return description; }
}
private string description = "Zipped";
private string configuration;
/// <summary>
/// Process XML data stored in the configuration file
/// </summary>
/// <param name="configuration">The XML string from the configuration file that contains extension configuration data.</param>
void IExtension.SetConfiguration(string configuration)
{
this.configuration = configuration;
// Create the document and load the Configuration element
XmlDocument doc = new XmlDocument();
try
{
// Creates the XML reader from the stream
// and moves it to the correct node
using (StringReader m_srdr = new StringReader(configuration))
{
using (XmlReader m_xrdr = XmlReader.Create(m_srdr))
{
m_xrdr.MoveToContent();
doc.LoadXml(m_xrdr.ReadOuterXml());
}
}
if (doc.DocumentElement.Name == "DeviceInfo")
{
foreach (XmlNode child in doc.DocumentElement.ChildNodes)
{
if (child.Name == "ZipExtensionDescription")
{
description = child.InnerText;
break;
}
}
}
//(Example)
//// For each printer in the configuration data, add it to the list of printers
//m_printers = new ArrayList();
//if (doc.DocumentElement.Name == "Printers")
//{
// foreach (XmlNode child in doc.DocumentElement.ChildNodes)
// {
// m_printers.Add(child.InnerText);
// }
//}
}
catch (Exception ex)
{
throw new Exception("Failed to retrieve configuration data: " + ex.Message);
}
}
#endregion
}
abstract internal class CreateAndRegisterStreamStream
{
#region Attributes and Properties
string name;
internal string Name
{
get { return name; }
set { name = value; }
}
string extension;
internal string Extension
{
get { return extension; }
set { extension = value; }
}
Encoding encoding;
internal Encoding Encoding
{
get { return encoding; }
set { encoding = value; }
}
string mimeType;
internal string MimeType
{
get { return mimeType; }
set { mimeType = value; }
}
bool willSeek;
internal bool WillSeek
{
get { return willSeek; }
set { willSeek = value; }
}
StreamOper operation;
internal StreamOper Operation
{
get { return operation; }
set { operation = value; }
}
protected Stream stream;
internal Stream Stream
{
get { return stream; }
set { stream = value; }
}
abstract internal void CloseStream();
#endregion
internal CreateAndRegisterStreamStream(string name,
string extension,
Encoding encoding,
string mimeType,
bool willSeek,
StreamOper operation)
{
this.name = name;
this.encoding = encoding;
this.extension = extension;
this.mimeType = mimeType;
this.operation = operation;
this.willSeek = willSeek;
}
}
internal class CreateAndRegisterStreamOther : CreateAndRegisterStreamStream
{
internal CreateAndRegisterStreamOther(string name,
string extension,
Encoding encoding,
string mimeType,
bool willSeek,
StreamOper operation)
: base(name, extension, encoding, mimeType, willSeek, operation)
{
stream = new MemoryStream();
}
override internal void CloseStream()
{
stream.Close();
}
}
internal class CreateAndRegisterStreamExcel : CreateAndRegisterStreamStream
{
internal CreateAndRegisterStreamExcel(string name,
string extension,
Encoding encoding,
string mimeType,
bool willSeek,
StreamOper operation)
: base(name, extension, encoding, mimeType, willSeek, operation)
{
stream = new UnclosableMemoryStream();
}
override internal void CloseStream()
{
((UnclosableMemoryStream)stream).AllowClose = true;
stream.Close();
}
}
}