2 // XmlMtomDictionaryWriter.cs
5 // Atsushi Enomoto <atsushi@ximian.com>
7 // Copyright (C) 2009 Novell, Inc. http://www.novell.com
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 using System.Net.Mime;
35 internal class XmlMtomDictionaryWriter : XmlDictionaryWriter
37 public XmlMtomDictionaryWriter (Stream stream, Encoding encoding, int maxSizeInBytes, string startInfo, string boundary, string startUri, bool writeMessageHeaders, bool ownsStream)
39 writer = new StreamWriter (stream, encoding);
40 max_bytes = maxSizeInBytes;
41 write_headers = writeMessageHeaders;
42 owns_stream = ownsStream;
44 var settings = new XmlWriterSettings ();
45 settings.Encoding = encoding;
46 settings.OmitXmlDeclaration = true;
47 xml_writer_settings = settings;
49 // FIXME: actually it does not likely use ContentType.ToString() but writes those header items by own.
50 // (so that it could generate "start" header dynamically)
51 var c = new ContentType ("multipart/related");
52 c.Parameters ["type"] = "application/xop+xml";
53 c.Boundary = boundary;
54 c.Parameters ["start"] = "<" + startUri + ">";
55 c.Parameters ["start-info"] = startInfo;
59 // constructor arguments
61 XmlWriterSettings xml_writer_settings;
66 ContentType content_type;
73 XmlWriter CreateWriter ()
75 return XmlWriter.Create (writer, xml_writer_settings);
78 public override void Close ()
85 public override void Flush ()
90 public override string LookupPrefix (string namespaceUri)
92 return w.LookupPrefix (namespaceUri);
95 public override void WriteBase64 (byte [] bytes, int start, int length)
98 w.WriteBase64 (bytes, start, length);
101 public override void WriteCData (string text)
107 public override void WriteCharEntity (char c)
110 w.WriteCharEntity (c);
113 public override void WriteChars (char [] buffer, int index, int count)
116 w.WriteChars (buffer, index, count);
119 public override void WriteComment (string comment)
122 w.WriteComment (comment);
125 public override void WriteDocType (string name, string pubid, string sysid, string intSubset)
127 throw new NotSupportedException (); // indeed
130 public override void WriteEndAttribute ()
132 w.WriteEndAttribute ();
135 public override void WriteEndDocument ()
137 w.WriteEndDocument ();
140 public override void WriteEndElement ()
142 w.WriteEndElement ();
144 WriteEndOfMimeSection ();
147 public override void WriteEntityRef (string name)
149 w.WriteEntityRef (name);
152 public override void WriteFullEndElement ()
154 w.WriteFullEndElement ();
156 WriteEndOfMimeSection ();
159 public override void WriteProcessingInstruction (string name, string data)
161 throw new NotSupportedException ();
164 public override void WriteRaw (string raw)
170 public override void WriteRaw (char [] chars, int index, int count)
173 w.WriteRaw (chars, index, count);
176 public override void WriteStartAttribute (string prefix, string localName, string namespaceURI)
179 w.WriteStartAttribute (prefix, localName, namespaceURI);
182 public override void WriteStartDocument ()
185 w.WriteStartDocument ();
188 public override void WriteStartDocument (bool standalone)
191 w.WriteStartDocument (standalone);
194 public override void WriteStartElement (string prefix, string localName, string namespaceURI)
199 WriteStartOfMimeSection ();
201 w.WriteStartElement (prefix, localName, namespaceURI);
205 public override WriteState WriteState {
206 get { return w.WriteState; }
209 public override void WriteString (string text)
215 i1 = text.IndexOf ('\r', i2);
217 w.WriteString (text.Substring (i2, i1 - i2));
218 WriteCharEntity ('\r');
221 w.WriteString (text.Substring (i2));
227 public override void WriteSurrogateCharEntity (char low, char high)
230 w.WriteSurrogateCharEntity (low, high);
233 public override void WriteWhitespace (string text)
236 w.WriteWhitespace (text);
239 public override string XmlLang {
240 get { return w.XmlLang; }
243 public override XmlSpace XmlSpace {
244 get { return w.XmlSpace; }
249 if (w == null && write_headers)
251 if (w == null || w.WriteState == WriteState.Closed || w.WriteState == WriteState.Error)
255 void WriteMimeHeaders ()
257 writer.Write ("MIME-Version: 1.0\r\n");
258 writer.Write ("Content-Type: ");
259 writer.Write (content_type.ToString ());
260 writer.Write ("\r\n\r\n\r\n");
263 void WriteStartOfMimeSection ()
267 // I'm not sure what's the expected behavior of this
268 // strange XmlWriter, but so far - it outputs only one
270 if (section_count > 1)
273 writer.Write ("\r\n");
275 writer.Write (content_type.Boundary);
276 writer.Write ("\r\n");
277 writer.Write ("Content-ID: ");
278 writer.Write (content_type.Parameters ["start"]);
279 writer.Write ("\r\n");
280 writer.Write ("Content-Transfer-Encoding: 8bit\r\n");
281 writer.Write ("Content-Type: application/xop+xml;charset=");
282 writer.Write (xml_writer_settings.Encoding.HeaderName);
283 writer.Write (";type=\"");
284 writer.Write (content_type.Parameters ["start-info"].Replace ("\"", "\\\""));
285 writer.Write ("\"\r\n\r\n");
288 void WriteEndOfMimeSection ()
290 // I'm not sure what's the expected behavior of this
291 // strange XmlWriter, but so far - it outputs only one
293 if (section_count > 1)
296 writer.Write ("\r\n");
298 writer.Write (content_type.Boundary);
299 writer.Write ("--\r\n");