C# 缓冲区操作 字节数组操作

using System;
using System.IO;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;




namespace Public
{
   public unsafe class BufferPip 
    {
        public static int DefaultSize = 1024;


        internal byte[] Buffer;
        protected int m_Read = 0;
        protected int m_Write = 0;


        public BufferPip()
            : this(DefaultSize)
        {
        }


        public BufferPip(int bufferSize)
        {
            Buffer = new Byte[bufferSize];
        }


        public BufferPip(byte[] bf)
        {
            Buffer = bf;
            m_Read = 0;
            m_Write = bf.Length;
        }


        public int OffsetGet
        {
            get { return m_Read; }
        }


        public BufferPip CopyDeep()
        {
            int len = this.Buffer.Length;
            BufferPip pip = new BufferPip(len);
            System.Buffer.BlockCopy(this.Buffer, 0, pip.Buffer, 0, len);
            pip.m_Read = this.m_Read;
            pip.m_Write = this.m_Write;
            return pip;
        }


        public BufferPip CopyUsable()
        {
            int len = this.Count;
            BufferPip pip = new BufferPip(len);
            System.Buffer.BlockCopy(this.Buffer, m_Read, pip.Buffer, 0, len);
            pip.m_Read = 0;
            pip.m_Write = len;
            return pip;
        }


        public BufferPip CopyUsable(byte[] addFront)
        {
            int len = this.Count;
            len += addFront.Length;
            BufferPip rT = new BufferPip(len);
            rT.Write(addFront);
            rT.Write(this);
            return rT;
        }


        public BufferPip(byte[] bf, int offset, int count)
        {
            Buffer = bf;
            m_Read = offset;
            m_Write = count;
        }


        /// <summary>
        /// 向当前读取位置之前插入数据,如果空间不够,那么将有效数据后移
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="structure"></param>
        public void Insert<T>(ref T structure)
        {
            int writePos;
            int size = Marshal.SizeOf(typeof(T));
            if (m_Read < size)
            {
                int copyLen = this.Count;
                System.Buffer.BlockCopy(this.Buffer, m_Read, this.Buffer, size, copyLen);
                writePos = 0;
                m_Read = 0;
                m_Write = size + copyLen;
            }
            else
                writePos = m_Read - size;
            fixed (byte* p = Buffer)
            {
                IntPtr aP = new IntPtr(p + writePos);
                Marshal.StructureToPtr(structure, aP, true);
            }
        }


        /// <summary>
        /// 忽略asci2编码 40以下的控制字符
        /// </summary>
        public void SkipChar40()
        {
            for (int i = this.m_Read; i < this.m_Write; i++)
            {
                if(this.Buffer[i] >= 40)
                {
                    this.m_Read = i;
                    return;
                }
            }
            this.Clear();
        }


        public void Read(MMAPSegment mms, int len)
        {//从buffer中读取len到MMAPSegment
            mms.Write(this.Buffer,m_Read,len);
            m_Read += len;
        }


        public void Read<T>(out T structure) //where T : struct
        {
            fixed (byte* p = Buffer)
            {
                IntPtr inP = new IntPtr(p+m_Read);
                structure = (T)Marshal.PtrToStructure(inP, typeof(T));
                m_Read += Marshal.SizeOf(typeof(T));
            }
        }


        /// <summary>
        /// 需要对数据进行二次处理时设置。
        /// begin是要重复使用数据的开始位置。
        /// </summary>
        /// <param name="begin"></param>
        public void SetReUse(int begin, int end)
        {
            m_Write = end;
            m_Read = begin;
        }


        /// <summary>
        /// 不改变结束位置,将开始位置重置。
        /// </summary>
        /// <param name="pos"></param>
        public void ReSetRead(int pos)
        {
            m_Read = pos;
        }


        public void FetchJoin(IList<ArraySegment<byte>> AS)
        {
            AS.Add(new ArraySegment<byte>(this.Buffer, this.m_Read, this.Count));
        }


        public int FetchInt(int pos)
        {
            return BitConverter.ToInt32(Buffer, pos);
        }


        public void Fetch(BufferPip pip, int len)
        {
            pip.Write(this.Buffer, this.m_Read, len);
        }


        public void FetchLast(BufferPip pip, int len)
        {
            int readBegin = this.m_Write - len;
            if (readBegin < m_Read)
                throw new Exception("Buffer Data Overflow  -zero");


            pip.Write(this.Buffer, readBegin, len);
        }


        /// <summary>
        /// 判断缓冲区的内容是否相等64位
        /// </summary>
        /// <returns></returns>
        public bool IsSame(BufferPip pip, int len)
        {
            return IsSame(pip.Buffer, pip.m_Read, len);
        }


        /// <summary>
        /// 判断缓冲区的内容是否相等64位
        /// </summary>
        public bool IsSame(byte[] value, int offset, int len)
        {
            fixed (byte* p1 = this.Buffer)
            fixed (byte* p2 = value)
            {
                return MMAPSegment.MemeryCompare(p1, p2, len) == IntPtr.Zero;
            }
        }


        public bool IsSame(IntPtr p, int len)
        {
            byte* t = (byte*)p.ToPointer();
            fixed (byte* f = this.Buffer)
            {
                return MMAPSegment.MemeryCompare(t, f, len) == IntPtr.Zero;
            }
        }




        public int BufferSize
        {
            get { return Buffer.Length; }
        }


        static void BufferWritOverFlow(BufferPip bp)
        {
            throw new Exception("BUffer WriteOverflow");
        }


        public bool IsOverReaded
        {
            get { return m_Read > m_Write; }
        }


        public int Count
        {
            get
            {
                return m_Write - m_Read;
            }
        }


      
        //剩余可写空间
        public int FreeSpace
        {
            get
            {
                return Buffer.Length - m_Write;//m_Read的空余空间必须在LeftZero后才可使用。
            }
        }


        public void Clear()
        {
            m_Read = 0;
            m_Write = 0;
        }


        //把有效数据左移动
        public void LeftZero()
        {
            int now = Count;
            if (now > 0)
                System.Buffer.BlockCopy(Buffer, m_Read, Buffer, 0, now);
            m_Read = 0;
            m_Write = now;
        }
        


        void OnInitialReadEnd(IAsyncResult aIR)
        {
            object[] param = aIR.AsyncState as object[];
            Stream aS = param[0] as Stream;
            Action<BufferPip> callBack = param[1] as Action<BufferPip>;


            int readed = aS.EndRead(aIR);
            m_Write = readed;
            callBack(this);
        }


        public void SkipToEnd(int toEndLen)
        {
            m_Read = m_Write - toEndLen;
        }


        public void SkipWrite(int len)
        {
            this.m_Write += len;
        }


        public void Write(MMAPSegment mms, int len)
        {
            mms.Read(this.Buffer, 0, len);
            m_Write += len;
        }
        public void Write(MMAPSegment mms, uint len)
        {
            this.Write(mms, (int)len);
        }


        public void Write(BufferPip pip)
        {
            pip.ReadToBuffer(this);
        }


        public void Write(byte[] data, int offset, int len)
        {
            System.Buffer.BlockCopy(data, offset, Buffer, m_Write, len);
            m_Write += len;
        }


        public void Write(byte[] data)
        {
            Write(data, 0, data.Length);
        }


        public void WriteWithClose(Stream aS,int len,Action<BufferPip, Exception> callback)
        {
            aS.BeginWrite(this.Buffer, m_Read, len, (ir) => {
                try
                {
                    aS.EndWrite(ir);
                    if (callback != null)
                        callback(this, null);
                }
                catch(Exception ef)
                {
                    if(callback != null)
                        callback(this,ef);
                }
                finally
                {
                    aS.Close();
                    aS.Dispose();
                }
            }, null);
        }


        //同步读取流数据
        public void WriteStream(Stream aS, int len)
        {
            aS.Read(this.Buffer, m_Write, len);
            m_Write += len;
        }


        public void WriteAsync(Stream aS, Action<BufferPip,Exception> callback)
        {
            WriteAsync(aS, this.FreeSpace, callback);
        }


        public void WriteAsyncOnce(Stream aS, Action<BufferPip,Exception> callback)
        {
            int maxlen =this.FreeSpace;
            aS.BeginRead(this.Buffer, m_Read, maxlen, (air) =>
            {
                int len = aS.EndRead(air);
                if (len <= 0)
                {
                    callback(this, new Exception("流接收端未正常结束,请检查发送端代码。"));
                    return;
                }
                m_Write += len;
                callback(this, null);
            }, null);


        }


        class DataSender
        {
            public BufferPip pip;
            public int Length;
            public Action<BufferPip, Exception> CB;
            public Stream Stream;


            public void WriteFullCallBack(IAsyncResult air)
            {
                try
                {
                    DataSender ds = air.AsyncState as DataSender;
                    int wlen = ds.Stream.EndRead(air);
                    pip.m_Read += wlen;


                    int askedMore = ds.Length - pip.m_Read;


                    if (wlen <= 0)
                    {//读取失败
                        ds.CB(this.pip, new Exception("写入0长度内容"));
                        return;
                    }
                    
                    if (askedMore > 0)
                    {//还需要读取数据
                        this.Stream.BeginRead(pip.Buffer, pip.m_Read, askedMore, this.WriteFullCallBack, this);
                    }
                    else
                    {//完成读取
                        pip.m_Write += wlen;
                        this.CB(this.pip, null);
                    }
                }
                catch (Exception ed)
                {
                    try { this.CB(this.pip, ed); }
                    catch { }
                }
            }
        }
        public void WriteFullAsync(Stream aS, int len, Action<BufferPip, Exception> callback)
        {
            var obj = new DataSender{pip=this,Length = len, CB = callback, Stream = aS };


            aS.BeginRead(this.Buffer, m_Read, len, obj.WriteFullCallBack, obj);
        }
        






        public void WriteAsync(Stream aS, int len, Action<BufferPip,Exception> callback)
        {//不考虑溢出,读取len个字符到buffer
            try
            {
                aS.BeginRead(this.Buffer, m_Read, len, (aIR) =>
                {
                    try
                    {
                        int wlen = aS.EndRead(aIR);
                        int askedMore = len - wlen;


                        if (wlen <= 0)
                        {//读取失败
                            callback(this, new Exception("写入0长度内容,输入流未完成输入即断开"));
                            return;
                        }
                        else if (askedMore > 0)
                        {//还需要读取数据
                            Exception aE = new Exception("写入函数未完全写入即返回,未处理逻辑");
                            callback(this, aE);
                            ErrorLog.Current.LogException(1, "bufferPip.WriteAsync", aE);
                        }
                        else
                        {//完成读取
                            m_Write += len;
                            callback(this, null);
                        }
                    }
                    catch (Exception e)
                    {
                        try
                        {
                            callback(this, e);
                        }
                        catch (Exception inE)
                        {
                            ErrorLog.Current.LogException(1000, "BufferPip.WriteAsync", inE);
                        }
                    }
                }, null);
            }
            catch (Exception outE)
            {
                ErrorLog.Current.LogException(1000, "BufferPip.WriteAsync", outE);
            }
        }


        public void Write(int t)
        {
            fixed (byte* numRef = Buffer)
            {
                int* nowPos = (int*)(numRef + this.m_Write);
                *nowPos = t;
            }
            m_Write += 4;
        }


        public void Write(uint t)
        {
            fixed (byte* numRef = Buffer)
            {
                uint* nowPos = (uint*)(numRef + this.m_Write);
                *nowPos = t;
            }
            m_Write += 4;
        }




        public void Write(long[] datas)
        {
            fixed (byte* numRef = Buffer)
            {
                for (int i = 0; i < datas.Length; i++)
                {
                    long* nowPos = (long*)(numRef + this.m_Write);
                    *nowPos = datas[i];
                    m_Write += 8;
                }
            }
        }


        public void Write(long t)
        {
            fixed (byte* numRef = Buffer)
            {
                long* nowPos = (long*)(numRef + this.m_Write);
                *nowPos = t;
            }
            m_Write += 8;
        }


        public void Write(ulong t)
        {
            fixed (byte* numRef = Buffer)
            {
                ulong* nowPos = (ulong*)(numRef + this.m_Write);
                *nowPos = t;
            }
            m_Write += 8;
        }


        public void Write(short t)
        {
            fixed (byte* numRef = Buffer)
            {
                short* nowPos = (short*)(numRef + this.m_Write);
                *nowPos = t;
            }
            m_Write += 2;
        }


        public void Write(ushort t)
        {
            fixed (byte* numRef = Buffer)
            {
                ushort* nowPos = (ushort*)(numRef + this.m_Write);
                *nowPos = t;
            }
            m_Write += 2;
        }


        public void Write(DateTime t)
        {
            long time = t.ToUniversalTime().Ticks;
            fixed (byte* numRef = Buffer)
            {
                long* nowPos = (long*)(numRef + this.m_Write);
                *nowPos = time;
            }
            m_Write += 8;
        }


        public void Write(double t)
        {
            fixed (byte* numRef = Buffer)
            {
                double* nowPos = (double*)(numRef + this.m_Write);
                *nowPos = t;
            }
            m_Write += 8;
        }


        public void Write(decimal t)
        {
            fixed (byte* numRef = Buffer)
            {
                decimal* nowPos = (decimal*)(numRef + this.m_Write);
                *nowPos = t;
            }
            m_Write += 16;
        }


        public void Write(float t)
        {
            fixed (byte* numRef = Buffer)
            {
                float* nowPos = (float*)(numRef + this.m_Write);
                *nowPos = t;
            }
            m_Write += 4;
        }
        public void Write(byte b)
        {
            Buffer[m_Write++] = b;
        }
        public void Write(bool b)
        {
            Buffer[m_Write++] = (b) ? (byte)255 : (byte)0;
        }


        public int Write<T>(ref T obj)
        {
            fixed (byte* p = Buffer)
            {
                IntPtr inp = new IntPtr(p + m_Write);
                Marshal.StructureToPtr(obj, inp, true);
                int rT = Marshal.SizeOf(typeof(T));
                m_Write += rT;
                return rT;
            }
        }


        public void WriteArray<T>(T[] data)
        {
            int rT = Marshal.SizeOf(typeof(T));
            fixed (byte* p = Buffer)
            {
                for (int i = 0; i < data.Length; i++)
                {
                    IntPtr inp = new IntPtr(p + m_Write);
                    Marshal.StructureToPtr(data[i], inp, true);
                    m_Write += rT;
                }
            }
        }


        /// <summary>
        /// 带分割的内容数组
        /// </summary>
        public void WriteArray<T>(T[] data,ref long sep)
        {
            int rT = Marshal.SizeOf(typeof(T));
            fixed (byte* p = Buffer)
            {
                for (int i = 0; i < data.Length; i++)
                {
                    IntPtr inp = new IntPtr(p + m_Write);
                    Marshal.StructureToPtr(data[i], inp, true);
                    m_Write += rT;


                    long* nowPos = (long*)(p + this.m_Write);
                    long toAppend = sep++;
                    *nowPos = toAppend;
                    m_Write += 8;
                }
            }
        }


        public void Write(IntPtr source, int size)
        {
            Marshal.Copy(source, this.Buffer, m_Write, size);
            m_Write += size;
        }


       


        public void WriteString(System.Text.Encoding encode,string info)
        {
            byte[] byteInfo = encode.GetBytes(info);
            this.Write(byteInfo);
        }


        public void Write(string info, System.Text.Encoding encode)
        {
            byte[] byteInfo = encode.GetBytes(info);
            this.Write(byteInfo);
            this.Write((ushort)0);
        }


        public void SkipRead(int len)
        {
            m_Read = m_Read + len;
        }


        public void ReadToIntPtr(IntPtr p, int len)
        {
            Marshal.Copy(this.Buffer, m_Read, p, len);
            m_Read += len;
        }


        public void ReadToIntPtr(IntPtr p, uint len)
        {
            ReadToIntPtr(p, (int)len);
        }


        public void ReadToBuffer(BufferOperat bff)
        {
            int len = Math.Min(this.Count, bff.FreeSpace);
            ReadToBuffer(bff, len);
        }


        public void ReadToBuffer(BufferOperat bff, int len)
        {
            bff.Write(this.Buffer,m_Read,len);
        }


        public void CheckOverFlow()
        {
            if (this.m_Read > this.m_Write)
                throw new Exception("buffer Read Overflow");
        }


        public byte ReadByte()
        {
            byte rT = Buffer[m_Read];
            m_Read++;
            return rT;
        }


        public short ReadInt16()
        {
            short i = BitConverter.ToInt16(Buffer, m_Read);
            m_Read += 2;
            return i;
        }


        public int ReadInt32()
        {
            int i = BitConverter.ToInt32(Buffer, m_Read);
            m_Read += 4;
            return i;
        }


        public uint ReadUInt32()
        {
            uint i = BitConverter.ToUInt32(Buffer, m_Read);
            m_Read += 4;
            return i;
        }


        public ushort ReadUInt16()
        {
            ushort i = BitConverter.ToUInt16(Buffer, m_Read);
            m_Read += 2;
            return i;
        }


        public long ReadInt64()
        {
            long rT = BitConverter.ToInt64(Buffer, m_Read);
            m_Read += 8;
            return rT;
        }


        public static int SizeOf(Type t)
        {
            return Marshal.SizeOf(t);
        }


        public void ReadToStream(Stream outs)
        {
            outs.Write(Buffer, 0, Buffer.Length);
            this.Clear();
        }
        public void FetchToFile(string path)
        {
            FileStream fs = new FileStream(path, FileMode.CreateNew, FileAccess.Write, FileShare.None);
            fs.Write(this.Buffer, m_Read, (m_Write - m_Read));
        }


        public void FetchToFile(string path,Action<Exception> callback)
        {
            FileStream fs = new FileStream(path, FileMode.CreateNew, FileAccess.Write, FileShare.None);
            fs.BeginWrite(this.Buffer, m_Read, (m_Write - m_Read), (airt) =>
            {
                try
                {
                    fs.EndWrite(airt);
                    callback(null);
                }
                catch (Exception e)
                {
                    callback(e);
                }
            }, null);
        }


        void NullFunction(Exception e)
        {


        }


        public void FetchToFile(string[] path, Action<Exception> callback)
        {
            try
            {
                foreach (string afile in path)
                {
                    this.FetchToFile(afile, NullFunction);
                    System.Threading.Thread.Sleep(0);//切换线程,降低优先级
                }
                callback(null);
            }


            catch (Exception e)
            {
                callback(e);
            }
        }


        class streamTransfer
        {
            public Stream sin;
            public Stream sout;
            public int askLen;
            int ReadedLen=0;
            int lastsendCount;
            public BufferPip pip;
            public Action<BufferPip, Exception> callback;




            public void DoCallBack(Exception e)
            {
                if (askLen == int.MaxValue)
                {
                    sin.Dispose();
                    sin.Close();
                    sout.Dispose();
                    sout.Close();
                }
                callback(pip, e);
            }


            public void DoTransfer()
            {
                try
                {
                    if (pip.Count > 0)
                    {
                        lastsendCount = Math.Min(askLen, pip.Count);
                        sout.BeginWrite(pip.Buffer, pip.m_Read, lastsendCount, OutDataEnded, null);
                    }
                    else
                    {
                        pip.Clear();
                        sin.BeginRead(pip.Buffer, pip.m_Write, pip.FreeSpace, DoReadEnded, null);
                    }
                }
                catch (Exception e)
                {
                    DoCallBack(e);
                }
            }
            void OutDataEnded(IAsyncResult air)
            {
                try
                {
                    sout.EndWrite(air);
                    ReadedLen += lastsendCount;//已经转移完成的字节数
                    int needRead = askLen - ReadedLen;
                    if (needRead <= 0)
                    {//发送完成
                        pip.m_Read += lastsendCount;
                        DoCallBack(null);
                        return;
                    }
                    else
                    {
                        pip.Clear();
                        sin.BeginRead(pip.Buffer, pip.m_Write,pip.Buffer.Length, DoReadEnded, null);
                    }
                }
                catch (Exception e)
                {
                    DoCallBack(e);
                }
            }


            void DoReadEnded(IAsyncResult air)
            {
                try
                {
                    int len = sin.EndRead(air);
                    pip.m_Write += len;


                    if (len == 0)
                    {
                        if (this.askLen == int.MaxValue)
                        {
                            DoCallBack(null);
                        }
                        else
                        {
                            DoCallBack(new Exception("非正常的流结束时间,从源数据读取时失败"));
                        }
                        return;
                    }


                    lastsendCount = Math.Min((askLen - ReadedLen), pip.Count);
                    sout.BeginWrite(pip.Buffer, pip.m_Read, lastsendCount, OutDataEnded, null);
                }
                catch (Exception e)
                {
                    DoCallBack(e);
                }
            }
        }
        /// <summary>
        /// 连接两个stream,把当前缓冲区内的数据+sin中的数据   转移tranLen字节长度  到 sout.
        /// sin可能会多读取数据到缓冲区
        /// </summary>
        /// <param name="sin"></param>
        /// <param name="sout"></param>
        /// <param name="tranLen"></param>
        public void StreamAnsycConnect(Stream si, Stream sou, int tranLen, Action<BufferPip, Exception> callback)
        {
            streamTransfer st = new streamTransfer() { sin = si, sout = sou, pip = this, askLen = tranLen, callback = callback };
            st.DoTransfer();
        }
        //读取输入流,保存到输出流,直到输入流结束
        public void StreamHttpcConnect(Stream si, Stream sou,Action<BufferPip, Exception> callback)
        {
            streamTransfer st = new streamTransfer() { sin = si, sout = sou, pip = this, askLen = int.MaxValue, callback = callback };
            st.DoTransfer();
        }


        public void ReadToStream(Stream outs,int length)
        {
            outs.Write(Buffer, 0, length);
            m_Read += length;
        }


        public void ReadToStreamAsync(Stream outs, Action<Exception> callback)
        {
            ReadStreamAsync(outs, this.Count, callback);
        }
        /// <summary>
        /// 异步写到流,callback不能为空
        /// outs不能在callback完成之前销毁
        /// </summary>
        public void ReadStreamAsync(Stream outs, int len, Action<Exception> callback)
        {
            outs.BeginWrite(this.Buffer, m_Read, len, (aIR) =>
            {
                try
                {
                    outs.EndWrite(aIR);
                    callback(null);
                }
                catch(Exception ed)
                {
                    callback(ed);
                }
            }, null);
            m_Read += len;//无论是否发送成功,都当作已经发送。
        }


        public static bool IsRNFoure(System.Text.Encoding encode)
        {
            return encode.GetBytes("\r\n").Length == 4;
        }


        public static void SetInt64(byte[] bf, int offset, long value)
        {
            fixed (byte* p = bf)
            {
                *(long*)(p + offset) = value;
            }
        }
        public static void SetInt32(byte[] bf, int offset, int value)
        {
            fixed (byte* p = bf)
            {
                *(int*)(p + offset) = value;
            }
        }


        public string ReadStringAbsolut(System.Text.Encoding encode, int bufStart, int bufEnd)
        {
            return encode.GetString(this.Buffer, bufStart, (bufEnd - bufStart));
        }


        public void  ReadToFindEnd(byte[] end,out int bufBegin,out int bufEnd)
        {
            bufBegin = -1;
            bufEnd = -1;
            int tofind = BitConverter.ToInt32(end, 0);
            fixed (byte* p = this.Buffer)
                fixed(byte* cmp = end)
            {
                byte* begin = p + this.m_Read;
                int nowEnd = 0;
                while (true)
                {
                    if (nowEnd + m_Read + 4 > m_Write)
                        return;


                    byte* nowP = begin + nowEnd;
                    if (tofind == (*((int*)(nowP))))
                    {
                        if (MemeryCompare(nowP, cmp, end.Length))
                        {
                            bufBegin = m_Read;
                            m_Read = m_Read + nowEnd + end.Length;
                            bufEnd = m_Read;
                            return;
                        }
                    }
                    nowEnd++;
                }
            }
        }


        public static bool MemeryCompare(byte* pi,byte* p2,int len)
        {
            int pos = 0;
            while ( len - pos  >= 8)
            {
                if ((*(long*)(pi + pos)) != (*(long*)(p2 + pos)))
                    return false;
                pos += 8;
            }


            for (int i = pos; i < len; i++)
            {
                if (pi[i] != p2[i])
                    return false;
            }


            return true;
        }
        public string ReadString(System.Text.Encoding encode)
        {
            return this.ReadString(encode, this.Count);
        }
        public string ReadString(System.Text.Encoding encode, int len)
        {
            string rT = encode.GetString(Buffer, m_Read, len);
            m_Read += len;
            return rT;
        }


        int FindNextLong(long l)
        {
            fixed (byte* p = this.Buffer)
            {
                byte* begin = p + this.m_Read;
                int nowEnd = 0;//m_Read之后的偏移量
                while (true)
                {
                    if (nowEnd + m_Read + 8 > m_Write)
                        return -1;


                    if (l == (*((long*)(begin + nowEnd))))
                    {
                        return nowEnd;
                    }
                    nowEnd++;
                }
            }
        }


        int FindNextInt(int tofind)
        {//返回以m_read为0的偏移量
            fixed (byte* p = this.Buffer)
            {
                byte* begin = p + this.m_Read;
                int nowEnd = 0;
                while (true)
                {
                    if (nowEnd + m_Read + 4 > m_Write)
                        return -1;


                    if (tofind == (*((int*)(begin + nowEnd))))
                    {
                        return nowEnd;
                    }
                    nowEnd++;
                }
            }
        }


        int FindNextByte(byte t)
        {
            fixed (byte* p = this.Buffer)
            {//避免越界检查
                byte* begin = p + this.m_Read;
                int rt = 0;
                while (true)
                {
                    if (rt + m_Read == m_Write)
                        return -1;
                    if (t == *(begin + rt))
                        return rt;
                    rt++;
                }
            }
        }


        int FindNextShort(short toFind)
        {
            fixed (byte* p = this.Buffer)
            {
                byte* begin = p + this.m_Read;
                int nowEnd = 0;
                while (true)
                {
                    if (nowEnd + m_Read + 2 > m_Write)
                        return -1;


                    if (toFind == (*((short*)(begin + nowEnd))))
                    {
                        return nowEnd;
                    }
                    nowEnd++;
                }
            }
        }


        //使用绝对定位获得字符串值
        public string GetAbsolutString(System.Text.Encoding en,int begin,int end)
        {
            return en.GetString(this.Buffer, begin, (end - begin));
        }


        public int IndexLenOf(byte[] data, int offset)
        {
            fixed (byte* src = this.Buffer)
            fixed (byte* tar = data)
            {
                int maxEnd = m_Write-data.Length;
                for (int i = offset; i < maxEnd; i++)
                {
                    for (int j = 0; j < data.Length; j++)
                    {
                        if (Buffer[i + j] != data[j])
                            goto ToContine;
                    }
                    return i;
                ToContine:
                    continue;
                }
            }


            return -1;
        }


        public int IndexLenOf(byte[] data)
        {
            int rt;
            if (data == null || data.Length == 0)
            {
                rt = -1;
            }
            else
            {
                switch (data.Length)
                {
                    case 1: rt = this.FindNextByte(data[0]); break;
                    case 2: rt = this.FindNextShort(BitConverter.ToInt16(data, 0)); break;
                    case 4: rt = this.FindNextInt(BitConverter.ToInt32(data, 0)); break;
                    case 8: rt = this.FindNextLong(BitConverter.ToInt64(data, 0)); break;
                    default:
                        if (data.Length > 8)
                        {
                            long l = BitConverter.ToInt64(data, 0);
                            fixed (byte* p = this.Buffer)
                            {
                                byte* begin = p + this.m_Read;
                                rt = 0;
                                while (true)
                                {
                                LoopBegin:
                                    if (rt + m_Read + 8 > m_Write)
                                    {
                                        rt = -1;
                                        break;
                                    }


                                    if (l == (*((long*)(begin + rt))))
                                    {
                                        for (int i = 4; i < data.Length; i++)
                                        {//long相同的概率非常低,这里不考虑优化。
                                            if (data[i] != *(begin + rt + i))
                                            {
                                                goto LoopBegin;
                                            }
                                        }
                                        goto LoopOut;
                                    }
                                    rt++;
                                }
                            LoopOut:
                                ;
                            }
                        }
                        else
                            throw new Exception("不支持的长度");
                        break;
                }
            }


            if (rt < 0)
                return rt;
            return rt;
        }


        /// <summary>
        /// 返回说明:
        ///  string 发现一个\r\n
        ///  ""   有连续的\r\n
        ///  null  没有结束的\r\n,但缓冲区可能还有数据。
        /// </summary>
        public string ReadLine(System.Text.Encoding encode, bool rnFoure)
        {
            int offset;
            if (rnFoure)
            {//4字节 回车换行
                offset = FindNextInt(655373);
            }
            else
            {//2字节 回车换行
                offset = FindNextShort(2573);
            }


            if (offset < 0)
                return null;
            int readBegin = m_Read;
            m_Read = m_Read + offset;
            if (rnFoure)
                m_Read += 4;
            else
                m_Read += 2;
            return encode.GetString(Buffer, readBegin, offset);
        }


        /// <summary>
        /// 将本对象的缓冲区设置到SocketAsyncEventArgs上
        /// </summary>
        /// <param name="e"></param>
        public void ReadSocketBufferFull(System.Net.Sockets.SocketAsyncEventArgs e)
        {
            this.LeftZero();
            e.SetBuffer(this.Buffer, m_Write, this.FreeSpace);
        }


        public void SendSocetBufferFull(System.Net.Sockets.SocketAsyncEventArgs e)
        {
            e.SetBuffer(this.Buffer, m_Read, this.Count);
        }


        public void WriteSoket(System.Net.Sockets.Socket s, Action<BufferPip, System.Net.Sockets.SocketAsyncEventArgs> callback)
        {
            System.Net.Sockets.SocketAsyncEventArgs received
                = new System.Net.Sockets.SocketAsyncEventArgs();
            received.SetBuffer(this.Buffer,m_Write,this.FreeSpace);
            received.UserToken = callback;
            received.Completed -= OnSocketDataReceived;
            received.Completed -= OnSocketDataReceived;
            received.Completed += OnSocketDataReceived;
            if (!s.ReceiveAsync(received))
            {
                OnSocketDataReceived(s, received);
            }
        }
        void OnSocketDataReceived(object sender,System.Net.Sockets.SocketAsyncEventArgs e)
        {
            m_Write += e.BytesTransferred;
            Action<BufferPip, System.Net.Sockets.SocketAsyncEventArgs> 
                cb = e.UserToken as Action<BufferPip, System.Net.Sockets.SocketAsyncEventArgs>;
            cb(this, e);
            this.LeftZero();
            if (e.BytesTransferred > 0)
            {
                System.Net.Sockets.Socket s = sender as System.Net.Sockets.Socket;
                if (!s.ReceiveAsync(e))
                {
                    OnSocketDataReceived(s, e);
                }
            }
        }




        public void ReadToSocket(System.Net.Sockets.Socket s,int len)
        {
            s.BeginSend(this.Buffer, m_Read, len, System.Net.Sockets.SocketFlags.None, null, null);
            m_Read += len;
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值