C# 实现流读取器 CBytesReader

CBytesReader类

using System;

namespace Common
{
    /// <summary>
    /// author  :   Jave.Lin
    /// date    :   2018-03-24
    /// </summary>
    public class CBytesReader : IDisposable
    {
        public static bool IsLittleEndian // return true
        {
            get { return BitConverter.IsLittleEndian; }
        }

        private int _m_iPos;
        private byte[] _m_pBuffer;
        private int _m_iIdx;
        private int _m_iLen;

        public int iRealPos { get { return _m_iIdx + _m_iPos; } }
        public int iIdx { get { return _m_iIdx; } }
        public int iPos { get { return _m_iPos; }set { _m_iPos = value; } }
        public int iLen { get { return _m_iLen; } }
        public int iRemainFreeSize { get { return _m_iLen - _m_iPos; } }

        public CBytesReader() { }

        public CBytesReader(byte[] buffer, int idx = 0, int len = 0)
        {
            SetBuffer(buffer, idx, len);
        }

        public void Dispose()
        {
            _m_pBuffer = null;
        }

        public void SetBuffer(byte[] buffer, int idx = 0, int len = 0)
        {
            if (buffer == null)
            {
                _m_pBuffer = null;
                _m_iIdx = 0;
                _m_iLen = 0;
            }
            else
            {
                _m_pBuffer = buffer;
                _m_iIdx = idx;
                _m_iLen = len == 0 ? _m_pBuffer.Length : len;
                _checkLen(_m_iLen);
            }
        }

        public void AddLen(int value)
        {
            var preV = _m_iLen + value;
            _checkLen(preV);
        }

        public void SetLen(int len)
        {
            _m_iLen = len;
        }

        /// <summary>
        /// Attention, it will change original-buffer data!
        /// </summary>
        public void TrimReaded()
        {
            var remain = iRemainFreeSize;
            var rpos = iRealPos;
            if (remain > 0 && rpos != _m_iIdx)
            {
                Buffer.BlockCopy(_m_pBuffer, rpos, _m_pBuffer, _m_iIdx, remain);
            }
            _m_iPos = 0;
        }
        public void TrimReaded1(int canRead)
        {
            if (canRead > 0)
            {
                var realPos = iRealPos;
                var canReadPos = realPos + canRead; // real pos + can read len
                Buffer.BlockCopy(_m_pBuffer, realPos, _m_pBuffer, _m_iIdx, canRead);
                //Array.Clear(_m_pBuffer, canRead + _m_iIdx, canReadPos);
            }
            _m_iPos = 0;
        }
        public char ReadChar()
        {
            _checkRemain(2);
            var ret = BitConverter.ToChar(_m_pBuffer, _m_iIdx + _m_iPos);
            _m_iPos += 2;
            return ret;
        }
        public bool ReadBool()
        {
            _checkRemain(1);
            return _m_pBuffer[_m_iIdx + _m_iPos++] != 0;
        }
        public sbyte ReadSByte()
        {
            _checkRemain(1);
            return (sbyte)_m_pBuffer[_m_iIdx + _m_iPos++];
        }
        public byte ReadByte()
        {
            _checkRemain(1);
            return _m_pBuffer[_m_iIdx + _m_iPos++];
        }

        public void ReadBytes(byte[] result, int resultLen, int resultIdx = 0)
        {
            if (result == null)
            {
                _throwErr(this.GetType().FullName + " ReadBytes argument: result == null");
            }
            if ((result.Length - resultIdx) < resultLen)
            {
                _throwErr(this.GetType().FullName + " ReadBytes argument: resultLen too large");
            }
            _checkRemain(resultLen);
            Buffer.BlockCopy(_m_pBuffer, _m_iIdx + _m_iPos, result, resultIdx, resultLen);
            _m_iPos += resultLen;
        }

        public short ReadInt16()
        {
            _checkRemain(2);
            var ret = BitConverter.ToInt16(_m_pBuffer, _m_iIdx + _m_iPos);
            _m_iPos += 2;
            return ret;
        }

        public ushort ReadUInt16()
        {
            _checkRemain(2);
            var ret = BitConverter.ToUInt16(_m_pBuffer, _m_iIdx + _m_iPos);
            _m_iPos += 2;
            return ret;
        }

        public int ReadInt32()
        {
            _checkRemain(4);
            var ret = BitConverter.ToInt32(_m_pBuffer, _m_iIdx + _m_iPos);
            _m_iPos += 4;
            return ret;
        }

        public uint ReadUInt32()
        {
            _checkRemain(4);
            var ret = BitConverter.ToUInt32(_m_pBuffer, _m_iIdx + _m_iPos);
            _m_iPos += 4;
            return ret;
        }

        public long ReadInt64()
        {
            _checkRemain(8);
            var ret = BitConverter.ToInt64(_m_pBuffer, _m_iIdx + _m_iPos);
            _m_iPos += 8;
            return ret;
        }

        public ulong ReadUInt64()
        {
            _checkRemain(8);
            var ret = BitConverter.ToUInt64(_m_pBuffer, _m_iIdx + _m_iPos);
            _m_iPos += 8;
            return ret;
        }

        public float ReadSingle()
        {
            _checkRemain(4);
            var ret = BitConverter.ToSingle(_m_pBuffer, _m_iIdx + _m_iPos);
            _m_iPos += 4;
            return ret;
        }

        public double ReadDouble()
        {
            _checkRemain(8);
            var ret = BitConverter.ToDouble(_m_pBuffer, _m_iIdx + _m_iPos);
            _m_iPos += 8;
            return ret;
        }

        private void _checkRemain(int value)
        {
            if (iRemainFreeSize < value)
            {
                _throwErr(this.GetType().FullName + " EOB (End of Byte[])");
            }
        }

        private void _checkLen(int value)
        {
            if (value > (_m_pBuffer.Length - _m_iIdx))
            {
                _throwErr(this.GetType().FullName + " set read buffer's len larger than buffer.Length");
            }
        }

        private void _throwErr(string errMsg)
        {
            throw new Exception(errMsg);
        }
    }
}

应用

下面的BitConverterExt类,可以在这看到实现

            var one = false;
            var two = true;
            var three = true;
            var four = false;
            var arrBool = new bool[3] { true, false, true };

            var bytes = new byte[200];

            var pos = 0;
            BitConverterExt.GetBytes(bytes, one, 0);
            BitConverterExt.GetBytes(bytes, two, pos += sizeof(bool));
            BitConverterExt.GetBytes(bytes, three, pos += sizeof(bool));
            BitConverterExt.GetBytes(bytes, four, pos += sizeof(bool));
            BitConverterExt.GetBytes(bytes, 'a', pos += sizeof(bool));
            BitConverterExt.GetBytes(bytes, arrBool, pos += sizeof(char));
            BitConverterExt.GetBytes(bytes, (ushort)0xf0ff, pos += sizeof(bool) * 3);
            BitConverterExt.GetBytes(bytes, new char[] { 'A', 'B' }, pos += sizeof(ushort));
            BitConverterExt.GetBytes(bytes, new ushort[] { 0xff, 0x8 }, pos += sizeof(char) * 2);
            BitConverterExt.GetBytes(bytes, 0xff, pos += sizeof(ushort) * 2);
            BitConverterExt.GetBytes(bytes, 0xffffffu, pos += sizeof(int));
            BitConverterExt.GetBytes(bytes, 0.999f, pos += sizeof(uint));
            BitConverterExt.GetBytes(bytes, 0.999D, pos += sizeof(float));
            BitConverterExt.GetBytes(bytes, new int[] { 1, 2, 3, 4 }, pos += sizeof(double));
            BitConverterExt.GetBytes(bytes, new uint[] { 5, 6, 7, 8 }, pos += sizeof(int) * 4);
            BitConverterExt.GetBytes(bytes, new float[] { 0.1f, 0.2f, 0.3f, 0.4f }, pos += sizeof(uint) * 4);
            BitConverterExt.GetBytes(bytes, new double[] { 0.1d, 0.2d, 0.3d, 0.4d }, pos += sizeof(float) * 4);
            BitConverterExt.GetBytes(bytes, new long[] { 0xff, 0xffff, 0xffffff, 0xffffffff }, pos += sizeof(double) * 4);
            BitConverterExt.GetBytes(bytes, new ulong[] { 0xffff, 0xffffff, 0xffffffff, 0xffffffffff }, pos += sizeof(long) * 4);

            var reader = new CBytesReader(bytes);

输出

+       bytes   {byte[200]} byte[]
        reader.iIdx 0   int
        reader.iLen 200 int
        reader.iPos 183 int
        reader.iRealPos 183 int
        reader.iRemain  17  int
        reader.ReadByte()   1   byte
        reader.ReadByte()   0   byte
        reader.ReadByte()   1   byte
        reader.ReadUInt16() 61695   ushort
        0xf0ff  61695   int
        reader.ReadChar()   65 'A'  char
        reader.ReadChar()   66 'B'  char
        reader.ReadUInt16() 255 ushort
        reader.ReadUInt16() 8   ushort
        reader.ReadUInt32() 255 uint
        reader.ReadUInt32() 16777215    uint
        0xffffffu   16777215    uint
        reader.ReadSingle() 0.999   float
        reader.ReadDouble() 0.999   double
        reader.ReadInt32()  1   int
        reader.ReadInt32()  2   int
        reader.ReadInt32()  3   int
        reader.ReadInt32()  4   int
        reader.ReadUInt32() 5   uint
        reader.ReadUInt32() 6   uint
        reader.ReadUInt32() 7   uint
        reader.ReadUInt32() 8   uint
        reader.ReadSingle() 0.1 float
        reader.ReadSingle() 0.2 float
        reader.ReadSingle() 0.3 float
        reader.ReadSingle() 0.4 float
        reader.ReadDouble() 0.1 double
        reader.ReadDouble() 0.2 double
        reader.ReadDouble() 0.3 double
        reader.ReadDouble() 0.4 double
        reader.ReadInt64()  255 long
        reader.ReadInt64()  65535   long
        reader.ReadInt64()  16777215    long
        reader.ReadInt64()  4294967295  long
        reader.ReadUInt64() 65535   ulong
        reader.ReadUInt64() 16777215    ulong
        reader.ReadUInt64() 4294967295  ulong
        reader.ReadUInt64() 1099511627775   ulong
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值