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

Initial commit
author Ivo Smits <Ivo@UCIS.nl>
date Tue, 11 Sep 2012 16:28:53 +0200
parents
children 28dc7d535036
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Pml/RW/PmlBinaryRW.cs	Tue Sep 11 16:28:53 2012 +0200
@@ -0,0 +1,223 @@
+using System;
+using System.IO;
+using System.Text;
+using System.Collections.Generic;
+
+namespace UCIS.Pml {
+	public class PmlBinaryRW : IPmlRW {
+		private PmlBinaryReader pReader;
+		private PmlBinaryWriter pWriter;
+
+		public PmlBinaryRW(Stream Stream) {
+			pReader = new PmlBinaryReader(Stream);
+			pWriter = new PmlBinaryWriter(Stream);
+		}
+		public PmlBinaryRW(Stream Stream, Encoding Encoding) {
+			pReader = new PmlBinaryReader(Stream, Encoding);
+			pWriter = new PmlBinaryWriter(Stream, Encoding);
+		}
+
+		public PmlElement ReadMessage() {
+			return pReader.ReadMessage();
+		}
+
+		public void WriteMessage(PmlElement Message) {
+			pWriter.WriteMessage(Message);
+		}
+
+		public PmlBinaryReader Reader {
+			get { return pReader; }
+		}
+		public PmlBinaryWriter Writer {
+			get { return pWriter; }
+		}
+	}
+
+	public class PmlBinaryWriter : IPmlWriter {
+		//private BinaryWriter pWriter;
+		private Stream pStream;
+		private Encoding pEncoding;
+
+		/*public PmlBinaryWriter(BinaryWriter Writer) {
+			pWriter = Writer;
+		}*/
+		public PmlBinaryWriter(Stream Stream) {
+			//pWriter = new BinaryWriter(Stream);
+			pStream = Stream;
+			pEncoding = Encoding.UTF8;
+		}
+		public PmlBinaryWriter(Stream Stream, Encoding Encoding) {
+			//pWriter = new BinaryWriter(Stream, Encoding);
+			pStream = Stream;
+			pEncoding = Encoding;
+		}
+
+		/*public BinaryWriter BaseWriter {
+			get { return pWriter; }
+			set { pWriter = value; }
+		}*/
+
+		public void WriteMessage(PmlElement Message) {
+			MemoryStream stream = new MemoryStream();
+			BinaryWriter writer = new BinaryWriter(stream, pEncoding);
+			WriteMessageTo(Message, writer);
+			lock (pStream) {
+				stream.WriteTo(pStream);
+				pStream.Flush();
+			}
+		}
+
+		public static void WriteMessageTo(PmlElement Message, BinaryWriter Writer) {
+			lock (Writer) {
+				Writer.Write((byte)255);
+				WriteElementTo(Message, Writer);
+				Writer.Write((byte)255);
+				Writer.Flush();
+			}
+		}
+
+		private static void WriteElementTo(PmlElement Element, BinaryWriter Writer) {
+			//byte[] Buffer = null;
+			if (Element == null) {
+				//Writer.Write((byte)PmlElementType.Null);
+				Writer.Write((byte)0);
+				return;
+			}
+			//Writer.Write((byte)Element.Type);
+			switch (Element.Type) {
+				case PmlType.Null:
+					Writer.Write((byte)0);
+					break;
+				case PmlType.Dictionary:
+					Writer.Write((byte)1);
+					foreach (KeyValuePair<string, PmlElement> Item in (PmlDictionary)Element) {
+						Writer.Write((byte)1);
+						Writer.Write(Item.Key);
+						WriteElementTo(Item.Value, Writer);
+					}
+					Writer.Write((byte)0);
+					break;
+				case PmlType.Collection:
+					Writer.Write((byte)2);
+					foreach (PmlElement Item in (PmlCollection)Element) {
+						Writer.Write((byte)1);
+						WriteElementTo(Item, Writer);
+					}
+					Writer.Write((byte)0);
+					break;
+				case PmlType.Binary: {
+						Writer.Write((byte)10);
+						Byte[] Buffer = Element.ToByteArray();
+						if (Buffer == null) {
+							Writer.Write((int)0);
+						} else {
+							Writer.Write((int)Buffer.Length);
+							Writer.Write(Buffer);
+						}
+					} break;
+				case PmlType.String:
+					Writer.Write((byte)11);
+					string Str = Element.ToString();
+					if (Str == null) {
+						Writer.Write("");
+					} else {
+						Writer.Write(Str);
+					}
+
+					break;
+				case PmlType.Integer:
+					Writer.Write((byte)20);
+					PmlInteger RMInt = (PmlInteger)Element;
+					if (RMInt.IsSigned) {
+						Writer.Write((byte)1);
+						Writer.Write((long)RMInt);
+					} else {
+						Writer.Write((byte)0);
+						Writer.Write((ulong)RMInt);
+					}
+					break;
+				default:
+					Writer.Write((byte)0);
+					Console.WriteLine("PmlBinaryRW: Can not encode PML type {0}", Element.Type);
+					break;
+			}
+		}
+	}
+
+	public class PmlBinaryReader : IPmlReader {
+		private BinaryReader pReader;
+
+		public PmlBinaryReader(BinaryReader Reader) {
+			pReader = Reader;
+		}
+		public PmlBinaryReader(Stream Stream) {
+			pReader = new BinaryReader(Stream);
+		}
+		public PmlBinaryReader(Stream Stream, Encoding Encoding) {
+			pReader = new BinaryReader(Stream, Encoding);
+		}
+
+		public BinaryReader BaseReader {
+			get { return pReader; }
+			set { pReader = value; }
+		}
+
+		public PmlElement ReadMessage() {
+			return ReadMessageFrom(pReader);
+		}
+
+		public static PmlElement ReadMessageFrom(BinaryReader Reader) {
+			PmlElement Element = null;
+			lock (Reader) {
+				if (Reader.ReadByte() != 255) {
+					return null;
+				}
+				Element = ReadElementFrom(Reader);
+				if (Reader.ReadByte() != 255) {
+					return null;
+				}
+			}
+			return Element;
+		}
+
+		private static PmlElement ReadElementFrom(BinaryReader Reader) {
+			Byte EType = Reader.ReadByte();
+			switch (EType) {
+				case 0: return new PmlNull();
+				case 1:
+					PmlDictionary ElementD = new PmlDictionary();
+					do {
+						byte B = Reader.ReadByte();
+						if (B == 0) return ElementD;
+						else if (B == 1) ElementD.Add(Reader.ReadString(), ReadElementFrom(Reader));
+						else return null;
+					}
+					while (true);
+				case 2:
+					PmlCollection ElementC = new PmlCollection();
+					do {
+						byte B = Reader.ReadByte();
+						if (B == 0) return ElementC;
+						else if (B == 1) ElementC.Add(ReadElementFrom(Reader));
+						else return null;
+					}
+					while (true);
+				case 10:
+					int Len = 0;
+					Len = Reader.ReadInt32();
+					return new PmlBinary(Reader.ReadBytes(Len));
+				case 11:
+					return new PmlString(Reader.ReadString());
+				case 20: {
+						byte B = Reader.ReadByte();
+						if (B == 0) return new PmlInteger(Reader.ReadUInt64());
+						else if (B == 1) return new PmlInteger(Reader.ReadInt64());
+						else return null;
+
+					}
+				default:
+					throw new Exception("Unknown PML type code " + EType.ToString());
+			}
+		}
+	}
+}