//-----------------------------------------------------------------------
//
// Copyright (c) Andrew Arnott. All rights reserved.
//
//-----------------------------------------------------------------------
namespace DotNetOAuth.Messaging {
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.Serialization;
using System.Xml;
using System.Xml.Linq;
///
/// An XmlReader-looking object that actually reads from a dictionary.
///
internal class DictionaryXmlReader {
///
/// Creates an XmlReader that reads data out of a dictionary instead of XML.
///
/// The name of the root XML element.
/// The field sorter so that the XmlReader generates xml elements in the order required by the .
/// The dictionary to read data from.
/// The XmlReader that will read the data out of the given dictionary.
internal static XmlReader Create(XName rootElement, IComparer fieldSorter, IDictionary fields) {
if (rootElement == null) {
throw new ArgumentNullException("rootElement");
}
if (fieldSorter == null) {
throw new ArgumentNullException("fieldSorter");
}
if (fields == null) {
throw new ArgumentNullException("fields");
}
return CreateRoundtripReader(rootElement, fieldSorter, fields);
}
///
/// Creates an that will read values out of a dictionary.
///
/// The surrounding root XML element to generate.
/// The field sorter so that the XmlReader generates xml elements in the order required by the .
/// The dictionary to list values from.
/// The generated .
private static XmlReader CreateRoundtripReader(XName rootElement, IComparer fieldSorter, IDictionary fields) {
Debug.Assert(rootElement != null, "rootElement == null");
Debug.Assert(fieldSorter != null, "fieldSorter == null");
Debug.Assert(fields != null, "fields == null");
MemoryStream stream = new MemoryStream();
XmlWriter writer = XmlWriter.Create(stream);
SerializeDictionaryToXml(writer, rootElement, fieldSorter, fields);
writer.Flush();
stream.Seek(0, SeekOrigin.Begin);
// For debugging purposes.
StreamReader sr = new StreamReader(stream);
Trace.WriteLine(sr.ReadToEnd());
stream.Seek(0, SeekOrigin.Begin);
return XmlReader.Create(stream);
}
///
/// Writes out the values in a dictionary as XML.
///
/// The to write out the XML to.
/// The name of the root element to use to surround the dictionary values.
/// The field sorter so that the XmlReader generates xml elements in the order required by the .
/// The dictionary with values to serialize.
private static void SerializeDictionaryToXml(XmlWriter writer, XName rootElement, IComparer fieldSorter, IDictionary fields) {
Debug.Assert(writer != null, "writer == null");
Debug.Assert(rootElement != null, "rootElement == null");
Debug.Assert(fields != null, "fields == null");
writer.WriteStartElement(rootElement.LocalName, rootElement.NamespaceName);
foreach (var pair in fields.OrderBy(pair => pair.Key, fieldSorter)) {
writer.WriteStartElement(pair.Key, rootElement.NamespaceName);
writer.WriteValue(pair.Value);
writer.WriteEndElement();
}
writer.WriteEndElement();
}
}
}