v10.10.2024.0701 使用IJsonHost改进Json序列化
大石头 编写于 2024-07-01 08:36:34 大石头 提交于 2024-07-01 08:44:42
X
using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Text;
using NewLife.Data;
using NewLife.Log;

namespace NewLife.Serialization
{
    /// <summary>序列化接口</summary>
    public interface IFormatterX
    {
        #region 属性
        /// <summary>数据流</summary>
        Stream Stream { get; set; }

        /// <summary>主对象</summary>
        Stack<Object> Hosts { get; }

        /// <summary>成员</summary>
        MemberInfo Member { get; set; }

        /// <summary>字符串编码,默认utf-8</summary>
        Encoding Encoding { get; set; }

        /// <summary>序列化属性而不是字段。默认true</summary>
        Boolean UseProperty { get; set; }

        /// <summary>用户对象。存放序列化过程中使用的用户自定义对象</summary>
        Object UserState { get; set; }
        #endregion

        #region 方法
        /// <summary>写入一个对象</summary>
        /// <param name="value">目标对象</param>
        /// <param name="type">类型</param>
        /// <returns></returns>
        Boolean Write(Object value, Type type = null);

        /// <summary>读取指定类型对象</summary>
        /// <param name="type"></param>
        /// <returns></returns>
        Object Read(Type type);

        /// <summary>读取指定类型对象</summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        T Read<T>();

        /// <summary>尝试读取指定类型对象</summary>
        /// <param name="type"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        Boolean TryRead(Type type, ref Object value);
        #endregion

        #region 调试日志
        /// <summary>日志提供者</summary>
        ILog Log { get; set; }
        #endregion
    }

    /// <summary>序列化处理器接口</summary>
    /// <typeparam name="THost"></typeparam>
    public interface IHandler<THost> where THost : IFormatterX
    {
        /// <summary>宿主读写器</summary>
        THost Host { get; set; }

        /// <summary>优先级</summary>
        Int32 Priority { get; set; }

        /// <summary>写入一个对象</summary>
        /// <param name="value">目标对象</param>
        /// <param name="type">类型</param>
        /// <returns></returns>
        Boolean Write(Object value, Type type);

        /// <summary>尝试读取指定类型对象</summary>
        /// <param name="type"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        Boolean TryRead(Type type, ref Object value);
    }

    /// <summary>序列化接口</summary>
    public abstract class FormatterBase //: IFormatterX
    {
        #region 属性
        /// <summary>数据流。默认实例化一个内存数据流</summary>
        public virtual Stream Stream { get; set; } = new MemoryStream();

        /// <summary>主对象</summary>
        public Stack<Object> Hosts { get; private set; } = new Stack<Object>();

        /// <summary>成员</summary>
        public MemberInfo Member { get; set; }

        /// <summary>字符串编码,默认utf-8</summary>
        public Encoding Encoding { get; set; } = Encoding.UTF8;

        /// <summary>序列化属性而不是字段。默认true</summary>
        public Boolean UseProperty { get; set; } = true;

        /// <summary>用户对象。存放序列化过程中使用的用户自定义对象</summary>
        public Object UserState { get; set; }
        #endregion

        #region 方法
        /// <summary>获取流里面的数据</summary>
        /// <returns></returns>
        public Byte[] GetBytes()
        {
            var ms = Stream;
            var pos = ms.Position;
            var start = 0;
            if (pos == 0 || pos == start) return new Byte[0];

            if (ms is MemoryStream ms2 && pos == ms.Length && start == 0)
                return ms2.ToArray();

            ms.Position = start;

            var buf = new Byte[pos - start];
            ms.Read(buf, 0, buf.Length);
            return buf;
        }

        /// <summary>获取流里面的数据包</summary>
        /// <returns></returns>
        public Packet GetPacket()
        {
            Stream.Position = 0;
            return new(Stream);
        }
        #endregion

        #region 跟踪日志
        /// <summary>日志提供者</summary>
        public ILog Log { get; set; } = Logger.Null;

        /// <summary>输出日志</summary>
        /// <param name="format"></param>
        /// <param name="args"></param>
        public virtual void WriteLog(String format, params Object[] args) => Log?.Info(format, args);
        #endregion
    }

    /// <summary>读写处理器基类</summary>
    public abstract class HandlerBase<THost, THandler> : IHandler<THost>
        where THost : IFormatterX
        where THandler : IHandler<THost>
    {
        /// <summary>宿主读写器</summary>
        public THost Host { get; set; }

        /// <summary>优先级</summary>
        public Int32 Priority { get; set; }

        /// <summary>写入一个对象</summary>
        /// <param name="value">目标对象</param>
        /// <param name="type">类型</param>
        /// <returns></returns>
        public abstract Boolean Write(Object value, Type type);

        /// <summary>尝试读取指定类型对象</summary>
        /// <param name="type"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public abstract Boolean TryRead(Type type, ref Object value);

        /// <summary>输出日志</summary>
        /// <param name="format"></param>
        /// <param name="args"></param>
        public void WriteLog(String format, params Object[] args) => Host.Log.Info(format, args);
    }
}