1 //------------------------------------------------------------
2 // Copyright (c) Microsoft Corporation.  All rights reserved.
3 //------------------------------------------------------------
4 namespace System.IdentityModel
5 {
6     using System.Collections;
7     using System.Collections.Generic;
8     using System.Diagnostics;
9     using System.IO;
10     using System.Security.Cryptography;
11     using System.Text;
12     using System.Xml;
13 
14     sealed class CanonicalizationDriver
15     {
16         bool closeReadersAfterProcessing;
17         XmlReader reader;
18         string[] inclusivePrefixes;
19         bool includeComments;
20 
21         public bool CloseReadersAfterProcessing
22         {
23             get { return this.closeReadersAfterProcessing; }
24             set { this.closeReadersAfterProcessing = value; }
25         }
26 
27         public bool IncludeComments
28         {
29             get { return this.includeComments; }
30             set { this.includeComments = value; }
31         }
32 
GetInclusivePrefixes()33         public string[] GetInclusivePrefixes()
34         {
35             return this.inclusivePrefixes;
36         }
37 
Reset()38         public void Reset()
39         {
40             this.reader = null;
41         }
42 
SetInclusivePrefixes(string[] inclusivePrefixes)43         public void SetInclusivePrefixes(string[] inclusivePrefixes)
44         {
45             this.inclusivePrefixes = inclusivePrefixes;
46         }
47 
SetInput(Stream stream)48         public void SetInput(Stream stream)
49         {
50             if (stream == null)
51             {
52                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("stream");
53             }
54             this.reader = XmlReader.Create(stream);
55         }
56 
SetInput(XmlReader reader)57         public void SetInput(XmlReader reader)
58         {
59             if (reader == null)
60             {
61                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("reader");
62             }
63             this.reader = reader;
64         }
65 
GetBytes()66         public byte[] GetBytes()
67         {
68             return GetMemoryStream().ToArray();
69         }
70 
GetMemoryStream()71         public MemoryStream GetMemoryStream()
72         {
73             MemoryStream stream = new MemoryStream();
74             WriteTo(stream);
75             stream.Seek(0, SeekOrigin.Begin);
76             return stream;
77         }
78 
WriteTo(HashAlgorithm hashAlgorithm)79         public void WriteTo(HashAlgorithm hashAlgorithm)
80         {
81             WriteTo(new HashStream(hashAlgorithm));
82         }
83 
WriteTo(Stream canonicalStream)84         public void WriteTo(Stream canonicalStream)
85         {
86             if (this.reader != null)
87             {
88                 XmlDictionaryReader dicReader = this.reader as XmlDictionaryReader;
89                 if ((dicReader != null) && (dicReader.CanCanonicalize))
90                 {
91                     dicReader.MoveToContent();
92                     dicReader.StartCanonicalization(canonicalStream, this.includeComments, this.inclusivePrefixes);
93                     dicReader.Skip();
94                     dicReader.EndCanonicalization();
95                 }
96                 else
97                 {
98                     XmlDictionaryWriter writer = XmlDictionaryWriter.CreateTextWriter(Stream.Null);
99                     if (this.inclusivePrefixes != null)
100                     {
101                         // Add a dummy element at the top and populate the namespace
102                         // declaration of all the inclusive prefixes.
103                         writer.WriteStartElement("a", reader.LookupNamespace(String.Empty));
104                         for (int i = 0; i < this.inclusivePrefixes.Length; ++i)
105                         {
106                             string ns = reader.LookupNamespace(this.inclusivePrefixes[i]);
107                             if (ns != null)
108                             {
109                                 writer.WriteXmlnsAttribute(this.inclusivePrefixes[i], ns);
110                             }
111                         }
112                     }
113                     writer.StartCanonicalization(canonicalStream, this.includeComments, this.inclusivePrefixes);
114                     if (reader is WrappedReader)
115                     {
116                         ((WrappedReader)reader).XmlTokens.GetWriter().WriteTo(writer, new DictionaryManager());
117                     }
118                     else
119                     {
120 
121                         writer.WriteNode(reader, false);
122                     }
123                     writer.Flush();
124                     writer.EndCanonicalization();
125 
126                     if (this.inclusivePrefixes != null)
127                        writer.WriteEndElement();
128 
129                     writer.Close();
130                 }
131                 if (this.closeReadersAfterProcessing)
132                 {
133                     this.reader.Close();
134                 }
135                 this.reader = null;
136             }
137             else
138             {
139                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.NoInputIsSetForCanonicalization)));
140             }
141         }
142     }
143 
144 }
145