diff Pml/RW/PmlXmlRW.cs @ 0:3ab940a0c7a0

Initial commit
author Ivo Smits <Ivo@UCIS.nl>
date Tue, 11 Sep 2012 16:28:53 +0200
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Pml/RW/PmlXmlRW.cs	Tue Sep 11 16:28:53 2012 +0200
@@ -0,0 +1,269 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Xml;
+using System.IO;
+using UCIS.Pml;
+
+namespace UCIS.Pml {
+	public class PmlXmlRW : IPmlRW {
+		private PmlXmlReader pReader;
+		private PmlXmlWriter pWriter;
+
+		public PmlXmlRW(Stream Stream) {
+			pReader = new PmlXmlReader(Stream);
+			pWriter = new PmlXmlWriter(Stream);
+		}
+		public PmlXmlRW(Stream Stream, Encoding Encoding) {
+			pReader = new PmlXmlReader(Stream);
+			pWriter = new PmlXmlWriter(Stream, Encoding);
+		}
+
+		public PmlElement ReadMessage() {
+			return pReader.ReadMessage();
+		}
+
+		public void WriteMessage(PmlElement Message) {
+			pWriter.WriteMessage(Message);
+		}
+	}
+
+	public class PmlXmlWriter : IPmlWriter {
+		private Stream pStream;
+		private XmlWriterSettings pXMLConfig;
+
+		public PmlXmlWriter(Stream Stream, Encoding Encoding) {
+			pXMLConfig = CreateXMLSettings(Encoding);
+
+			pStream = Stream;
+		}
+		public PmlXmlWriter(Stream Stream)
+			: this(Stream, Encoding.UTF8) {
+		}
+
+		private static XmlWriterSettings CreateXMLSettings() {
+			return CreateXMLSettings(null);
+		}
+		private static XmlWriterSettings CreateXMLSettings(Encoding Encoding) {
+			XmlWriterSettings XMLConfig = new XmlWriterSettings();
+			if (Encoding == null) Encoding = Encoding.UTF8;
+			XMLConfig.ConformanceLevel = ConformanceLevel.Document;
+			XMLConfig.NewLineHandling = NewLineHandling.Entitize;
+			XMLConfig.OmitXmlDeclaration = true;
+			XMLConfig.CheckCharacters = true;
+			XMLConfig.Encoding = Encoding;
+			XMLConfig.CloseOutput = false;
+			return XMLConfig;
+		}
+
+		public void WriteMessage(PmlElement Message) {
+			WriteMessageToStream(Message, pStream);
+			pStream.WriteByte(0);
+			pStream.Flush();
+		}
+
+		public static void WriteMessageToFile(PmlElement Message, string Filename) {
+			FileStream F = File.Create(Filename);
+			WriteMessageToStream(Message, F);
+			F.Close();
+		}
+
+		public static void WriteMessageToStream(PmlElement Message, Stream Stream) {
+			WriteMessageToStream(Message, Stream, CreateXMLSettings());
+		}
+
+		public static void WriteMessageToStream(PmlElement Message, Stream Stream, XmlWriterSettings Settings) {
+			XmlWriter Writer = System.Xml.XmlWriter.Create(Stream, Settings);
+			Writer.WriteStartDocument();
+			Writer.WriteStartElement("msg");
+			WriteElementTo(Message, Writer);
+			Writer.WriteEndElement();
+			Writer.WriteEndDocument();
+			Writer.Flush();
+			Writer.Close();
+		}
+
+		private static void WriteElementTo(PmlElement Element, System.Xml.XmlWriter Writer) {
+			switch (Element.Type) {
+				case PmlType.Binary:
+					Writer.WriteAttributeString("type", "binary");
+					byte[] Bytes = Element.ToByteArray();
+					Writer.WriteBase64(Bytes, 0, Bytes.Length);
+					break;
+				case PmlType.Collection:
+					Writer.WriteAttributeString("type", "collection");
+					foreach (PmlElement Child in (PmlCollection)Element) {
+						Writer.WriteStartElement("item");
+						WriteElementTo(Child, Writer);
+						Writer.WriteEndElement();
+					}
+
+					break;
+				case PmlType.Dictionary:
+					Writer.WriteAttributeString("type", "dictionary");
+					foreach (KeyValuePair<string, PmlElement> Child in (PmlDictionary)Element) {
+						Writer.WriteStartElement(Child.Key);
+						WriteElementTo(Child.Value, Writer);
+						Writer.WriteEndElement();
+					}
+
+					break;
+				case PmlType.Integer:
+					Writer.WriteAttributeString("type", "integer");
+					Writer.WriteString(Element.ToString());
+					break;
+				case PmlType.Null:
+					Writer.WriteAttributeString("type", "null");
+					break;
+				case PmlType.String:
+					Writer.WriteAttributeString("type", "string");
+					Writer.WriteString(Element.ToString());
+					break;
+			}
+		}
+	}
+
+	public class PmlXmlReader : IPmlReader {
+		private BinaryReader pReader;
+		private System.Xml.XmlReaderSettings pXMLSettings;
+
+		public PmlXmlReader(Stream Stream)
+			: this(new BinaryReader(Stream)) {
+		}
+
+		public PmlXmlReader(BinaryReader Reader) {
+			pReader = Reader;
+			pXMLSettings = new System.Xml.XmlReaderSettings();
+			pXMLSettings.ConformanceLevel = System.Xml.ConformanceLevel.Document;
+			pXMLSettings.CloseInput = true;
+			pXMLSettings.IgnoreComments = true;
+			pXMLSettings.IgnoreProcessingInstructions = true;
+			pXMLSettings.IgnoreWhitespace = true;
+			pXMLSettings.ValidationType = System.Xml.ValidationType.None;
+			pXMLSettings.ValidationFlags = System.Xml.Schema.XmlSchemaValidationFlags.None;
+			pXMLSettings.CheckCharacters = true;
+		}
+
+		public BinaryReader BaseReader {
+			get { return pReader; }
+			set { pReader = value; }
+		}
+
+		private XmlDocument ReadXMLDocument() {
+			System.Xml.XmlDocument Doc = new System.Xml.XmlDocument();
+			MemoryStream Buffer = default(MemoryStream);
+			System.Xml.XmlReader XMLReader = default(System.Xml.XmlReader);
+			byte B = 0;
+			Buffer = new MemoryStream();
+			do {
+				B = pReader.ReadByte();
+				if (B == 0) break;
+				Buffer.WriteByte(B);
+			}
+			while (true);
+			Buffer.Flush();
+			Buffer.Seek(0, SeekOrigin.Begin);
+
+			XMLReader = System.Xml.XmlReader.Create(Buffer, pXMLSettings);
+			Doc.Load(XMLReader);
+			XMLReader.Close();
+			return Doc;
+		}
+
+		public PmlElement ReadMessage() {
+			System.Xml.XmlDocument Doc = default(System.Xml.XmlDocument);
+			Doc = ReadXMLDocument();
+			if (Doc == null) return null;
+			return ReadElement(Doc.FirstChild);
+		}
+
+		public static PmlElement ReadElement(System.Xml.XmlNode X) {
+			PmlType pType;
+			bool pTypeFound = false;
+			pType = PmlType.Null;
+			pTypeFound = true;
+			if (X.Attributes != null && X.Attributes.Count > 0 && X.Attributes["type"] != null) {
+				switch (X.Attributes["type"].Value.ToLowerInvariant()) {
+					case "binary":
+						pType = PmlType.Binary;
+						break;
+					case "collection":
+						pType = PmlType.Collection;
+						break;
+					case "dictionary":
+						pType = PmlType.Dictionary;
+						break;
+					case "string":
+						pType = PmlType.String;
+						break;
+					case "null":
+						pType = PmlType.Null;
+						break;
+					case "integer":
+						pType = PmlType.Integer;
+						break;
+					default:
+						pTypeFound = false;
+						break;
+				}
+			} else {
+				pTypeFound = false;
+			}
+
+			if (!pTypeFound) {
+				if (X.HasChildNodes) {
+					if (X.ChildNodes.Count == 1 && X.FirstChild.NodeType == System.Xml.XmlNodeType.Text) {
+						Int64 dummy;
+						UInt64 dummyu;
+						if (Int64.TryParse(X.FirstChild.Value, out dummy) || UInt64.TryParse(X.FirstChild.Value, out dummyu)) {
+							pType = PmlType.Integer;
+						} else {
+							pType = PmlType.String;
+						}
+					} else if (X.FirstChild.Name == "item") {
+						pType = PmlType.Collection;
+					} else {
+						pType = PmlType.Dictionary;
+					}
+				} else {
+					pType = PmlType.Null;
+				}
+			}
+
+			switch (pType) {
+				case PmlType.Null:
+					return new PmlNull();
+				case PmlType.Binary:
+					if (X.FirstChild == null) {
+						return new PmlBinary(new byte[0]);
+					} else {
+						return new PmlBinary(Convert.FromBase64String(X.FirstChild.Value));
+					}
+				case PmlType.Integer:
+					return new PmlInteger(X.FirstChild.Value);
+				case PmlType.String:
+					if (X.FirstChild == null) {
+						return new PmlString("");
+					} else {
+						return new PmlString(X.FirstChild.Value);
+					}
+				case PmlType.Collection:
+					PmlCollection C = new PmlCollection();
+					foreach (XmlNode N in X.ChildNodes) {
+						C.Add(ReadElement(N));
+					}
+
+					return C;
+				case PmlType.Dictionary:
+					PmlDictionary D = new PmlDictionary();
+					foreach (XmlNode N in X.ChildNodes) {
+						D.Add(N.Name, ReadElement(N));
+					}
+
+					return D;
+				default:
+					return null;
+			}
+		}
+	}
+}
\ No newline at end of file