| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166 | using System;using System.IO;using System.Xml;using Google.ProtocolBuffers.Descriptors;namespace Google.ProtocolBuffers.Serialization{    /// <summary>    /// Writes a proto buffer to an XML document or fragment.  .NET 3.5 users may also    /// use this class to produce Json by setting the options to support Json and providing    /// an XmlWriter obtained from <see cref="System.Runtime.Serialization.Json.JsonReaderWriterFactory"/>.    /// </summary>    public class XmlFormatWriter : AbstractTextWriter    {        public const string DefaultRootElementName = "root";        private const int NestedArrayFlag = 0x0001;        private readonly XmlWriter _output;        private string _rootElementName;        static XmlWriterSettings DefaultSettings        {            get { return new XmlWriterSettings() {CheckCharacters = false, NewLineHandling = NewLineHandling.Entitize}; }        }        /// <summary>        /// Constructs the XmlFormatWriter to write to the given TextWriter        /// </summary>        public XmlFormatWriter(TextWriter output) : this(XmlWriter.Create(output, DefaultSettings)) { }        /// <summary>        /// Constructs the XmlFormatWriter to write to the given stream        /// </summary>        public XmlFormatWriter(Stream output) : this(XmlWriter.Create(output, DefaultSettings)) { }        /// <summary>        /// Constructs the XmlFormatWriter to write to the given XmlWriter        /// </summary>        public XmlFormatWriter(XmlWriter output)        {            _output = output;            _rootElementName = DefaultRootElementName;        }        /// <summary>        /// Closes the underlying XmlTextWriter        /// </summary>        protected override void Dispose(bool disposing)        {            if(disposing)                _output.Close();        }        /// <summary>        /// Gets or sets the default element name to use when using the Merge<TBuilder>()        /// </summary>        public string RootElementName        {            get { return _rootElementName; }            set { ThrowHelper.ThrowIfNull(value, "RootElementName"); _rootElementName = value; }        }        /// <summary>        /// Gets or sets the options to use while generating the XML        /// </summary>        public XmlWriterOptions Options { get; set; }        private bool TestOption(XmlWriterOptions option) { return (Options & option) != 0; }        /// <summary>        /// Writes a message as an element using the name defined in <see cref="RootElementName"/>        /// </summary>        public override void WriteMessage(IMessageLite message)        { WriteMessage(_rootElementName, message); }        /// <summary>        /// Writes a message as an element with the given name        /// </summary>        public override void WriteMessage(string elementName, IMessageLite message)        {            if (TestOption(XmlWriterOptions.OutputJsonTypes))            {                _output.WriteStartElement("root"); // json requires this is the root-element                _output.WriteAttributeString("type", "object");            }            else                _output.WriteStartElement(elementName);            message.WriteTo(this);            _output.WriteEndElement();            _output.Flush();        }        /// <summary>        /// Writes a message        /// </summary>        protected override void WriteMessageOrGroup(string field, IMessageLite message)        {            _output.WriteStartElement(field);            if (TestOption(XmlWriterOptions.OutputJsonTypes))                _output.WriteAttributeString("type", "object");            message.WriteTo(this);            _output.WriteEndElement();        }        /// <summary>        /// Writes a String value        /// </summary>        protected override void WriteAsText(string field, string textValue, object typedValue)        {            _output.WriteStartElement(field);            if (TestOption(XmlWriterOptions.OutputJsonTypes))            {                if (typedValue is int || typedValue is uint || typedValue is long || typedValue is ulong || typedValue is double || typedValue is float)                    _output.WriteAttributeString("type", "number");                else if (typedValue is bool)                    _output.WriteAttributeString("type", "boolean");            }            _output.WriteString(textValue);            //Empty strings should not be written as empty elements '<item/>', rather as '<item></item>'            if (_output.WriteState == WriteState.Element)                _output.WriteRaw("");            _output.WriteEndElement();        }        /// <summary>        /// Writes an array of field values        /// </summary>        protected override void WriteArray(FieldType fieldType, string field, System.Collections.IEnumerable items)        {            //see if it's empty            System.Collections.IEnumerator eitems = items.GetEnumerator();            try { if (!eitems.MoveNext()) return; }            finally            { if (eitems is IDisposable) ((IDisposable) eitems).Dispose(); }            if (TestOption(XmlWriterOptions.OutputNestedArrays | XmlWriterOptions.OutputJsonTypes))            {                _output.WriteStartElement(field);                if (TestOption(XmlWriterOptions.OutputJsonTypes))                    _output.WriteAttributeString("type", "array");                base.WriteArray(fieldType, "item", items);                _output.WriteEndElement();            }            else                base.WriteArray(fieldType, field, items);        }        /// <summary>        /// Writes a System.Enum by the numeric and textual value        /// </summary>        protected override void WriteEnum(string field, int number, string name)        {            _output.WriteStartElement(field);            if (!TestOption(XmlWriterOptions.OutputJsonTypes) && TestOption(XmlWriterOptions.OutputEnumValues))                _output.WriteAttributeString("value", XmlConvert.ToString(number));            _output.WriteString(name);            _output.WriteEndElement();        }    }}
 |