using System.Text;

namespace PlcSiemens.Core.Extension
{
    public static class StreamExtension
    {
        /// <summary>
        /// 压入一个布尔量，当前位置提升1
        /// </summary>
        /// <param name="stream"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public static Stream Push(this Stream stream, bool value)
        {
            //stream.WriteArray()
            return stream;
        }
    }

    /// <summary>编码助手</summary>
    public static class EncodingHelper
    {
        #region 编码检测

        /// <summary>检测文件编码</summary>
        public static Encoding Detect(this string filename)
        {
            using (var fs = File.OpenRead(filename))
            {
                return Detect(fs);
            }
        }

        /// <summary>检测文件编码</summary>
        public static Encoding DetectEncoding(this FileInfo file)
        {
            using (var fs = file.OpenRead())
            {
                return fs.Detect();
            }
        }

        /// <summary>检测数据流编码</summary>
        /// <param name="stream">数据流</param>
        /// <param name="sampleSize">BOM检测失败时用于启发式探索的数据大小</param>
        /// <returns></returns>
        public static Encoding Detect(this Stream stream, long sampleSize = 0x400)
        {
            // 记录数据流原始位置，后面需要复原
            var pos = stream.Position;
            stream.Position = 0;

            // 首先检查BOM
            var boms = new byte[stream.Length > 4 ? 4 : stream.Length];
            stream.Read(boms, 0, boms.Length);

            var encoding = boms.Detect();
            if (encoding != null)
            {
                stream.Position = pos;
                return encoding;
            }

            // BOM检测失败，开始启发式探测
            // 抽查一段字节数组
            var data = new byte[sampleSize > stream.Length ? stream.Length : sampleSize];
            Array.Copy(boms, data, boms.Length);
            if (stream.Length > boms.Length) stream.Read(data, boms.Length, data.Length - boms.Length);
            stream.Position = pos;

            return data.DetectInternal();
        }

        #endregion 编码检测
    }
}
