1 /*
2 PowerShell 6.0
3
4 Copyright (c) Microsoft Corporation. All rights reserved.
5
6 All rights reserved.
7
8 MIT License
9
10 Permission is hereby granted, free of charge, to any person obtaining a copy
11 of this software and associated documentation files (the ""Software""), to deal
12 in the Software without restriction, including without limitation the rights
13 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14 copies of the Software, and to permit persons to whom the Software is
15 furnished to do so, subject to the following conditions:
16
17 The above copyright notice and this permission notice shall be included in all
18 copies or substantial portions of the Software.
19
20 THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26 SOFTWARE.
27 */
28
29 /********************************************************************++
30 Copyright (c) Microsoft Corporation. All rights reserved.
31 --********************************************************************/
32
33 using System;
34 using System.IO;
35 using System.Management.Automation;
36 using System.Xml;
37
38
39 using Dbg = System.Management.Automation.Diagnostics;
40
41
42
43 namespace Microsoft.PowerShell
44 {
45 /// <summary>
46 ///
47 /// Wraps Hitesh's xml serializer in such a way that it will select the proper serializer based on the data
48 /// format.
49 ///
50 /// </summary>
51
52 internal class Serialization
53 {
54 /// <summary>
55 ///
56 /// Describes the format of the data streamed between minishells, e.g. the allowed arguments to the minishell
57 /// -outputformat and -inputformat command line parameters.
58 ///
59 /// </summary>
60
61 internal enum DataFormat
62 {
63 /// <summary>
64 ///
65 /// text format -- i.e. stream text just as out-default would display it.
66 ///
67 /// </summary>
68
69 Text = 0,
70
71 /// <summary>
72 ///
73 /// XML-serialized format
74 ///
75 /// </summary>
76
77 XML = 0xFF,
78
79 /// <summary>
80 ///
81 /// Indicates that the data should be discarded instead of processed.
82 ///
83 /// </summary>
84 None = 2
85 }
86
87
88
89 protected
Serialization(DataFormat dataFormat, string streamName)90 Serialization(DataFormat dataFormat, string streamName)
91 {
92 Dbg.Assert(!string.IsNullOrEmpty(streamName), "stream needs a name");
93
94 format = dataFormat;
95 this.streamName = streamName;
96 }
97
98
99
100 protected static string XmlCliTag = "#< CLIXML";
101
102 protected string streamName;
103 protected DataFormat format;
104 }
105
106
107
108 internal
109 class WrappedSerializer : Serialization
110 {
111 internal
WrappedSerializer(DataFormat dataFormat, string streamName, TextWriter output)112 WrappedSerializer(DataFormat dataFormat, string streamName, TextWriter output)
113 :
114 base(dataFormat, streamName)
115 {
116 Dbg.Assert(output != null, "output should have a value");
117
118 textWriter = output;
119 switch (format)
120 {
121 case DataFormat.XML:
122 XmlWriterSettings settings = new XmlWriterSettings();
123 settings.CheckCharacters = false;
124 settings.OmitXmlDeclaration = true;
125 _xmlWriter = XmlWriter.Create(textWriter, settings);
126 _xmlSerializer = new Serializer(_xmlWriter);
127 break;
128 case DataFormat.Text:
129 default:
130 // do nothing; we'll just write to the TextWriter
131 // or discard it.
132
133 break;
134 }
135 }
136
137
138
139 internal
140 void
Serialize(object o)141 Serialize(object o)
142 {
143 Serialize(o, this.streamName);
144 }
145
146 internal
147 void
Serialize(object o, string streamName)148 Serialize(object o, string streamName)
149 {
150 switch (format)
151 {
152 case DataFormat.None:
153 break;
154 case DataFormat.XML:
155 if (_firstCall)
156 {
157 _firstCall = false;
158 textWriter.WriteLine(Serialization.XmlCliTag);
159 }
160 _xmlSerializer.Serialize(o, streamName);
161 break;
162 case DataFormat.Text:
163 default:
164 textWriter.Write(o.ToString());
165 break;
166 }
167 }
168
169
170 internal
171 void
End()172 End()
173 {
174 switch (format)
175 {
176 case DataFormat.None:
177 // do nothing
178 break;
179
180 case DataFormat.XML:
181 _xmlSerializer.Done();
182 _xmlSerializer = null;
183 break;
184
185 case DataFormat.Text:
186 default:
187 // do nothing
188
189 break;
190 }
191 }
192
193
194 internal TextWriter textWriter;
195 private XmlWriter _xmlWriter;
196 private Serializer _xmlSerializer;
197 private bool _firstCall = true;
198 }
199
200
201
202 internal
203 class WrappedDeserializer : Serialization
204 {
205 internal
WrappedDeserializer(DataFormat dataFormat, string streamName, TextReader input)206 WrappedDeserializer(DataFormat dataFormat, string streamName, TextReader input)
207 :
208 base(dataFormat, streamName)
209 {
210 Dbg.Assert(input != null, "input should have a value");
211
212 // If the data format is none - do nothing...
213 if (dataFormat == DataFormat.None)
214 return;
215
216 textReader = input;
217 _firstLine = textReader.ReadLine();
218 if (String.Compare(_firstLine, Serialization.XmlCliTag, StringComparison.OrdinalIgnoreCase) == 0)
219 {
220 // format should be XML
221
222 dataFormat = DataFormat.XML;
223 }
224
225 switch (format)
226 {
227 case DataFormat.XML:
228 _xmlReader = XmlReader.Create(textReader, new XmlReaderSettings { XmlResolver = null });
229 _xmlDeserializer = new Deserializer(_xmlReader);
230 break;
231 case DataFormat.Text:
232 default:
233 // do nothing; we'll just read from the TextReader
234
235 break;
236 }
237 }
238
239
240
241 internal
242 object
Deserialize()243 Deserialize()
244 {
245 object o;
246 switch (format)
247 {
248 case DataFormat.None:
249 _atEnd = true;
250 return null;
251
252 case DataFormat.XML:
253 string unused;
254 o = _xmlDeserializer.Deserialize(out unused);
255 break;
256
257 case DataFormat.Text:
258 default:
259 if (_atEnd)
260 {
261 return null;
262 }
263 if (_firstLine != null)
264 {
265 o = _firstLine;
266 _firstLine = null;
267 }
268 else
269 {
270 o = textReader.ReadLine();
271 if (o == null)
272 {
273 _atEnd = true;
274 }
275 }
276 break;
277 }
278 return o;
279 }
280
281
282
283 internal
284 bool
285 AtEnd
286 {
287 get
288 {
289 bool result = false;
290 switch (format)
291 {
292 case DataFormat.None:
293 _atEnd = true;
294 result = true;
295 break;
296
297 case DataFormat.XML:
298 result = _xmlDeserializer.Done();
299 break;
300
301 case DataFormat.Text:
302 default:
303 result = _atEnd;
304 break;
305 }
306 return result;
307 }
308 }
309
310
311
312 internal
313 void
End()314 End()
315 {
316 switch (format)
317 {
318 case DataFormat.None:
319 case DataFormat.XML:
320 case DataFormat.Text:
321 default:
322 // do nothing
323
324 break;
325 }
326 }
327
328
329 internal TextReader textReader;
330 private XmlReader _xmlReader;
331 private Deserializer _xmlDeserializer;
332 private string _firstLine;
333 private bool _atEnd;
334 }
335 } // namespace
336 /*http://example.com*/
337