Click here to Skip to main content
15,897,291 members
Articles / Programming Languages / XML

Optimizing Serialization in .NET

Rate me:
Please Sign up or sign in to vote.
4.87/5 (88 votes)
16 May 2010Public Domain31 min read 649.3K   5K   332  
Provides code and techniques to enable developers to optimize serialization of data
#if DEBUG
using System;
using System.Collections;
using System.ComponentModel;
using System.Drawing;

using NUnit.Framework;

#if NET20
using System.Collections.Generic;
#endif

namespace SimmoTech.Utils.Serialization
{
	
	[TestFixture]
	public class DrawingFastSerializationHelperTests
	{
		SerializationWriter Writer;
		private int writerPosition;
		private long writerLength;
		private long objectWriterLength;

		[SetUp]
		public void CreateWriter()
		{
			Writer = new SerializationWriter();
			reader = null;
			writerPosition = 0;
			writerLength = -1;
			objectWriterLength = -1;
		}

		[Browsable(false)]
		public SerializationReader Reader
		{
			get
			{
				if(reader == null)
				{
					writerPosition = (int) Writer.BaseStream.Position;
					reader = getReaderFromWriter(Writer);
				}
				return reader;
			}
		}

		SerializationReader reader;

		private void CheckValueAsObject(int expectedSizeAsObject, object value, IComparer comparer, bool preserveDecimalScale)
		{
			SerializationWriter objectWriter = new SerializationWriter();
			objectWriter.PreserveDecimalScale = preserveDecimalScale;
			objectWriter.WriteObject(value);
			Assert.AreEqual(expectedSizeAsObject, objectWriter.BaseStream.Position - 4, "Incorrect length on Write As Object");

			SerializationReader objectReader = getReaderFromWriter(objectWriter);
			object newValue = objectReader.ReadObject();
			Assert.AreEqual(expectedSizeAsObject, objectReader.BaseStream.Position - 4, "Incorrect length on Read As Object");
			if(comparer == null)
				Assert.AreEqual(value, newValue, "Object Value Read does not match Object Value Write");
			else
			{
				Assert.AreEqual(0, comparer.Compare(value, newValue), "Object Value Read does not match Object Value Write");
			}
		}

		private void CheckValue(int expectedSize, int expectedSurrogateHandledSize, object value)
		{
			CheckValue(expectedSize, expectedSurrogateHandledSize, value, null);
		}

		private void createWriter() {
			SerializationWriter.TypeSurrogates.Clear();
			CreateWriter();
		}

		private void createSurrogateWriter() {
			SerializationWriter.TypeSurrogates.Add(new DrawingFastSerializationHelper());
			CreateWriter();
		}

		private void CheckValue(int expectedSize, int expectedSurrogateHandledSize, object value, IComparer comparer) {
			createWriter();
			CheckValue(expectedSize, value, comparer);
			if (expectedSurrogateHandledSize != -1) {
				createSurrogateWriter();
				CheckValue(expectedSurrogateHandledSize, value, comparer);
			}
		}

		private void CheckValue(int expectedSize, object value, IComparer comparer)
		{
			string writerType = SerializationWriter.TypeSurrogates.Count == 0 ? "No surrogate" : "With surrogate";
			Writer.WriteObject(value);
			object newValue = Reader.ReadObject();

			Assert.IsTrue((value == null && newValue == null) || (value != null && newValue != null), "Incorrect null/not null: " + writerType);

			if(expectedSize != -1)
			{
				Assert.AreEqual(expectedSize, writerPosition - 4, "Incorrect length on WriteObject/" + writerType);
				Assert.AreEqual(expectedSize, Reader.BaseStream.Position - 4, "Incorrect length on ReadObject/" + writerType);
			}
			if(value != null) Assert.AreSame(value.GetType(), newValue.GetType());

			if(comparer == null)
				Assert.AreEqual(value, newValue, "Comparison failed: " + writerType);
			else
			{
				Assert.AreEqual(0, comparer.Compare(value, newValue), "IComparer comparison failed: " + writerType);
			}

		}

		private SerializationReader getReaderFromWriter(SerializationWriter writer)
		{
			byte[] data = writer.ToArray();
			if(writerLength == -1)
				writerLength = data.Length;
			else
			{
				objectWriterLength = data.Length;
			}
			return new SerializationReader(data);
		}

		[Test]
		public void CheckKnownColorRed() {
			Color value = Color.Red;
			Assert.IsTrue(value.IsKnownColor);
			CheckValue(188, 6, value);
		}

		[Test]
		public void CheckKnownColorGreen() {
			Color value = Color.Green;
			Assert.IsTrue(value.IsKnownColor);
			CheckValue(188, 5, value);
		}

		[Test]
		public void CheckKnownColorBlue() {
			Color value = Color.Blue;
			Assert.IsTrue(value.IsKnownColor);
			CheckValue(188, 5, value);
		}

		[Test]
		public void CheckValueColorRed() {
			Color value = Color.FromArgb(Color.Red.ToArgb());
			Assert.IsFalse(value.IsKnownColor);
			CheckValue(188, 6, value);
		}

		[Test]
		public void CheckValueColorGreen() {
			Color value = Color.FromArgb(Color.Green.ToArgb());
			Assert.IsFalse(value.IsKnownColor);
			CheckValue(188, 6, value);
		}

		[Test]
		public void CheckValueColorBlue() {
			Color value = Color.FromArgb(Color.Blue.ToArgb());
			Assert.IsFalse(value.IsKnownColor);
			CheckValue(188, 6, value);
		}

	}
}

#endif

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under A Public Domain dedication


Written By
Software Developer (Senior) Hunton Information Systems Ltd.
United Kingdom United Kingdom
Simon Hewitt is a freelance IT consultant and is MD of Hunton Information Systems Ltd.

He is currently looking for contract work in London.

He is happily married to Karen (originally from Florida, US), has a lovely daughter Bailey, and they live in Kings Langley, Hertfordshire, UK.

Comments and Discussions