v9.8.2018.0605   由DataReader直接映射实体列表,以支持netstandard的MySql和SQLite,且提升性能
大石头 authored at 2018-06-05 00:45:23
3.43 KiB
X
using System;

namespace NewLife.Net.Modbus
{
    /// <summary>IO操作助手</summary>
    static class IOHelper
    {
        /// <summary>从字节数组中读取一段数据</summary>
        /// <param name="data"></param>
        /// <param name="offset">偏移</param>
        /// <param name="count">数量</param>
        /// <returns></returns>
        public static Byte[] ReadBytes(this Byte[] data, Int32 offset = 0, Int32 count = -1)
        {
            if (count <= 0) count = data.Length - offset;

            var buf = new Byte[count];
#if MF
            Array.Copy(data, offset, buf, 0, count);
#else
            Buffer.BlockCopy(data, offset, buf, 0, count);
#endif
            return buf;
        }

        /// <summary>从字节数据指定位置读取一个无符号16位整数</summary>
        /// <param name="data"></param>
        /// <param name="offset">偏移</param>
        /// <returns></returns>
        public static UInt16 ReadUInt16(this Byte[] data, Int32 offset = 0)
        {
            return (UInt16)((data[offset] << 8) + data[offset + 1]);
        }

        /// <summary>向字节数组的指定位置写入一个无符号16位整数</summary>
        /// <param name="data"></param>
        /// <param name="offset">偏移</param>
        /// <param name="n"></param>
        /// <returns></returns>
        public static Byte[] WriteUInt16(this Byte[] data, Int32 offset, Int32 n)
        {
            // STM32单片机是小端
            //data[offset] = (Byte)(n & 0xFF);
            //data[offset + 1] = (Byte)(n >> 8);
            // Modbus协议规定大端
            data[offset] = (Byte)(n >> 8);
            data[offset + 1] = (Byte)(n & 0xFF);

            return data;
        }

        /// <summary>向字节数组写入一片数据</summary>
        /// <param name="data"></param>
        /// <param name="srcOffset"></param>
        /// <param name="buf"></param>
        /// <param name="offset">偏移</param>
        /// <param name="count">数量</param>
        /// <returns></returns>
        public static Byte[] Write(this Byte[] data, Int32 srcOffset, Byte[] buf, Int32 offset = 0, Int32 count = -1)
        {
            if (count <= 0) count = data.Length - offset;

#if MF
            Array.Copy(buf, srcOffset, data, offset, count);
#else
            Buffer.BlockCopy(buf, srcOffset, data, offset, count);
#endif
            return data;
        }

        #region CRC
        static readonly UInt16[] crc_ta = new UInt16[16] { 0x0000, 0xCC01, 0xD801, 0x1400, 0xF001, 0x3C00, 0x2800, 0xE401, 0xA001, 0x6C00, 0x7800, 0xB401, 0x5000, 0x9C01, 0x8801, 0x4400, };

        /// <summary>Crc校验</summary>
        /// <param name="data"></param>
        /// <param name="offset">偏移</param>
        /// <param name="count">数量</param>
        /// <returns></returns>
        public static UInt16 Crc(this Byte[] data, Int32 offset, Int32 count = -1)
        {
            if (data == null || data.Length < 1) return 0;

            UInt16 u = 0xFFFF;
            Byte b;

            if (count == 0) count = data.Length - offset;

            for (var i = offset; i < count; i++)
            {
                b = data[i];
                u = (UInt16)(crc_ta[(b ^ u) & 15] ^ (u >> 4));
                u = (UInt16)(crc_ta[((b >> 4) ^ u) & 15] ^ (u >> 4));
            }

            return u;
        }
        #endregion
    }
}