123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424 |
- using System;
- using System.IO;
- using System.Collections;
- using System.Drawing;
- using System.ComponentModel;
- using System.Reflection;
- using System.Collections.Generic;
- using System.Text;
- using System.Globalization;
- namespace FastReport.Utils
- {
- /// <summary>
- /// Specifies the target for the serialize operation.
- /// </summary>
- public enum SerializeTo
- {
- /// <summary>
- /// Serialize to the report file.
- /// </summary>
- Report,
- /// <summary>
- /// Serialize to the preview pages.
- /// </summary>
- Preview,
- /// <summary>
- /// Serialize to the source pages of a preview.
- /// </summary>
- SourcePages,
- /// <summary>
- /// Serialize to the designer's clipboard.
- /// </summary>
- Clipboard,
- /// <summary>
- /// Serialize to the designer's undo/redo buffer.
- /// </summary>
- Undo
- }
- internal class DiffEventArgs
- {
- private object obj;
- private object diffObject;
- public object Object
- {
- get { return obj; }
- set { obj = value; }
- }
- public object DiffObject
- {
- get { return diffObject; }
- set { diffObject = value; }
- }
- }
- internal delegate void DiffEventHandler(object sender, DiffEventArgs e);
- /// <summary>
- /// The writer used to serialize object's properties to a report file.
- /// </summary>
- public class FRWriter : IDisposable
- {
- #region Fields
- private XmlDocument doc;
- private XmlItem root;
- private XmlItem curItem;
- private XmlItem curRoot;
- //private StringBuilder FText;
- private object diffObject;
- private bool saveChildren;
- private bool writeHeader;
- private BlobStore blobStore;
- private SerializeTo serializeTo;
- private Hashtable diffObjects;
- #endregion
- #region Properties
- internal event DiffEventHandler GetDiff;
- internal BlobStore BlobStore
- {
- get { return blobStore; }
- set { blobStore = value; }
- }
- /// <summary>
- /// Gets or sets current xml item name.
- /// </summary>
- public string ItemName
- {
- get { return curItem.Name; }
- set { curItem.Name = value; }
- }
- /// <summary>
- /// Gets or sets target of serialization.
- /// </summary>
- public SerializeTo SerializeTo
- {
- get { return serializeTo; }
- set { serializeTo = value; }
- }
- /// <summary>
- /// Gets the ethalon object to compare with.
- /// </summary>
- public object DiffObject
- {
- get { return diffObject; }
- }
- /// <summary>
- /// Gets or sets a value that determines whether is necessary to serialize child objects.
- /// </summary>
- public bool SaveChildren
- {
- get { return saveChildren; }
- set { saveChildren = value; }
- }
- /// <summary>
- /// Gets or sets a value that determines whether is necessary to add xml header.
- /// </summary>
- public bool WriteHeader
- {
- get { return writeHeader; }
- set { writeHeader = value; }
- }
- #endregion
- #region Private Methods
- private string PropName(string name)
- {
- return serializeTo == SerializeTo.Preview ? ShortProperties.GetShortName(name) : name;
- }
- #endregion
- #region Public Methods
- /// <summary>
- /// Serializes the specified object.
- /// </summary>
- /// <param name="obj">The object to serialize.</param>
- /// <remarks>
- /// The object must implement the <see cref="IFRSerializable"/> interface. This method
- /// invokes the <b>Serialize</b> method of the object.
- /// </remarks>
- /// <example>This example demonstrates the use of writer.
- /// <code>
- /// public void Serialize(FRWriter writer)
- /// {
- /// // get the etalon object. It will be used to write changed properties only.
- /// Base c = writer.DiffObject as Base;
- ///
- /// // write the type name
- /// writer.ItemName = ClassName;
- ///
- /// // write properties
- /// if (Name != "")
- /// writer.WriteStr("Name", Name);
- /// if (Restrictions != c.Restrictions)
- /// writer.WriteValue("Restrictions", Restrictions);
- ///
- /// // write child objects if allowed
- /// if (writer.SaveChildren)
- /// {
- /// foreach (Base child in ChildObjects)
- /// {
- /// writer.Write(child);
- /// }
- /// }
- /// }
- /// </code>
- /// </example>
- public void Write(IFRSerializable obj)
- {
- Write(obj, null);
- }
- /// <summary>
- /// Serializes the object using specified etalon.
- /// </summary>
- /// <param name="obj">The object to serialize.</param>
- /// <param name="diff">The etalon object.</param>
- public void Write(IFRSerializable obj, object diff)
- {
- if (obj == null)
- return;
- XmlItem saveCurItem = curItem;
- XmlItem saveCurRoot = curRoot;
- //StringBuilder saveText = FText;
- object saveDiffObject = diffObject;
- try
- {
- //FText = new StringBuilder();
- curItem = curItem == null ? root : curItem.Add();
- curRoot = curItem;
- diffObject = diff;
- if (obj is Base && SerializeTo == SerializeTo.Preview)
- {
- diffObject = (obj as Base).OriginalComponent;
- curItem.Name = diffObject != null ? (obj as Base).Alias : (obj as Base).ClassName;
- }
- if (GetDiff != null)
- {
- DiffEventArgs e = new DiffEventArgs();
- e.Object = obj;
- GetDiff(this, e);
- diffObject = e.DiffObject;
- }
- if (diffObject == null)
- {
- try
- {
- Type objType = obj.GetType();
- if (!diffObjects.Contains(objType))
- diffObjects[objType] = Activator.CreateInstance(objType);
- diffObject = diffObjects[objType];
- }
- catch
- {
- }
- }
- obj.Serialize(this);
- }
- finally
- {
- //if (FText.Length > 0)
- // FText.Remove(FText.Length - 1, 1);
- //FCurRoot.Text = FText.ToString();
- //FText = saveText;
- curItem = saveCurItem;
- curRoot = saveCurRoot;
- diffObject = saveDiffObject;
- }
- }
- /// <summary>
- /// Writes a string property.
- /// </summary>
- /// <param name="name">Property name.</param>
- /// <param name="value">Property value.</param>
- public void WriteStr(string name, string value)
- {
- curRoot.SetProp(PropName(name), value);
- //FText.Append(PropName(name));
- //FText.Append("=\"");
- //FText.Append(Converter.ToXml(value));
- //FText.Append("\" ");
- }
- /// <summary>
- /// Writes a boolean property.
- /// </summary>
- /// <param name="name">Property name.</param>
- /// <param name="value">Property value.</param>
- public void WriteBool(string name, bool value)
- {
- curRoot.SetProp(PropName(name), value ? "true" : "false");
- // FText.Append(PropName(name));
- //FText.Append("=\"");
- //FText.Append(value ? "true" : "false");
- //FText.Append("\" ");
- }
- /// <summary>
- /// Writes an integer property.
- /// </summary>
- /// <param name="name">Property name.</param>
- /// <param name="value">Property value.</param>
- public void WriteInt(string name, int value)
- {
- curRoot.SetProp(PropName(name), value.ToString());
- //FText.Append(PropName(name));
- //FText.Append("=\"");
- //FText.Append(value.ToString());
- //FText.Append("\" ");
- }
- /// <summary>
- /// Writes a float property.
- /// </summary>
- /// <param name="name">Property name.</param>
- /// <param name="value">Property value.</param>
- public void WriteFloat(string name, float value)
- {
- curRoot.SetProp(PropName(name), value.ToString(CultureInfo.InvariantCulture.NumberFormat));
- //FText.Append(PropName(name));
- //FText.Append("=\"");
- //FText.Append(value.ToString(CultureInfo.InvariantCulture.NumberFormat));
- //FText.Append("\" ");
- }
- /// <summary>
- /// Writes a double property.
- /// </summary>
- /// <param name="name">Property name.</param>
- /// <param name="value">Property value.</param>
- public void WriteDouble(string name, double value)
- {
- curRoot.SetProp(PropName(name), value.ToString(CultureInfo.InvariantCulture.NumberFormat));
- //FText.Append(PropName(name));
- //FText.Append("=\"");
- //FText.Append(value.ToString(CultureInfo.InvariantCulture.NumberFormat));
- //FText.Append("\" ");
- }
- /// <summary>
- /// Writes an enumeration property.
- /// </summary>
- /// <param name="name">Property name.</param>
- /// <param name="value">Property value.</param>
- public void WriteValue(string name, object value)
- {
- curRoot.SetProp(PropName(name), value != null ? Converter.ToString(value) : "null");
- //FText.Append(PropName(name));
- //FText.Append("=\"");
- //FText.Append(value != null ? Converter.ToXml(value) : "null");
- //FText.Append("\" ");
- }
- /// <summary>
- /// Writes an object reference property.
- /// </summary>
- /// <param name="name">Property name.</param>
- /// <param name="value">Property value.</param>
- public void WriteRef(string name, Base value)
- {
- curRoot.SetProp(PropName(name), value != null ? value.Name : "null");
- //FText.Append(PropName(name));
- //FText.Append("=\"");
- //FText.Append(value != null ? value.Name : "null");
- //FText.Append("\" ");
- }
- /// <summary>
- /// Writes a standalone property value.
- /// </summary>
- /// <param name="name">Name of property.</param>
- /// <param name="value">Property value.</param>
- /// <remarks>
- /// This method produces the following output:
- /// <PropertyName>PropertyValue</PropertyName>
- /// </remarks>
- public void WritePropertyValue(string name, string value)
- {
- XmlItem item = curItem.Add();
- item.Name = name;
- item.Value = value;
- }
- /// <summary>
- /// Determines if two objects are equal.
- /// </summary>
- /// <param name="obj1">The first object.</param>
- /// <param name="obj2">The second object.</param>
- /// <returns><b>true</b> if objects will be serialized to the same value.</returns>
- public bool AreEqual(object obj1, object obj2)
- {
- if (obj1 == obj2)
- return true;
- if (obj1 == null || obj2 == null)
- return false;
- string s1 = Converter.ToString(obj1);
- string s2 = Converter.ToString(obj2);
- return s1 == s2;
- }
- /// <summary>
- /// Disposes the writer.
- /// </summary>
- public void Dispose()
- {
- doc.Dispose();
- foreach (object obj in diffObjects.Values)
- {
- if (obj is IDisposable)
- (obj as IDisposable).Dispose();
- }
- }
- /// <summary>
- /// Saves the writer output to a stream.
- /// </summary>
- /// <param name="stream">Stream to save to.</param>
- public void Save(Stream stream)
- {
- doc.AutoIndent = serializeTo == SerializeTo.Report;
- doc.WriteHeader = WriteHeader;
- doc.Save(stream);
- }
- #endregion
- /// <summary>
- /// Initializes a new instance of the <b>FRWriter</b> class with default settings.
- /// </summary>
- public FRWriter()
- {
- doc = new XmlDocument();
- root = doc.Root;
- //FText = new StringBuilder();
- saveChildren = true;
- writeHeader = true;
- diffObjects = new Hashtable();
- }
- /// <summary>
- /// Initializes a new instance of the <b>FRWriter</b> class with specified xml item that will
- /// receive writer's output.
- /// </summary>
- /// <param name="root">The xml item that will receive writer's output.</param>
- public FRWriter(XmlItem root) : this()
- {
- this.root = root;
- }
- }
- }
|