using System;
using System.IO;
using System.Text;

namespace WS
{
    ///<summary>流数据操作扩展</summary>
    public static class MemoryStreamHelp
    {
        public static int GetStringCount(this MemoryStream ms)
        {
            return (int)(ms.Length - ms.Position);
        }

        #region Short
            /// <summary>
            /// 从流中读取一个short数据
            /// </summary>
            /// <returns></returns>
            public static short ReadShort(this MemoryStream ms)
        {
            byte[] arr = new byte[2];
            ms.Read(arr, 0, 2);
            return BitConverter.ToInt16(arr, 0);
        }

        /// <summary>
        /// 把一个short数据写入流
        /// </summary>
        /// <param name="value"></param>
        public static void WriteShort(this MemoryStream ms, short value)
        {
            byte[] arr = BitConverter.GetBytes(value);
            ms.Write(arr, 0, arr.Length);
        }
        #endregion

        #region UShort
        /// <summary>
        /// 从流中读取一个ushort数据
        /// </summary>
        /// <returns></returns>
        public static ushort ReadUShort(this MemoryStream ms)
        {
            byte[] arr = new byte[2];
            ms.Read(arr, 0, 2);
            return BitConverter.ToUInt16(arr, 0);
        }

        /// <summary>
        /// 把一个ushort数据写入流
        /// </summary>
        /// <param name="value"></param>
        public static void WriteUShort(this MemoryStream ms, ushort value)
        {
            byte[] arr = BitConverter.GetBytes(value);
            ms.Write(arr, 0, arr.Length);
        }
        #endregion

        #region Int
        /// <summary>
        /// 从流中读取一个int数据
        /// </summary>
        /// <returns></returns>
        public static int ReadInt(this MemoryStream ms)
        {
            byte[] arr = new byte[4];
            ms.Read(arr, 0, 4);
            return BitConverter.ToInt32(arr, 0);
        }

        /// <summary>
        /// 把一个int数据写入流
        /// </summary>
        /// <param name="value"></param>
        public static void WriteInt(this MemoryStream ms, int value)
        {
            byte[] arr = BitConverter.GetBytes(value);
            ms.Write(arr, 0, arr.Length);
        }
        #endregion

        #region UInt
        /// <summary>
        /// 从流中读取一个uint数据
        /// </summary>
        /// <returns></returns>
        public static uint ReadUInt(this MemoryStream ms)
        {
            byte[] arr = new byte[4];
            ms.Read(arr, 0, 4);
            return BitConverter.ToUInt32(arr, 0);
        }

        /// <summary>
        /// 把一个uint数据写入流
        /// </summary>
        /// <param name="value"></param>
        public static void WriteUInt(this MemoryStream ms, uint value)
        {
            byte[] arr = BitConverter.GetBytes(value);
            ms.Write(arr, 0, arr.Length);
        }
        #endregion

        #region Long
        /// <summary>
        /// 从流中读取一个long数据
        /// </summary>
        /// <returns></returns>
        public static long ReadLong(this MemoryStream ms)
        {
            byte[] arr = new byte[8];
            ms.Read(arr, 0, 8);
            return BitConverter.ToInt64(arr, 0);
        }

        /// <summary>
        /// 把一个long数据写入流
        /// </summary>
        /// <param name="value"></param>
        public static void WriteLong(this MemoryStream ms, long value)
        {
            byte[] arr = BitConverter.GetBytes(value);
            ms.Write(arr, 0, arr.Length);
        }
        #endregion

        #region ULong
        /// <summary>
        /// 从流中读取一个ulong数据
        /// </summary>
        /// <returns></returns>
        public static ulong ReadULong(this MemoryStream ms)
        {
            byte[] arr = new byte[8];
            ms.Read(arr, 0, 8);
            return BitConverter.ToUInt64(arr, 0);
        }

        /// <summary>
        /// 把一个ulong数据写入流
        /// </summary>
        /// <param name="value"></param>
        public static void WriteULong(this MemoryStream ms, ulong value)
        {
            byte[] arr = BitConverter.GetBytes(value);
            ms.Write(arr, 0, arr.Length);
        }
        #endregion

        #region Float
        /// <summary>
        /// 从流中读取一个float数据
        /// </summary>
        /// <returns></returns>
        public static float ReadFloat(this MemoryStream ms)
        {
            byte[] arr = new byte[4];
            ms.Read(arr, 0, 4);
            return BitConverter.ToSingle(arr, 0);
        }

        /// <summary>
        /// 把一个float数据写入流
        /// </summary>
        /// <param name="value"></param>
        public static void WriteFloat(this MemoryStream ms, float value)
        {
            byte[] arr = BitConverter.GetBytes(value);
            ms.Write(arr, 0, arr.Length);
        }
        #endregion

        #region Double
        /// <summary>
        /// 从流中读取一个double数据
        /// </summary>
        /// <returns></returns>
        public static double ReadDouble(this MemoryStream ms)
        {
            byte[] arr = new byte[8];
            ms.Read(arr, 0, 8);
            return BitConverter.ToDouble(arr, 0);
        }

        /// <summary>
        /// 把一个double数据写入流
        /// </summary>
        /// <param name="value"></param>
        public static void WriteDouble(this MemoryStream ms, double value)
        {
            byte[] arr = BitConverter.GetBytes(value);
            ms.Write(arr, 0, arr.Length);
        }
        #endregion

        #region Bool
        /// <summary>
        /// 从流中读取一个bool数据
        /// </summary>
        /// <returns></returns>
        public static bool ReadBool(this MemoryStream ms)
        {
            return ms.ReadByte() == 1;
        }

        /// <summary>
        /// 把一个bool数据写入流
        /// </summary>
        /// <param name="value"></param>
        public static void WriteBool(this MemoryStream ms, bool value)
        {
            ms.WriteByte((byte)(value == true ? 1 : 0));
        }
        #endregion

        #region String_1
        /// <summary>
        /// 从流中读取一个sting数组
        /// </summary>
        /// <returns></returns>
        public static string ReadUTF8String(this MemoryStream ms)
        {
            ushort len = ms.ReadUShort();
            byte[] arr = new byte[len];
            ms.Read(arr, 0, len);
            return Encoding.UTF8.GetString(arr);
        }

        /// <summary>
        /// 把一个string数据写入流
        /// </summary>
        /// <param name="str"></param>
        public static void WriteUTF8String(this MemoryStream ms, string str)
        {
            byte[] arr = Encoding.UTF8.GetBytes(str);
            if (arr.Length > 65535)
            {
                throw new InvalidCastException("字符串超出范围");
            }
            ms.WriteUShort((ushort)arr.Length);
            ms.Write(arr, 0, arr.Length);
        }
        #endregion

        #region String_2

        ///<summary>写入String</summary>
        public static void WriteString(this MemoryStream ms, string str)
        {
            byte[] arr = Encoding.UTF8.GetBytes(str);
            ms.Write(arr, 0, arr.Length);
        }

        ///<summary>读取String</summary>
        public static string ReadString(this MemoryStream ms, int len)
        {
            byte[] arr = new byte[len];
            ms.Read(arr, 0, len);
            return Encoding.UTF8.GetString(arr);
        }

        #endregion
    }
}
