ByteReader

各位帮忙看看这样写算比较好的方法吗

/**
*┌──────────────────────────────────────────────────────────────┐
*│ 描   述:                                                    
*│ 作   者:blackmaple                                              
*│ 版   本:1.0                                                 
*│ 创建时间:2019/3/2 15:28:55                             
*└──────────────────────────────────────────────────────────────┘
*┌──────────────────────────────────────────────────────────────┐
*│ 命名空间: Common.Packets                                   
*│ 类   名:ByteReader                                      
*└──────────────────────────────────────────────────────────────┘
*/

using DotNetCross.Memory;
using System;
using System.Runtime.InteropServices;
using System.Text;

namespace Common.Packets
{
    public unsafe class ByteReader : IByteReader, IDisposable
    {
        private readonly GCHandle GC_Handle;
        protected byte* _pbuffer;
        protected byte[] _mbuffer { get; set; }
        protected int Capacity { get; set; }
        protected int Offset { get; set; }
        protected bool Disposed { get; set; }
        public short Opcode { get; set; }
        public ByteReader(byte[] _buffer, int _start, int _length)
        {
            if (_buffer == null)
                throw new ArgumentNullException("缓存数据为空");
            if (_start < 0 || _length <= 0)
                throw new ArgumentOutOfRangeException("数据超出范围");
            if (_buffer.Length < _start || _start + _length > _buffer.Length)
                throw new ArgumentOutOfRangeException("数据超出范围");

            GC_Handle = GCHandle.Alloc(_buffer, GCHandleType.Pinned);
            _pbuffer = (byte*)GC_Handle.AddrOfPinnedObject() + _start;
            Capacity = _length;
            _mbuffer = new byte[_length];
            fixed (byte* dst = _mbuffer)
                Unsafe.CopyBlock(dst, _pbuffer, (uint)_length);
            Disposed = false;
            Opcode = ReadShort();
            Offset = 0;
        }

        public ByteReader(byte[] _buffer) : this(_buffer, 0, _buffer.Length) { }

        protected byte* Advance(int count)
        {
            if (Disposed)
                throw new ObjectDisposedException(GetType().FullName);
            if (Offset + count > Capacity)
                throw new IndexOutOfRangeException("数据超出范围");

            var src = _mbuffer;
            var dst = new byte[count];
            fixed (byte* buf = dst)
            {
                Marshal.Copy(src, Offset, (IntPtr)buf, count);
                Offset += count;
                return buf;
            }
        }

        ~ByteReader()
        {
            Dispose();
        }

        public void Dispose()
        {
            if (!Disposed)
            {
                GC_Handle.Free();
                Disposed = true;
            }
        }

        public bool ReadBool()
        {
            return *Advance(1) != 0;
        }

        public byte ReadByte()
        {
            return *Advance(1);
        }

        public byte[] ReadLeftOverBytes()
        {
            return ReadBytes(Capacity - Offset);
        }

        public byte[] ReadBytes(int count)
        {
            var src = Advance(count);
            var data = new byte[count];

            fixed (byte* dst = data)
                Unsafe.CopyBlock(dst, src, (uint)count);

            return data;
        }

        public int ReadInt()
        {
            return *(int*)Advance(4);
        }

        public long ReadLong()
        {
            return *(long*)Advance(8);
        }

        public short ReadShort()
        {
            return *(short*)Advance(2);
        }

        public float ReadSingle()
        {
            return *(float*)Advance(4);
        }

        public double ReadDouble()
        {
            return *(double*)Advance(8);
        }

        public string ReadString(int count = -1)
        {
            return Encoding.Default.GetString(ReadBytes(count == -1 ? ReadShort() : count));
        }

        public void Skip(int count)
        {
            if (count <= 0)
                throw new ArgumentOutOfRangeException("数据超出范围");

            Advance(count);
        }

        public void Reset(int position = 0)
        {
            Offset = position;
        }

        public byte[] GetBuffer()
        {
            return _mbuffer;
        }

        public override string ToString()
        {
            var sb = new StringBuilder(Capacity * 3);
            foreach (var b in GetBuffer())
            {
                sb.AppendFormat("{0:X2} ", b);
            }
            return sb.ToString();
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值