Data模块数据采集管理功能开发v2

dev-0829
ccongli 1 year ago
parent 8dbdc55399
commit c616fdcbd1

@ -26,7 +26,11 @@ namespace VOL.Core.EFDbContext
&& logLevel == LogLevel.Information)
{
var logContent = formatter(state, exception);
// TODO: 拿到日志内容想怎么玩就怎么玩吧
Console.WriteLine();
Console.ForegroundColor = ConsoleColor.Green; // 字体绿色
Console.WriteLine(logContent);
Console.ResetColor();
}
}
public IDisposable BeginScope<TState>(TState state) => null;

@ -84,11 +84,14 @@ namespace VOL.Core.EFDbContext
{
optionsBuilder.UseSqlServer(connectionString);
}
//默认禁用实体跟踪
// 默认禁用实体跟踪(注释记录EFCore时)
optionsBuilder = optionsBuilder.UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking);
//var loggerFactory = new LoggerFactory();
//loggerFactory.AddProvider(new EFLoggerProvider());
// optionsBuilder.UseLoggerFactory(loggerFactory);
// 记录EFCore产生的SQL语句
var loggerFactory = new LoggerFactory();
loggerFactory.AddProvider(new EFLoggerProvider());
optionsBuilder.UseLoggerFactory(loggerFactory);
base.OnConfiguring(optionsBuilder);
}
protected override void OnModelCreating(ModelBuilder modelBuilder)

@ -0,0 +1,23 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using VOL.Entity.DomainModels;
namespace VOL.Data.IServices.modbus
{
public interface IDataProcessing
{
// 写设备运行数据
bool saveDeviceData(Data_Device device, out string message);
// 写设备生产数据
bool saveProduceData(Data_Produce produce, out string message);
// 写设备性能数据
bool saveEfficiencyData();
}
}

@ -0,0 +1,25 @@
using NModbus;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace VOL.Data.IServices.modbus
{
public interface IModbusService
{
/// <summary>
/// 创建主站客户端
/// </summary>
/// <returns></returns>
void createModbusClient();
/// <summary>
/// 关闭链接
/// </summary>
/// <returns></returns>
void disConnent();
}
}

@ -35,7 +35,15 @@ namespace VOL.Data.Services
_httpContextAccessor = httpContextAccessor;
_repository = dbRepository;
//多租户会用到这init代码其他情况可以不用
//base.Init(dbRepository);
Init(dbRepository);
}
}
//重写ServiceBase Init方法设置IsMultiTenancy=true开启多租户功能
protected override void Init(IRepository<Data_Device> repository)
{
//开启多租户功能,开启后会对查询、导出、删除、编辑功能同时生效
//如果只需要对某个功能生效,如编辑,则在重写编辑方法中设置 IsMultiTenancy = true;
IsMultiTenancy = true;
}
}
}

@ -0,0 +1,92 @@
using Microsoft.AspNetCore.Http;
using VOL.Data.IServices.modbus;
using VOL.Entity.DomainModels;
using VOL.Core.Services;
using Microsoft.AspNetCore.Mvc;
using Autofac.Core;
using VOL.Core.Extensions.AutofacManager;
namespace VOL.Data.Services.modbus
{
public class DataProcessing : IDataProcessing, IDependency // 继承IDependency交给Ioc容器接管
{
private readonly IHttpContextAccessor _httpContextAccessor;
public DataProcessing(IHttpContextAccessor httpContextAccessor) {
_httpContextAccessor = httpContextAccessor;
}
// 写设备运行数据
public bool saveDeviceData(Data_Device device, out string message) {
SaveModel model = new SaveModel();
Dictionary<string, object> mapData = new()
{
{ "temperature", device.temperature ?? 68.0M },
{ "potential", device.potential ?? 220.0M },
{ "current", device.current ?? 24.0M },
{ "processno", device.processno ?? "10092768" },
{ "run_mode", device.run_mode ?? 1 }
};
model.MainData = mapData;
try {
Core.Utilities.WebResponseContent result = Data_DeviceService.Instance.Add(model);
if (!result.Status)
{
message = result.Message;
//Logger.Info(result.Message);
return false;
}
} catch (Exception ex)
{
//Logger.Error(ex.Message);
message = ex.Message;
return false;
}
message = "ok";
return true;
}
// 写设备生产数据
public bool saveProduceData(Data_Produce produce, out string message)
{
SaveModel model = new SaveModel();
Dictionary<string, object> mapData = new()
{
{ "standby_time", produce.standby_time ?? 24 },
{ "run_time", produce.run_time ?? 20 },
{ "status", produce.status ?? 1 },
{ "turnout", produce.turnout ?? 1640 },
{ "turnout_one", produce.turnout_one ?? 450 },
{ "turnout_two", produce.turnout_two ?? 630 },
{ "turnout_three", produce.turnout_three ?? 560 }
};
model.MainData = mapData;
try
{
Core.Utilities.WebResponseContent result = Data_ProduceService.Instance.Add(model);
if (!result.Status)
{
message = result.Message;
return false;
}
}
catch (Exception ex)
{
message = ex.Message;
return false;
}
message = "ok";
return true;
}
// 写设备性能数据
public bool saveEfficiencyData()
{
throw new NotImplementedException();
}
}
}

@ -0,0 +1,102 @@
using NModbus;
using System.Net.Sockets;
using VOL.Data.IServices.modbus;
namespace VOL.Data.Services.modbus
{
public class ModbusTcpService : IModbusService
{
// IP
private string ip { set; get; } = "127.0.0.1";
// 端口
private int port { set; get; } = 502;
// 从站地址
private int slaveNo { set; get; } = 1;
private TcpClient client;
private IModbusMaster modbusMaster;
public ModbusTcpService(string ip, int port) {
this.ip = ip;
this.port = port;
this.client = new TcpClient(ip, port);
this.createModbusClient();
}
public void createModbusClient()
{
ModbusFactory modbusFactory = new();
modbusMaster = modbusFactory.CreateMaster(client);
modbusMaster.Transport.ReadTimeout = 3000; //读超时
modbusMaster.Transport.WriteTimeout = 3000;//写超时
modbusMaster.Transport.Retries = 3;
modbusMaster.Transport.WaitToRetryMilliseconds = 500;//尝试重复连接间隔
}
// 是否已连接
public bool isConnected
{
get => client.Connected;
}
// 读线圈 0x01 0x
public bool[] ReadCoils(byte slaveAddress, ushort startAddress, ushort num)
{
return modbusMaster.ReadCoils(slaveAddress, startAddress, num);
}
// 读离散输入 0x02 1x
public bool[] ReadInputs(byte slaveAddress, ushort startAddress, ushort num)
{
return modbusMaster.ReadInputs(slaveAddress, startAddress, num);
}
// 读保持寄存器 0x03 4x
public ushort[] ReadHoldingRegisters(byte slaveAddress, ushort startAddress, ushort num)
{
return modbusMaster.ReadHoldingRegisters(slaveAddress, startAddress, num);
}
// 读输入寄存器 0x04 3x
public ushort[] ReadInputRegisters(byte slaveAddress, ushort startAddress, ushort num)
{
return modbusMaster.ReadInputRegisters(slaveAddress, startAddress, num);
}
// 写单个线圈 0x05
public void WriteSingleCoil(byte slaveAddress, ushort startAddress, bool value)
{
modbusMaster.WriteSingleCoil(slaveAddress, startAddress, value);
}
// 写单个保持寄存器 0x06
public void WriteSingleRegister(byte slaveAddress, ushort startAddress, ushort value)
{
modbusMaster.WriteSingleRegister(slaveAddress, startAddress, value);
}
// 写多个线圈 0x0F
public void WriteMultipleCoils(byte slaveAddress, ushort startAddress, bool[] value)
{
modbusMaster.WriteMultipleCoils(slaveAddress, startAddress, value);
}
// 写多个保持寄存器 0x10
public void WriteMultipleRegisters(byte slaveAddress, ushort startAddress, ushort[] value)
{
modbusMaster.WriteMultipleRegisters(slaveAddress, startAddress, value);
}
// 关闭Socket
public void disConnent() {
client.Close();
modbusMaster.Dispose();
}
}
}

@ -13,9 +13,11 @@
<ItemGroup>
<Folder Include="IRepositories\" />
<Folder Include="IServices\" />
<Folder Include="Repositories\" />
<Folder Include="Services\" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="NModbus" Version="3.0.80" />
</ItemGroup>
</Project>

@ -3,6 +3,18 @@ using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Authorization;
using System;
using VOL.Core.Filters;
using VOL.Core.Controllers.Basic;
using VOL.Data.IServices.modbus;
using VOL.Data.IServices;
using VOL.Data.Services.modbus;
using Microsoft.Extensions.DependencyInjection;
using Newtonsoft.Json.Linq;
using static System.Reflection.Metadata.BlobBuilder;
using System.Linq;
using System.Collections.Generic;
using VOL.WebApi.Utils;
using VOL.Core.Services;
using VOL.Entity.DomainModels;
namespace VOL.WebApi.Controllers.Data
{
@ -13,17 +25,173 @@ namespace VOL.WebApi.Controllers.Data
[AllowAnonymous]
public class DataCaptureController : Controller
{
private static ModbusTcpService _service; // 静态字段
private readonly IHttpContextAccessor _httpContextAccessor;
private readonly IDataProcessing _dataService; // 业务处理
[ActivatorUtilitiesConstructor]
public DataCaptureController(
//ModbusTcpService service, // ModbusTcpService为有参构造暂时无法注入
IDataProcessing dataService,
IHttpContextAccessor httpContextAccessor
)
{
//_service = service;
_dataService = dataService;
_httpContextAccessor = httpContextAccessor;
}
// 静态构造器 类实例化前调用,且只调用一次
static DataCaptureController()
{
try
{
_service = new ModbusTcpService("127.0.0.1", 502);
Console.WriteLine("master modbus tcp created...");
}
catch (Exception)
{
Console.WriteLine("master modbus tcp connect failed");
}
}
/// <summary>
/// 测试采集接口
/// 测试定时接口
/// </summary>
/// <returns>IActionResult</returns>
//[ApiTask]
[HttpGet, HttpPost, Route("test")]
public IActionResult Test()
{
//Logger.Info("log info test...");
//Logger.Error("log info error...");
Data_Device data_Device = new Data_Device();
bool result = _dataService.saveDeviceData(data_Device, out string message);
Console.WriteLine(message);
Data_Produce data_Produce = new Data_Produce();
bool result2 = _dataService.saveProduceData(data_Produce, out string message1);
Console.WriteLine(message1);
return Content(DateTime.Now.ToString("yyyy-MM-dd HH:mm:sss"));
}
/// <summary>
/// 测试采集接口
/// </summary>
/// <returns>IActionResult</returns>
//[ApiTask]
[HttpGet, HttpPost, Route("getData")]
public IActionResult Collection()
{
Console.WriteLine(_service);
bool isConnected = _service == null ? false : _service.isConnected;
if (!isConnected)
{
try
{
_service.disConnent();
_service = new ModbusTcpService("127.0.0.1", 502);
Console.WriteLine("master modbus tcp reconnect...");
}
catch (Exception)
{
Console.WriteLine("master modbus tcp reconnect failed");
}
isConnected = _service == null ? false : _service.isConnected;
if (!isConnected)
{
return Content("master modbus connect failed!");
}
}
try {
// 读Int16
ushort[] us1 = _service.ReadHoldingRegisters(1, 9, 1);
short v = DataConvertUtil.GetShort(us1, 0);
Console.WriteLine("Short Data" + v);
// 读Float
ushort[] us2 = _service.ReadHoldingRegisters(1, 1, 2);
float f = DataConvertUtil.GetReal(us2, 0);
Console.WriteLine("Real Data" + f);
// 读Bool
ushort[] us3 = _service.ReadHoldingRegisters(1, 11, 1);
bool[] bs = DataConvertUtil.GetBools(us3,0,1);
Console.WriteLine("Bools Data" + String.Join(",",bs));
// 写String
ushort[] src = new ushort[6];
DataConvertUtil.SetString(src, 0, "你好世界"); // UTF8 1个中文字符 = 3Byte
_service.WriteMultipleRegisters(1, 30, src);
// 读String
ushort[] target = _service.ReadHoldingRegisters(1, 30, 6);
string str = DataConvertUtil.GetString(target,0,6);
Console.WriteLine("String Data" + str.ToString());
} catch (Exception ex) {
Console.WriteLine(ex.Message);
_service.disConnent();
return Content("read data error!");
}
return Content("ok!");
}
[HttpGet, HttpPost, Route("readTest")]
public IActionResult Test01()
{
if (_service.isConnected)
{
//Console.WriteLine("=========read0x=========");
//bool[] data0x = _service.ReadCoils(1, 0, 5); // 0x
////bool[] bools = { true, false };
//Array.ForEach(data0x, Console.WriteLine);
//Console.WriteLine("=========read0x=========");
//Console.WriteLine("=========read1x=========");
//bool[] data1x = _service.ReadInputs(1, 0, 5);
//Array.ForEach(data1x, Console.WriteLine);
//Console.WriteLine("=========read1x=========");
Console.WriteLine("=========read4x=========");
ushort[] data4xs_int16 = _service.ReadHoldingRegisters(1, 8, 2);
short val = DataConvertUtil.GetShort(data4xs_int16, 1);
Console.WriteLine(val);
ushort[] data4xs_int32 = _service.ReadHoldingRegisters(1, 1, 2);
int vval = DataConvertUtil.GetInt(data4xs_int32, 0);
Console.WriteLine(vval);
ushort[] data4xs_int64 = _service.ReadHoldingRegisters(1, 4, 4);
long vvval = DataConvertUtil.GetLong(data4xs_int64, 0);
Console.WriteLine(vvval);
Console.WriteLine("=========read4x=========");
//Console.WriteLine("=========read3x=========");
//ushort[] data3xs = _service.ReadInputRegisters(1, 4, 2);
//uint[] data3x = data3xs.Select(x => (uint)x).ToArray();
//Array.ForEach(data3x, Console.WriteLine);
//Console.WriteLine("=========read3x=========");
_service.disConnent();
//List<Object> data = new();
//data.Add(data0x);
//data.Add(data1x);
//data.Add(data3x);
//data.Add(data4x);
return Content("read ok");
}
else
{
return Content("Modbus 从站连接失败!");
}
}
}

@ -6,6 +6,8 @@ using Microsoft.AspNetCore.Mvc;
using VOL.Core.Controllers.Basic;
using VOL.Entity.AttributeManager;
using VOL.Data.IServices;
using System;
namespace VOL.Data.Controllers
{
[Route("api/Data_Device")]
@ -15,6 +17,7 @@ namespace VOL.Data.Controllers
public Data_DeviceController(IData_DeviceService service)
: base(service)
{
// 类存在多个构造函数时没有加ActivatorUtilitiesConstructor注解不为指定的执行构造
}
}
}

@ -28,6 +28,7 @@ namespace VOL.Data.Controllers
{
_service = service;
_httpContextAccessor = httpContextAccessor;
//Console.WriteLine("123456789");
}
}
}

@ -17,6 +17,7 @@ namespace VOL.System.Controllers
public Sys_LogController(ISys_LogService service)
: base("System", "System", "Sys_Log", service)
{
// 没有多个构造函数时,执行默认构造
}
}
}

@ -22,7 +22,7 @@ namespace VOL.WebApi
AppContext.SetSwitch("Npgsql.DisableDateTimeInfinityConversions", true);
//CreateHostBuilder(args).Build().Run();
var host = CreateHostBuilder(args).Build();
#region kafka订阅消息
#region kafka订阅消息111
//if (AppSetting.Kafka.UseConsumer)
//{
// using var scope = host.Services.CreateScope();
@ -30,9 +30,9 @@ namespace VOL.WebApi
// testConsumer.Consume(res =>
// {
// Console.WriteLine($"recieve:{DateTime.Now.ToLongTimeString()} value:{res.Message.Value}");
// //静态方法 数据处理 入库等操作
// //静态方法 数据处理 入库等操作
// bool bl = DataHandle.AlarmData(res.Message.Value);
// //回调函数需返回便于执行Commit
// //回调函数需返回便于执行Commit
// return bl;
// }, AppSetting.Kafka.Topics.TestTopic);
//}
@ -40,6 +40,7 @@ namespace VOL.WebApi
host.Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
@ -53,5 +54,26 @@ namespace VOL.WebApi
webBuilder.UseIIS();
webBuilder.UseStartup<Startup>();
}).UseServiceProviderFactory(new AutofacServiceProviderFactory());
//public static async Task Main(string[] args)
//{
// // 创建一个定时器每隔1秒触发一次
// var timer = new Timer(async state =>
// {
// // 在这里编写您的异步任务逻辑
// await Task.Delay(1000);
// Console.WriteLine("异步定时任务执行");
// }, null, TimeSpan.Zero, TimeSpan.FromSeconds(1));
// TimeSpan.Zero 表示定时器立即开始执行TimeSpan.FromSeconds(1) 表示每隔1秒触发一次定时任务。
// // 等待一段时间,观察异步定时任务的执行
// await Task.Delay(5000);
// // 停止定时器
// timer.Dispose();
// Console.WriteLine("定时器已停止");
//}
}
}

@ -0,0 +1,41 @@
using System.Collections.Generic;
namespace VOL.WebApi.Utils
{
public class CommonUtil
{
// 实体对象转Dictionary
public static Dictionary<string, object> ConvertToDictionary<T>(T entity)
{
var dictionary = new Dictionary<string, object>();
var properties = typeof(T).GetProperties();
foreach (var property in properties)
{
var key = property.Name;
var value = property.GetValue(entity);
dictionary.Add(key, value);
}
return dictionary;
}
// Dictionary转实体对象
public static T ConvertToObject<T>(Dictionary<string, object> dictionary) where T : new()
{
var obj = new T();
var properties = typeof(T).GetProperties();
foreach (var property in properties)
{
if (dictionary.TryGetValue(property.Name, out var value))
{
property.SetValue(obj, value);
}
}
return obj;
}
}
}

@ -0,0 +1,305 @@
using System.Text;
using System;
namespace VOL.WebApi.Utils
{
public class DataConvertUtil
{
/// <summary>
/// 赋值string string => ushort[]
/// </summary>
/// <param name="src"></param>
/// <param name="start"></param>
/// <param name="value"></param>
/// <returns></returns>
public static void SetString(ushort[] src, int start, string value)
{
byte[] bytesTemp = Encoding.UTF8.GetBytes(value);
ushort[] dest = Bytes2Ushorts(bytesTemp);
dest.CopyTo(src, start);
}
/// <summary>
/// 获取string ushort[] => string
/// </summary>
/// <param name="src"></param>
/// <param name="start"></param>
/// <param name="len"></param>
/// <returns>string</returns>
public static string GetString(ushort[] src, int start, int len)
{
ushort[] temp = new ushort[len];
for (int i = 0; i < len; i++)
{
temp[i] = src[i + start];
}
byte[] bytesTemp = Ushorts2Bytes(temp);
string res = Encoding.UTF8.GetString(bytesTemp).Trim(new char[] { '\0' });
return res;
}
/// <summary>
/// 赋值Real float => ushort[]
/// </summary>
/// <param name="src"></param>
/// <param name="start"></param>
/// <param name="value"></param>
public static void SetReal(ushort[] src, int start, float value)
{
byte[] bytes = BitConverter.GetBytes(value);
ushort[] dest = Bytes2Ushorts(bytes);
dest.CopyTo(src, start);
}
/// <summary>
/// 获取float ushort[] => float
/// </summary>
/// <param name="src"></param>
/// <param name="start"></param>
/// <returns>float</returns>
public static float GetReal(ushort[] src, int start)
{
try
{
ushort[] temp = new ushort[2];
for (int i = 0; i < 2; i++)
{
temp[i] = src[i + start];
}
byte[] bytesTemp = Ushorts2Bytes(temp,true);
Array.Reverse(bytesTemp);
// BitConverter默认是小端转换如果是大端字节顺序存放需要先反序字节顺序
float res = BitConverter.ToSingle(bytesTemp, 0);
return res;
} catch (Exception e)
{
return 0;
}
}
/// <summary>
/// 赋值Short short => ushort[]
/// </summary>
/// <param name="src"></param>
/// <param name="start"></param>
/// <param name="value"></param>
public static void SetShort(ushort[] src, int start, short value)
{
byte[] bytes = BitConverter.GetBytes(value);
ushort[] dest = Bytes2Ushorts(bytes);
dest.CopyTo(src, start);
}
/// <summary>
/// 获取short ushort[] => short
/// </summary>
/// <param name="src"></param>
/// <param name="start"></param>
/// <returns>short</returns>
public static short GetShort(ushort[] src, int start)
{
try
{
ushort[] temp = new ushort[1];
temp[0] = src[start];
byte[] bytesTemp = Ushorts2Bytes(temp);
short res = BitConverter.ToInt16(bytesTemp, 0);
return res;
}
catch (Exception e)
{
return 0;
}
}
/// <summary>
/// 赋值Short short => ushort[]
/// </summary>
/// <param name="src"></param>
/// <param name="start"></param>
/// <param name="value"></param>
public static void SetInt(ushort[] src, int start, int value)
{
byte[] bytes = BitConverter.GetBytes(value);
ushort[] dest = Bytes2Ushorts(bytes);
dest.CopyTo(src, start);
}
/// <summary>
/// 获取short ushort[] => int
/// </summary>
/// <param name="src"></param>
/// <param name="start"></param>
/// <returns>short</returns>
public static int GetInt(ushort[] src, int start)
{
try {
ushort[] temp = new ushort[2];
temp[0] = src[start];
temp[1] = src[start + 1]; // 0 100
Array.Reverse(temp); // 100 0
byte[] bytesTemp = Ushorts2Bytes(temp);
int res = BitConverter.ToInt32(bytesTemp, 0);
return res;
} catch (Exception e)
{
return 0;
}
}
/// <summary>
/// 获取short ushort[] => long
/// </summary>
/// <param name="src"></param>
/// <param name="start"></param>
/// <returns>short</returns>
public static long GetLong(ushort[] src, int start)
{
try {
ushort[] temp = new ushort[4];
temp[0] = src[start];
temp[1] = src[start + 1];
temp[2] = src[start + 2];
temp[3] = src[start + 3]; // 0 0 0 100
Array.Reverse(temp); // 100 0 0 0
byte[] bytesTemp = Ushorts2Bytes(temp);
long res = BitConverter.ToInt64(bytesTemp, 0);
return res;
} catch (Exception e)
{
return 0;
}
}
/// <summary>
/// 获取bool数组 ushort[] => bool[]
/// </summary>
/// <param name="src"></param>
/// <param name="start"></param>
/// <returns>short</returns>
public static bool[] GetBools(ushort[] src, int start, int num)
{
ushort[] temp = new ushort[num];
for (int i = start; i < start + num; i++)
{
temp[i] = src[i + start];
} // 0 1 0 1 0 0 0 0 默认小端模式
//Array.Reverse(temp); // 0 0 0 0 1 0 1 0
byte[] bytes = Ushorts2Bytes(temp);
bool[] res = Bytes2Bools(bytes);
return res;
}
// byte[] => bool[]
private static bool[] Bytes2Bools(byte[] b)
{
bool[] array = new bool[8 * b.Length];
for (int i = 0; i < b.Length; i++)
{
for (int j = 0; j < 8; j++)
{
array[i * 8 + j] = (b[i] & 1) == 1;//判定byte的最后一位是否为1若为1则是true否则是false
b[i] = (byte)(b[i] >> 1);//将byte右移一位
}
}
return array;
}
// bool[] => byte
private static byte Bools2Byte(bool[] array)
{
if (array != null && array.Length > 0)
{
byte b = 0;
for (int i = 0; i < 8; i++)
{
if (array[i])
{
byte nn = (byte)(1 << i);//左移一位相当于×2
b += nn;
}
}
return b;
}
return 0;
}
// byte[] => ushort[]
private static ushort[] Bytes2Ushorts(byte[] src, bool reverse = false)
{
int len = src.Length;
byte[] srcPlus = new byte[len + 1];
src.CopyTo(srcPlus, 0);
int count = len >> 1;
if (len % 2 != 0)
{
count += 1;
}
ushort[] dest = new ushort[count];
if (reverse)
{
for (int i = 0; i < count; i++)
{
dest[i] = (ushort)(srcPlus[i * 2] << 8 | srcPlus[2 * i + 1] & 0xff);
}
}
else
{
for (int i = 0; i < count; i++)
{
dest[i] = (ushort)(srcPlus[i * 2] & 0xff | srcPlus[2 * i + 1] << 8);
}
}
return dest;
}
// ushort[] => byte[]
private static byte[] Ushorts2Bytes(ushort[] src, bool reverse = false)
{
int count = src.Length;
byte[] dest = new byte[count << 1];
if (reverse)
{
for (int i = 0; i < count; i++)
{
dest[i * 2] = (byte)(src[i] >> 8);
dest[i * 2 + 1] = (byte)(src[i] >> 0);
}
}
else
{
for (int i = 0; i < count; i++)
{
dest[i * 2] = (byte)(src[i] >> 0);
dest[i * 2 + 1] = (byte)(src[i] >> 8);
}
}
return dest;
}
}
}
Loading…
Cancel
Save