Click here to Skip to main content
15,897,704 members
Articles / Programming Languages / C#

Integration: Mechanics + Hydraulics + Navigation

Rate me:
Please Sign up or sign in to vote.
5.00/5 (46 votes)
3 Feb 2011CPOL21 min read 61.8K   6.1K   88  
Sample of integration of branches of engineering.
using System;
using System.Collections.Generic;
using System.Collections;
using System.Text;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;
using System.Reflection;


using CategoryTheory;

using DiagramUI.Labels;
using DiagramUI.Attributes;
using DiagramUI.Interfaces;

using SerializationInterface;


namespace DiagramUI
{
    /// <summary>
    /// Desktop for serialization
    /// </summary>
    [Serializable()]
    public class PureDesktopPeer : PureDesktop, ISerializable
    {
        #region Fields

        /// <summary>
        /// Parent container
        /// </summary>
        private IObjectContainer parent;

        /// <summary>
        /// List of exceptios
        /// </summary>
        private static List<Exception> exceptions;


        /// <summary>
        /// Serialization binders
        /// </summary>
        private static SerializationBinder[] binders;

        /// <summary>
        /// The need change flag
        /// </summary>
        private static bool needChange;

        /// <summary>
        /// Comments
        /// </summary>
        private List<object> comments = new List<object>();

        /// <summary>
        /// Comment bytes
        /// </summary>
        private byte[] commentBytes;

        /// <summary>
        /// Stream position
        /// </summary>
        private long streamPosition;

        /// <summary>
        /// The "has parent" sign
        /// </summary>
        private bool hasParent = false;

 
        #endregion

        #region Constructors

        /// <summary>
        /// Default constructor
        /// </summary>
        public PureDesktopPeer()
        {
        }

        /// <summary>
        /// Deserialization constructor
        /// </summary>
        /// <param name="info">Serialization info</param>
        /// <param name="context">Streaming context</param>
        protected PureDesktopPeer(SerializationInfo info, StreamingContext context)
        {
            byte[] b = info.GetValue("Bytes", typeof(byte[])) as byte[];
            MemoryStream ms = new MemoryStream(b);
            Load(ms, true);
        }


        #endregion

        #region ISerializable Members

        void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
        {
            MemoryStream ms = new MemoryStream();
            Save(ms);
            info.AddValue("Bytes", ms.GetBuffer(), typeof(byte[]));
        }

        #endregion

        #region IDesktop Members

        /// <summary>
        /// Copies objects and arrows
        /// </summary>
        /// <param name="objects">Objects</param>
        /// <param name="arrows">Arrows</param>
        /// <param name="associated">Copy associated objects sign</param>
        public override void Copy(IList<IObjectLabel> objects, IList<IArrowLabel> arrows, bool associated)
        {
            foreach (IObjectLabel l in objects)
            {
                string type = l.Type;
                string st = l.Object.GetType() + "";
                if (!type.Equals(st))
                {
                    //type = st;
                }
                PureObjectLabelPeer lp = new PureObjectLabelPeer(l.Name, l.Kind, type, l.X, l.Y);
                Type t = l.GetType();
                object[] o = t.GetCustomAttributes(typeof(SerializableLabelAttribute), true);
                if (o != null)
                {
                    if (o.Length > 0)
                    {
                        IObjectLabelHolder lh = lp;
                        lh.Label = l;
                    }
                }
                IObjectLabel lab = lp;
                lab.Object = l.Object;
                lab.Desktop = this;
                this.objects.Add(lab);
                if (associated)
                {
                    lab.Object.Object = lab;
                }
                table[l.Name] = lab;
            }
            //PureObjectLabel.Wrappers = false;
            foreach (IArrowLabel l in arrows)
            {
                PureArrowLabelPeer lp = new PureArrowLabelPeer(l.Name, l.Kind, l.Type, l.X, l.Y);
                Type t = l.GetType();
                object[] o = t.GetCustomAttributes(typeof(SerializableLabelAttribute), true);
                if (o != null)
                {
                    if (o.Length > 0)
                    {
                        IArrowLabelHolder lh = lp;
                        lh.Label = l;
                    }
                }
                IArrowLabel lab = new PureArrowLabelPeer(l.Name, l.Kind, l.Type, l.X, l.Y);
                lab.Arrow = l.Arrow;
                if (associated)
                {
                    lab.Arrow.Object = lab;
                }
                lab.Desktop = this;
                this.arrows.Add(lab);
               // components.Add(lab);
                table[l.Name] = lab;
                lab.Source = PureDesktop.Find(objects, this.Objects, l.Source, l.Desktop);
                lab.Target = PureDesktop.Find(objects, this.Objects, l.Target, l.Desktop);
            }
            if (!associated)
            {
                return;
            }
            SetParents(this);
            PureObjectLabel.SetLabels(objects);
            PureArrowLabel.SetLabels(arrows);
            //PureObjectLabel.Wrappers = true;
        }



        /// <summary>
        /// Access to component
        /// </summary>
        /// <param name="name">Component name</param>
        /// <returns>The component</returns>
        public override INamedComponent this[string name]
        {
            get
            {
                INamedComponent nc = base[name];
                if (nc != null)
                {
                    return nc;
                }
                nc = GetFromRoot(this, name);
                if (nc != null)
                {
                    return nc;
                }
                nc = GetChild(this, name);
                if (nc != null)
                {
                    return nc;
                }
                return null;
            }
        }

        /// <summary>
        /// Parent desktop
        /// </summary>
        public override IDesktop ParentDesktop
        {
            get
            {
                return parentDesktop;
            }
        }

        /// <summary>
        /// Level of desktop
        /// </summary>
        public override int Level
        {
            get
            {
                if (parentDesktop == null)
                {
                    return 0;
                }
                return parentDesktop.Level + 1;
            }
        }



        /// <summary>
        /// Root desktop
        /// </summary>
        public override IDesktop Root
        {
            get
            {
                IDesktop d = parentDesktop;
                if (d == null)
                {
                    return this;
                }
                return d.Root;
            }
        }

        /// <summary>
        /// Serialization bindres
        /// </summary>
        static public SerializationBinder[] Binders
        {
            get
            {
                return binders;
            }
            set
            {
                binders = value;
            }
        }


        #endregion

        #region Overriden

        /// <summary>
        /// Clears all content
        /// </summary>
        public override void ClearAll()
        {
            base.ClearAll();
            comments.Clear();
            commentBytes = null;
        }

        /// <summary>
        /// Gets objects and arrows of associated object
        /// </summary>
        /// <param name="ao">The associated object</param>
        /// <param name="objects">Objects</param>
        /// <param name="arrows">Arrows</param>
        protected override void GetObjects(IAssociatedObject ao, IList<ICategoryObject> objects, IList<ICategoryArrow> arrows)
        {
            if (ao is IObjectContainer)
            {
                IObjectContainer oc = ao as IObjectContainer;
                IDesktop d = oc.Desktop;
                ICollection<object> c = d.AllComponents;
                foreach (object o in c)
                {
                    if (o is IObjectLabel)
                    {
                        IObjectLabel ol = o as IObjectLabel;
                        GetObjects(ol.Object, objects, arrows);
                    }
                    if (o is IArrowLabel)
                    {
                        IArrowLabel al = o as IArrowLabel;
                        GetObjects(al.Arrow, objects, arrows);
                    }
                }
            }
            else
            {
                base.GetObjects(ao, objects, arrows);
            }
        }

        /// <summary>
        /// All components
        /// </summary>
        public override ICollection<object> AllComponents
        {
            get
            {
                return GetAllObjects(this);
            }
        }


        #endregion

        #region Specific members


        /// <summary>
        /// The need change sign
        /// </summary>
        static public bool NeedChange
        {
            get
            {
                return needChange;
            }
            set
            {
                needChange = value;
            }
        }

 

        /// <summary>
        /// Saves all aliases of desktop to stream
        /// </summary>
        /// <param name="desktop">The desktop</param>
        /// <param name="stream">The stream</param>
        static public void SaveAllAliases(IDesktop desktop, Stream stream)
        {
            Dictionary<string, object> d = desktop.GetAllAliases();
            BinaryFormatter bf = new BinaryFormatter();
            bf.Serialize(stream, d);
        }

        /// <summary>
        /// Content
        /// </summary>
        public byte[] Content
        {
            get
            {
                MemoryStream ms = new MemoryStream();
                Save(ms);
                return ms.GetBuffer();
            }
        }

        /// <summary>
        /// Comments
        /// </summary>
        public List<object> Comments
        {
            get
            {
                if (commentBytes != null)
                {
                    MemoryStream ms = new MemoryStream(commentBytes);
                    BinaryFormatter bf = new BinaryFormatter();
                    comments = bf.Deserialize(ms) as List<object>;
                    commentBytes = null;
                }
                return comments;
            }
        }

 
        /// <summary>
        /// Checks desktop
        /// </summary>
        /// <param name="desktop">The desktop</param>
        /// <param name="binders">The serialization binders</param>
        /// <returns>List of exceptions or null if right</returns>
        public static List<Exception> Check(IDesktop desktop, SerializationBinder[] binders)
        {
            exceptions = new List<Exception>();
            bool b = false;
            try
            {
                IList<IObjectLabel> objects = desktop.Objects;
                IList<IArrowLabel> arrows = desktop.Arrows;
                PureDesktopPeer d = new PureDesktopPeer();
                d.Copy(objects, arrows, true);
                SetParents(d);
                Stream stream = new MemoryStream();
                d.Save(stream);
                PureDesktopPeer dnew = new PureDesktopPeer();
                b = dnew.Load(stream);
                dnew.Dispose();
            }
            catch (Exception e)
            {
                e.Log();
                if (exceptions != null)
                {
                    exceptions.Add(e);
                }
                else
                {
                    if (errorHandler != null)
                    {
                        errorHandler.ShowError(e);
                    }
                }
            }
            List<Exception> res = b ? null : exceptions;
            exceptions = null;
            SetParents(desktop);
            return res;
        }

        /// <summary>
        /// Checks loading from stream
        /// </summary>
        /// <param name="stream">The stream</param>
        /// <returns>List of exceptions</returns>
        public static List<Exception> Check(Stream stream)
        {
            bool b = false;
            exceptions = new List<Exception>();
            try
            {
                PureDesktopPeer d = new PureDesktopPeer();
                d.Load(stream, binders, true);
                SetParents(d);
                Stream s = new MemoryStream();
                d.Save(s);
                d.Dispose();
                PureDesktopPeer dnew = new PureDesktopPeer();
                b = dnew.Load(s, binders, true);
                dnew.Dispose();
            }
            catch (Exception e)
            {
                e.Log();
                if (exceptions != null)
                {
                    exceptions.Add(e);
                }
                else
                {
                    if (errorHandler != null)
                    {
                        errorHandler.ShowError(e);
                    }
                }
            }
            List<Exception> res = b ? null : exceptions;
            if (res != null)
            {
                if (res.Count == 0)
                {
                    res = null;
                }
            }
            exceptions = null;
            return res;
        }

        /// <summary>
        /// Transforms
        /// </summary>
        /// <param name="instream">Input stream</param>
        /// <param name="outstream">Output strem</param>
        public void Transform(Stream instream, Stream outstream)
        {
            Load(instream);
            SetParents(this);
            Save(outstream);
        }


        /// <summary>
        /// Checks loading from bytes
        /// </summary>
        /// <param name="bytes">The bytes</param>
        /// <returns>Result of cheking</returns>
        public static List<Exception> Check(byte[] bytes)
        {
            MemoryStream stream = new MemoryStream(bytes);
            return Check(stream);
        }




        /// <summary>
        /// Saves itself
        /// </summary>
        /// <param name="stream">Stream to save</param>
        public void Save(Stream stream)
        {
            PreSave();
            BinaryFormatter bformatter = new BinaryFormatter();
            //PureObjectLabel.Wrappers = true;
            bformatter.Serialize(stream, objects);
            bformatter.Serialize(stream, arrows);
            if (commentBytes != null)
            {
                bformatter.Serialize(stream, commentBytes);
                return;
            }
            BinaryFormatter bf = new BinaryFormatter();
            MemoryStream str = new MemoryStream();
            bf.Serialize(str, comments);
            bformatter.Serialize(stream, str.GetBuffer());
        }

        /// <summary>
        /// The Pre Save operation
        /// </summary>
        public void PreSave()
        {
            SetParents(this);
            PureObjectLabel.SetType(objects);
            PureArrowLabel.SetType(arrows);
            foreach (IArrowLabel label in arrows)
            {
                if (objects.Contains(label.Source))
                {
                    label.SourceNumber = objects.IndexOf(label.Source);
                }
                else
                {
                    IObjectLabel ls = label.Source.GetRoot(this) as IObjectLabel;
                    int sn = objects.IndexOf(ls);
                    IObjectContainer scont = ls.Object as IObjectContainer;
                    string ns = scont.GetName(label.Source);
                    label.SourceNumber = new object[] { sn, ns };
                }
                if (objects.Contains(label.Target))
                {
                    label.TargetNumber = objects.IndexOf(label.Target);
                }
                else
                {
                    IObjectLabel lt = label.Target.GetRoot(this) as IObjectLabel;
                    int tn = objects.IndexOf(lt);
                    IObjectContainer tcont = lt.Object as IObjectContainer;
                    string nt = tcont.GetName(label.Target);
                    label.TargetNumber = new object[] { tn, nt };
                }
            }

        }

        /// <summary>
        /// Refreshes itself
        /// </summary>
        public void Refresh()
        {
            MemoryStream stream = new MemoryStream();
            Save(stream);
            objects.Clear();
            arrows.Clear();
            stream.Position = 0;
            Load(stream);
        }

        /// <summary>
        /// Gets all objects of desktop
        /// </summary>
        /// <param name="desktop">The desktop</param>
        /// <returns>Collection of all objects including children</returns>
        public static ICollection<object> GetAllObjects(IDesktop desktop)
        {
            List<object> l = new List<object>();
            ICollection<object> components = desktop.Components;
            l.AddRange(components);
            ICollection<IObjectLabel> objs = desktop.Objects;
            foreach (IObjectLabel o in objs)
            {
                if (o.Object is IObjectContainer)
                {
                    IObjectContainer oc = o.Object as IObjectContainer;
                    l.AddRange(oc.AllObjects);
                }
            }
            return l;
        }

        /// <summary>
        /// Loading from stream
        /// </summary>
        /// <param name="stream">The stream</param>
        /// <param name="binders">Serialization binders</param>
        /// <param name="post">The "post" sign</param>
        /// <returns>True in success and false otherwise</returns>
        public bool Load(Stream stream, SerializationBinder[] binders, bool post)
        {
            if (!loadBinders(stream, binders, post))
            {
                return false;
            }
            LoadComments(stream);
            return true;
        }



        /// <summary>
        /// Loads from bytes
        /// </summary>
        /// <param name="buffer">Buffer</param>
        /// <param name="binders">Serialization binders</param>
        /// <returns>True in success and false otherwise</returns>
        public bool Load(byte[] buffer, SerializationBinder[] binders)
        {
            return Load(buffer, binders, true);
        }


        /// <summary>
        /// Loading from stream
        /// </summary>
        /// <param name="stream">The stream</param>
        /// <returns>True in success and false otherwise</returns>
        public bool Load(Stream stream)
        {
            return Load(stream, binders, true);
        }

 
        /// <summary>
        /// Loads from bytes
        /// </summary>
        /// <param name="buffer">Buffer</param>
        /// <returns>True in success and false otherwise</returns>
        public bool Load(byte[] buffer)
        {
            return Load(buffer, true);
        }


        /// <summary>
        /// Adds arrow with existing source and target
        /// </summary>
        /// <param name="arrow">Arrow</param>
        /// <param name="source">Source</param>
        /// <param name="target">Target</param>
        /// <param name="name">Arrow name</param>
        /// <param name="kind">Arrow kind</param>
        /// <returns>Added arrow</returns>
        public IArrowLabel AddArrowWithExistingLabels(ICategoryArrow arrow, 
            IObjectLabel source, IObjectLabel target, string name, string kind)
        {
            source.Object.Object = source;
            target.Object.Object = target;
            IArrowLabel arrowLabel = new PureArrowLabelPeer(name, kind, arrow.GetType().FullName, 0, 0);
            arrowLabel.Desktop = this;
            arrowLabel.Arrow = arrow;
            arrow.Object = arrowLabel;
            arrowLabel.Source = source;
            arrowLabel.Target = target;
            arrowLabel.Arrow = arrow;
            arrow.Source = source.Object;
            arrow.Target = target.Object;
            arrows.Add(arrowLabel);
            return arrowLabel;
        }

 
        /// <summary>
        /// Sets parents of objects of desktop
        /// </summary>
        /// <param name="desktop">The desktop</param>
        public static void SetParents(IDesktop desktop)
        {
            ICollection<IObjectLabel> objects = desktop.Objects;
            foreach (IObjectLabel ol in objects)
            {
                if (ol.Object is IObjectContainer)
                {
                    IObjectContainer oc = ol.Object as IObjectContainer;
                    oc.SetParents(desktop);
                }
            }
        }





        internal bool Load(byte[] buffer, SerializationBinder[] binders, bool post)
        {
            MemoryStream stream = new MemoryStream(buffer);
            return Load(stream, binders, post);
        }

        internal bool Load(Stream stream, bool post)
        {
            return Load(stream, binders, post);
        }


        internal bool Load(byte[] buffer, bool post)
        {
            return Load(buffer, binders, post);
        }


        /// <summary>
        /// The post load operation
        /// </summary>
        /// <returns></returns>
        internal bool PostLoad()
        {
            try
            {
                PureObjectLabel.SetLabels(this.Objects);
                PureArrowLabel.SetLabels(this.Arrows);
                SetParents(this);
                ICollection<object> components = Components;
                foreach (INamedComponent nc in components)
                {
                    nc.Desktop = this;
                    table[nc.Name] = nc;
                    if (nc is IObjectLabel)
                    {
                        IObjectLabel ol = nc as IObjectLabel;
                        if (ol.Object is IObjectContainer)
                        {
                            IObjectContainer oc = ol.Object as IObjectContainer;
                            bool b = oc.PostLoad();
                            if (!b)
                            {
                                return false;
                            }
                        }
                    }
                }
                foreach (IArrowLabel arrow in arrows)
                {
                    IObjectLabel source = null;
                    IObjectLabel target = null;
                    if (arrow.SourceNumber is Int32)
                    {
                        source = objects[(int)arrow.SourceNumber] as IObjectLabel;
                    }
                    else
                    {
                        object[] os = arrow.SourceNumber as object[];
                        IObjectLabel so = objects[(int)os[0]] as IObjectLabel;
                        IObjectContainer sc = so.Object as IObjectContainer;
                        source = sc[os[1] as string] as IObjectLabel;
                    }
                    if (arrow.TargetNumber is Int32)
                    {
                        target = objects[(int)arrow.TargetNumber] as IObjectLabel;
                    }
                    else
                    {
                        object[] ot = arrow.TargetNumber as object[];
                        IObjectLabel to = objects[(int)ot[0]] as IObjectLabel;
                        IObjectContainer tc = to.Object as IObjectContainer;
                        target = tc[ot[1] as string] as IObjectLabel;
                    }
                    arrow.Arrow.Source = source.Object;
                    arrow.Arrow.Target = target.Object;
                    arrow.Source = source;
                    arrow.Target = target;
                    IAssociatedObject ass = arrow.Arrow as IAssociatedObject;
                    ass.Object = arrow;
                }
                return true;
            }
            catch (Exception ex)
            {
                ex.Log();
                if (exceptions != null)
                {
                    exceptions.Add(ex);
                }
                else
                {
                    if (errorHandler != null)
                    {
                        errorHandler.ShowError(ex);
                    }
                }
            }
            return false;
        }

        /// <summary>
        /// Gets full list of desktop components
        /// </summary>
        /// <param name="desktop">The desktop</param>
        /// <param name="list">The list</param>
        static public void GetFullList(IDesktop desktop, List<INamedComponent> list)
        {
            ICollection<object> l = desktop.AllComponents;
            foreach (INamedComponent c in l)
            {
                list.Add(c);
                IAssociatedObject ao = c as IAssociatedObject;
                if (ao.Object is IObjectContainer)
                {
                    IObjectContainer cont = ao.Object as IObjectContainer;
                    IDesktop d = cont.Desktop;
                    GetFullList(d, list);
                }
            }
        }

        /// <summary>
        /// Gets full list of desktop components
        /// </summary>
        /// <param name="desktop">Desktop</param>
        /// <param name="objects">Objects</param>
        /// <param name="arrows">Arrows</param>
        static public void GetFullList(IDesktop desktop, out List<IObjectLabel> objects, out List<IArrowLabel> arrows)
        {
            objects = new List<IObjectLabel>();
            arrows = new List<IArrowLabel>();
            List<INamedComponent> list = new List<INamedComponent>();
            foreach (INamedComponent c in list)
            {
                if (c is IObjectLabel)
                {
                    IObjectLabel l = c as IObjectLabel;
                    objects.Add(l);
                }
                if (c is IArrowLabel)
                {
                    IArrowLabel l = c as IArrowLabel;
                    arrows.Add(l);
                }
            }
        }

        /// <summary>
        /// Gets type that implements interface
        /// </summary>
        /// <param name="interfaceName">Name of interface</param>
        /// <param name="assemblyBuffer">Bytes of assembly</param>
        /// <returns>Type that implements interface</returns>
        public static Type GetInterface(string interfaceName, byte[] assemblyBuffer)
        {
            Assembly ass = Assembly.Load(assemblyBuffer);
            Type[] types = ass.GetTypes();
            foreach (Type t in types)
            {
                object o = t.GetInterface(interfaceName);
                if (o != null)
                {
                    return t;
                }
            }
            return null;
        }


        /// <summary>
        /// Serializes object
        /// </summary>
        /// <param name="o">Object to serialize</param>
        /// <returns></returns>
        static public byte[] Serialize(object o)
        {
            if (o == null)
            {
                return null;
            }
            BinaryFormatter bf = new BinaryFormatter();
            MemoryStream stream = new MemoryStream();
            bf.Serialize(stream, o);
            return stream.GetBuffer();
        }

        /// <summary>
        /// Deserializes buffer
        /// </summary>
        /// <param name="buffer">The buffer</param>
        /// <returns>Dezerialized object</returns>
        static public object Deserialize(byte[] buffer)
        {
            if (buffer == null)
            {
                return null;
            }
            BinaryFormatter bf = new BinaryFormatter();
            MemoryStream stream = new MemoryStream(buffer);
            return bf.Deserialize(stream);
        }

 
        /// <summary>
        /// Saves propreties
        /// </summary>
        /// <param name="properties">Properties</param>
        /// <param name="bytes">Bytes</param>
        /// <param name="info">Serialization info</param>
        public static void SaveProperties(object properties, byte[] bytes, SerializationInfo info)
        {
            if (properties != null)
            {
                Serialization.Serialize<object>("Properties", info, properties);
                return;
            }
            byte[] b = bytes;
            if (b == null)
            {
                b = new byte[0];
            }
            info.AddValue("Properties", b, typeof(byte[]));
        }


        /// <summary>
        /// Clones object by serialization
        /// </summary>
        /// <typeparam name="T">Type of object</typeparam>
        /// <param name="obj">The prototype object</param>
        /// <returns>A clone</returns>
        public static T Clone<T>(T obj) where T : class
        {
            MemoryStream ms = new MemoryStream();
            BinaryFormatter bf = new BinaryFormatter();
            bf.Serialize(ms, obj);
            ms.Position = 0;
            return bf.Deserialize(ms) as T;
        }

        /// <summary>
        /// Loads bytes
        /// </summary>
        /// <param name="name">name</param>
        /// <param name="info">info</param>
        /// <returns>The bytes</returns>
        public static byte[] LoadBytes(string name, SerializationInfo info)
        {
            return info.GetValue(name, typeof(byte[])) as byte[];
        }

        /// <summary>
        /// Loads bytes properties
        /// </summary>
        /// <param name="info">Info</param>
        /// <returns>Propreties</returns>
        public static byte[] LoadProperties(SerializationInfo info)
        {
            return LoadBytes("Properties", info);
        }

        /// <summary>
        /// Loads label bytes
        /// </summary>
        /// <param name="info">Info</param>
        /// <returns>Butes</returns>
        public static byte[] LoadLabel(SerializationInfo info)
        {
            return LoadBytes("Label", info);
        }

        /// <summary>
        /// Saves label
        /// </summary>
        /// <param name="label">Label to save</param>
        /// <param name="bytes">Bytes of label</param>
        /// <param name="info">Info</param>
        public static void SaveLabel(object label, byte[] bytes, SerializationInfo info)
        {
            if (label != null)
            {
                Serialization.Serialize<object>("Label", info, label);
                return;
            }
            byte[] b = bytes;
            if (b == null)
            {
                b = new byte[0];
            }
            info.AddValue("Label", b, typeof(byte[]));
        }


        /// <summary>
        /// Gets object from bytes
        /// </summary>
        /// <typeparam name="T">Type of object</typeparam>
        /// <param name="obj">The object</param>
        /// <param name="bytes">Bytes</param>
        /// <returns>The object</returns>
        public static T GetObject<T>(ref T obj, byte[] bytes) where T : class
        {
            if (obj != null)
            {
                return obj;
            }
            if (bytes == null)
            {
                return null;
            }
            if (bytes.Length == 0)
            {
                return null;
            }
            MemoryStream ms = new MemoryStream(bytes);
            BinaryFormatter bf = new BinaryFormatter();
            SerializationBinder[] binders = PureDesktopPeer.Binders;
            if (binders == null)
            {
                try
                {
                    obj = bf.Deserialize(ms) as T;
                }
                catch (Exception ex)
                {
                    ex.Log();
                    return null;
                }
            }
            else
            {
                try
                {
                    obj = bf.Deserialize(ms) as T;
                }
                catch (Exception exc)
                {
                    exc.Log();
                    if (binders != null)
                    {
                        foreach (SerializationBinder binder in binders)
                        {
                            bf.Binder = binder;
                            try
                            {
                                obj = bf.Deserialize(ms) as T;
                                break;
                            }
                            catch (Exception exce)
                            {
                                exce.Log();
                            }
                        }
                    }
                }
            }
            return obj;
        }


        /// <summary>
        /// Gets properties
        /// </summary>
        /// <param name="properties">Properties</param>
        /// <param name="bytes">Bytes</param>
        /// <returns>Properties</returns>
        public static object GetProperties(object properties, byte[] bytes)
        {
            if (properties != null)
            {
                return properties;
            }
            if (bytes == null)
            {
                return null;
            }
            if (bytes.Length == 0)
            {
                return null;
            }
            MemoryStream ms = new MemoryStream(bytes);
            BinaryFormatter bf = new BinaryFormatter();
            return bf.Deserialize(ms);
        }

        /// <summary>
        /// Checks whether object can be setialized
        /// </summary>
        /// <param name="o">Object to check</param>
        public static void CheckSerialization(object o)
        {
            MemoryStream ms = new MemoryStream();
            BinaryFormatter bf = new BinaryFormatter();
            try
            {
                bf.Serialize(ms, o);
            }
            catch (Exception e)
            {
                e.Log();
                throw e;
            }
        }

 


        /// <summary>
        /// Parent desktop
        /// </summary>
        internal IDesktop parentDesktop
        {
            get
            {
                if (parent == null)
                {
                    return null;
                }
                IAssociatedObject obj = parent as IAssociatedObject;
                INamedComponent nc = obj.Object as INamedComponent;
                return nc.Desktop;
            }
        }

        /// <summary>
        /// Post deserialization operation
        /// </summary>
        /// <returns>True in success and false otherwise</returns>
        internal bool PostDeserialize()
        {
            try
            {
                IList<ICategoryArrow> arrows = CategoryArrows;
                foreach (ICategoryArrow arrow in arrows)
                {
                    PureDesktop.PostSetArrow(arrow);
                }
                IList<ICategoryObject> objects = CategoryObjects;
                foreach (ICategoryObject lab in objects)
                {
                   PureDesktop.PostSetArrow(lab);
                }
                foreach (ICategoryArrow lab in arrows)
                {
                    if (lab is IPostSerialize)
                    {
                        IPostSerialize post = lab as IPostSerialize;
                        post.PostSerialize();
                    }
                }
                if (!hasParent)
                {
                    PureDesktop.PostLoad(this);
                }
                return true;
            }
            catch (Exception ex)
            {
                ex.Log();
                if (exceptions != null)
                {
                    exceptions.Add(ex);
                }
                else
                {
                    if (errorHandler != null)
                    {
                        errorHandler.ShowError(ex);
                    }
                }
            }
            return false;
        }


        internal void setParent(IObjectContainer parent)
        {
            this.parent = parent;
        }

        internal bool loadBinders(Stream stream, SerializationBinder[] binders, bool post)
        {
            if (load(stream, null, post))
            {
                return true;
            }
            if (binders == null)
            {
                return false;
            }
            ObjectContainerBase.Binders = binders;
            foreach (SerializationBinder binder in binders)
            {
                if (load(stream, binder, post))
                {
                    return true;
                }
            }
            return false;
        }

        private static int GetOrder(INamedComponent nc, IDesktop desktop)
        {
            if (nc.Desktop == desktop)
            {
                return nc.Ord;
            }
            IObjectContainer oc = ParentContainer(nc);
            IAssociatedObject ao = oc as IAssociatedObject;
            INamedComponent comp = ao.Object as INamedComponent;
            return GetOrder(comp, desktop);
        }

        /// <summary>
        /// Path of component desktops
        /// </summary>
        /// <param name="component">The component</param>
        /// <returns>Desktop path</returns>
        static public List<IDesktop> GetPath(INamedComponent component)
        {
            List<IDesktop> l = new List<IDesktop>();
            IDesktop d = component.Desktop;
            while (true)
            {
                if (d == null)
                {
                    break;
                }
                l.Add(d);
                d = d.ParentDesktop;
            }
            return l;
        }

        /// <summary>
        /// Common desktop of two components
        /// </summary>
        /// <param name="c1">First component</param>
        /// <param name="c2">Second component</param>
        /// <returns>Common desktop</returns>
        public static IDesktop GetCommonDesktop(INamedComponent c1, INamedComponent c2)
        {
            List<IDesktop> l1 = GetPath(c1);
            List<IDesktop> l2 = GetPath(c2);
            foreach (IDesktop d in l1)
            {
                if (l2.Contains(d))
                {
                    return d;
                }
            }
            return null;
        }

        /// <summary>
        /// Gets difference between components 
        /// </summary>
        /// <param name="nc1">First component</param>
        /// <param name="nc2">Second component</param>
        /// <returns>Difference</returns>
        public static int GetDifference(INamedComponent nc1, INamedComponent nc2)
        {
            IDesktop d = GetCommonDesktop(nc1, nc2);
            return GetOrder(nc1, d) - GetOrder(nc2, d);
        }


        

        private static IObjectContainer ParentContainer(INamedComponent nc)
        {
            IDesktop d = nc.Desktop;
            if (!(d is PureDesktopPeer))
            {
                return null;
            }
            PureDesktopPeer pd = d as PureDesktopPeer;
            return pd.parent;
        }
        

        private bool load(Stream stream, SerializationBinder binder, bool post)
        {
            stream.Position = 0;
            BinaryFormatter bformatter = new BinaryFormatter();
            if (binder != null)
            {
                bformatter.Binder = binder;
            }
            try
            {
               // PureObjectLabel.Wrappers = true;
                objects = bformatter.Deserialize(stream) as ArrayList;
                arrows = bformatter.Deserialize(stream) as ArrayList;
                if (objects == null)
                {
                    objects = new ArrayList();
                }
                if (arrows == null)
                {
                    arrows = new ArrayList();
                }
                foreach (object o in objects)
                {
                    if (o is INamedComponent)
                    {
                        INamedComponent nc = o as INamedComponent;
                        nc.Desktop = this;
                        string n = nc.Name;
                        if (!table.ContainsKey(n))
                        {
                            table[n] = nc;
                        }
                    }
                    if (o is IObjectLabel)
                    {
                        IObjectLabel l = o as IObjectLabel;
                        object os = l.Object;
                        if (os is IAssociatedObject)
                        {
                            IAssociatedObject ass = os as IAssociatedObject;
                            ass.Object = l;
                        }
                        if (os is IObjectContainer)
                        {
                            IObjectContainer oc = os as IObjectContainer;
                            bool lb = oc.Load();
                            if (!lb)
                            {
                                return false;
                            }
                        }
                    }
                }
                foreach (object o in arrows)
                {
                    if (o is INamedComponent)
                    {
                        if (o is IArrowLabel)
                        {
                            IArrowLabel l = o as IArrowLabel;
                            object os = l.Arrow;
                            if (os is IAssociatedObject)
                            {
                                IAssociatedObject ass = os as IAssociatedObject;
                                ass.Object = l;
                            }
                        }
                        INamedComponent nc = o as INamedComponent;
                        string n = nc.Name;
                        if (!table.ContainsKey(n))
                        {
                            table[n] = nc;
                        }
                        nc.Desktop = this;
                    }
                }
                if (post)
                {
                   bool b = PostLoad();
                   if (!b)
                   {
                       return false;
                   }
                   return PostDeserialize();
                }
                return true;
            }
            catch (Exception ex)
            {
                ex.Log();
                if (exceptions != null)
                {
                    exceptions.Add(ex);
                }
                else
                {
                    if (errorHandler != null)
                    {
                        errorHandler.ShowError(ex);
                    }
                }
            }
            return false;
        }


        /// <summary>
        /// Gets child named component
        /// </summary>
        /// <param name="desktop">Desktop</param>
        /// <param name="name">Name of object</param>
        /// <returns>The child component</returns>
        static public INamedComponent GetChild(IDesktop desktop, string name)
        {
            IList<IObjectLabel> c = desktop.Objects;
            foreach (IObjectLabel l in c)
            {
                object ob = l.Object;
                if (!(ob is IObjectContainer))
                {
                    continue;
                }
                IObjectContainer cont = ob as IObjectContainer;
                ICollection<object> all = cont.AllObjects;
                foreach (INamedComponent nc in all)
                {
                    string n = nc.GetName(desktop);
                    if (n.Equals(name))
                    {
                        return nc;
                    }
                }
            }
            return null;
        }

        /// <summary>
        /// Gets child named component form root desktop
        /// </summary>
        /// <param name="desktop">Root desktop</param>
        /// <param name="name">Name of object</param>
        /// <returns>The child component</returns>
        static public INamedComponent GetFromRoot(IDesktop desktop, string name)
        {
            if (name.Length >= 3)
            {
                if (name.Substring(0, 3).Equals("../"))
                {
                    PureDesktopPeer d = desktop as PureDesktopPeer;
                    IObjectContainer cont = d.parent;
                    IAssociatedObject ao = cont as IAssociatedObject;
                    INamedComponent cnc = ao.Object as INamedComponent;
                    INamedComponent nc = cnc.Desktop[name.Substring(3)];
                    if (nc != null)
                    {
                        return nc;
                    }
                }
            }
            return null;
        }

 
        /// <summary>
        /// Position of stream
        /// </summary>
        public long StreamPosition
        {
            get
            {
                return streamPosition;
            }
        }

        /// <summary>
        /// The "has parent" sign
        /// </summary>
        public bool HasParent
        {
            get { return hasParent; }
            set { hasParent = value; }
        }

        /// <summary>
        /// Loads Comments from stream
        /// </summary>
        /// <param name="stream">The stream</param>
        private void LoadComments(Stream stream)
        {
            streamPosition = stream.Position;
            try
            {
                BinaryFormatter bf = new BinaryFormatter();
                commentBytes = bf.Deserialize(stream) as byte[];
                if (commentBytes != null)
                {
                    streamPosition = stream.Position;
                }
            }
            catch (Exception ex)
            {
                ex.Log();
                stream.Position = streamPosition;
            }
        }

        /// <summary>
        /// Global error handler
        /// </summary>
        private static IErrorHandler errorHandler
        {
            get
            {
                return PureDesktop.ErrorHandler;
            }
        }


        #endregion

    }
}

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 The Code Project Open License (CPOL)


Written By
Architect
Russian Federation Russian Federation
Ph. D. Petr Ivankov worked as scientific researcher at Russian Mission Control Centre since 1978 up to 2000. Now he is engaged by Aviation training simulators http://dinamika-avia.com/ . His additional interests are:

1) Noncommutative geometry

http://front.math.ucdavis.edu/author/P.Ivankov

2) Literary work (Russian only)

http://zhurnal.lib.ru/editors/3/3d_m/

3) Scientific articles
http://arxiv.org/find/all/1/au:+Ivankov_Petr/0/1/0/all/0/1

Comments and Discussions