|
|
|
@ -5,111 +5,96 @@ using System.Collections.Generic; |
|
|
|
using System.Runtime.InteropServices; |
|
|
|
using System.Data.SqlClient; |
|
|
|
|
|
|
|
namespace DataService |
|
|
|
{ |
|
|
|
public static class ExtMethods |
|
|
|
{ |
|
|
|
public static string GetExceptionMsg(this Exception e) |
|
|
|
{ |
|
|
|
namespace DataService { |
|
|
|
public static class ExtMethods { |
|
|
|
public static string GetExceptionMsg(this Exception e) { |
|
|
|
string err = string.Empty; |
|
|
|
Exception exp = e; |
|
|
|
while (exp != null) |
|
|
|
{ |
|
|
|
while (exp != null) { |
|
|
|
err += string.Format("\n {0}", exp.Message); |
|
|
|
exp = exp.InnerException; |
|
|
|
} |
|
|
|
|
|
|
|
err += string.Format("\n {0}", e.StackTrace); |
|
|
|
return err; |
|
|
|
} |
|
|
|
|
|
|
|
public static bool ModifyItemName(this ITag tag, string name) |
|
|
|
{ |
|
|
|
public static bool ModifyItemName(this ITag tag, string name) { |
|
|
|
IDataServer server = tag.Parent.Server; |
|
|
|
lock (server.SyncRoot) |
|
|
|
{ |
|
|
|
lock (server.SyncRoot) { |
|
|
|
int index = server.GetItemProperties(tag.ID); |
|
|
|
if (index < 0) return false; |
|
|
|
var meta = server.MetaDataList[index]; |
|
|
|
if (meta.Name == name) return true; |
|
|
|
server.MetaDataList[index] = new TagMetaData(meta.ID, meta.GroupID, name, meta.Address, meta.DataType, meta.Size, meta.Archive, meta.Maximum, meta.Minimum, meta.Cycle); |
|
|
|
server.MetaDataList[index] = new TagMetaData(meta.ID, meta.GroupID, name, meta.Address, meta.DataType, |
|
|
|
meta.Size, meta.Archive, meta.Maximum, meta.Minimum, meta.Cycle); |
|
|
|
server.RemoveItemIndex(meta.Name); |
|
|
|
server.AddItemIndex(name, tag); |
|
|
|
return true; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
public static SubCondition FindSubConditon(this IAlarmServer server, string sourceName, SubAlarmType alarmType) |
|
|
|
{ |
|
|
|
public static SubCondition |
|
|
|
FindSubConditon(this IAlarmServer server, string sourceName, SubAlarmType alarmType) { |
|
|
|
var conds = server.QueryConditions(sourceName); |
|
|
|
if (conds == null) return SubCondition.Empty; |
|
|
|
foreach (ICondition cond in conds) |
|
|
|
{ |
|
|
|
foreach (ICondition cond in conds) { |
|
|
|
SubCondition sub = cond.FindSubConditon(alarmType); |
|
|
|
if (sub.SubAlarmType == alarmType) |
|
|
|
return sub; |
|
|
|
} |
|
|
|
|
|
|
|
return SubCondition.Empty; |
|
|
|
} |
|
|
|
|
|
|
|
public static SubCondition FindSubConditon(this ICondition cond, SubAlarmType alarmType) |
|
|
|
{ |
|
|
|
public static SubCondition FindSubConditon(this ICondition cond, SubAlarmType alarmType) { |
|
|
|
var subs = cond.SubConditions; |
|
|
|
if (subs != null && subs.Count > 0) |
|
|
|
{ |
|
|
|
foreach (var sub in subs) |
|
|
|
{ |
|
|
|
if (sub.SubAlarmType == alarmType) |
|
|
|
{ |
|
|
|
if (subs != null && subs.Count > 0) { |
|
|
|
foreach (var sub in subs) { |
|
|
|
if (sub.SubAlarmType == alarmType) { |
|
|
|
return sub; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
return SubCondition.Empty; |
|
|
|
} |
|
|
|
|
|
|
|
public static bool HasScaling(this IDataServer server, string tagName) |
|
|
|
{ |
|
|
|
public static bool HasScaling(this IDataServer server, string tagName) { |
|
|
|
ITag tag = server[tagName]; |
|
|
|
if (tag == null) return false; |
|
|
|
int scaleid = server.GetScaleByID(tag.ID); |
|
|
|
return scaleid >= 0; |
|
|
|
} |
|
|
|
|
|
|
|
public static bool HasAlarm(this IDataServer dserver, string sourceName) |
|
|
|
{ |
|
|
|
public static bool HasAlarm(this IDataServer dserver, string sourceName) { |
|
|
|
IAlarmServer server = dserver as IAlarmServer; |
|
|
|
if (server == null) return false; |
|
|
|
List<ICondition> conds = server.ConditionList as List<ICondition>; |
|
|
|
return conds == null || conds.Count == 0 ? false : conds.BinarySearch(new DigitAlarm(0, sourceName)) >= 0; |
|
|
|
} |
|
|
|
|
|
|
|
public static bool HasSubCondition(this IDataServer dserver, string sourceName, SubAlarmType alarmType) |
|
|
|
{ |
|
|
|
public static bool HasSubCondition(this IDataServer dserver, string sourceName, SubAlarmType alarmType) { |
|
|
|
IAlarmServer server = dserver as IAlarmServer; |
|
|
|
if (server == null) return false; |
|
|
|
var conds = server.QueryConditions(sourceName); |
|
|
|
if (conds == null) return false; |
|
|
|
foreach (ICondition cond in conds) |
|
|
|
{ |
|
|
|
foreach (ICondition cond in conds) { |
|
|
|
var subs = cond.SubConditions; |
|
|
|
if (subs != null && subs.Count > 0) |
|
|
|
{ |
|
|
|
foreach (var sub in subs) |
|
|
|
{ |
|
|
|
if (sub.SubAlarmType == alarmType) |
|
|
|
{ |
|
|
|
if (subs != null && subs.Count > 0) { |
|
|
|
foreach (var sub in subs) { |
|
|
|
if (sub.SubAlarmType == alarmType) { |
|
|
|
return true; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
return false; |
|
|
|
} |
|
|
|
|
|
|
|
public static ItemData<object> ReadValueEx(this IReaderWriter reader, DeviceAddress address) |
|
|
|
{ |
|
|
|
switch (address.VarType) |
|
|
|
{ |
|
|
|
public static ItemData<object> ReadValueEx(this IReaderWriter reader, DeviceAddress address) { |
|
|
|
switch (address.VarType) { |
|
|
|
case DataType.BOOL: |
|
|
|
var bit = reader.ReadBit(address); |
|
|
|
return new ItemData<object>(bit.Value, bit.TimeStamp, bit.Quality); |
|
|
|
@ -131,13 +116,12 @@ namespace DataService |
|
|
|
var str = reader.ReadString(address, address.DataSize); |
|
|
|
return new ItemData<object>(str.Value, str.TimeStamp, str.Quality); |
|
|
|
} |
|
|
|
|
|
|
|
return new ItemData<object>(null, 0, QUALITIES.QUALITY_BAD); |
|
|
|
} |
|
|
|
|
|
|
|
public static int WriteValueEx(this IReaderWriter writer, DeviceAddress address, object value) |
|
|
|
{ |
|
|
|
switch (address.VarType) |
|
|
|
{ |
|
|
|
public static int WriteValueEx(this IReaderWriter writer, DeviceAddress address, object value) { |
|
|
|
switch (address.VarType) { |
|
|
|
case DataType.BOOL: |
|
|
|
return writer.WriteBit(address, Convert.ToBoolean(value)); |
|
|
|
case DataType.BYTE: |
|
|
|
@ -153,115 +137,112 @@ namespace DataService |
|
|
|
case DataType.STR: |
|
|
|
return writer.WriteString(address, value.ToString()); |
|
|
|
} |
|
|
|
|
|
|
|
return -1; |
|
|
|
} |
|
|
|
|
|
|
|
public static HistoryData[] BatchRead(DataSource source, params ITag[] itemArray) |
|
|
|
{ |
|
|
|
public static HistoryData[] BatchRead(DataSource source, params ITag[] itemArray) { |
|
|
|
int len = itemArray.Length; |
|
|
|
HistoryData[] values = new HistoryData[len]; |
|
|
|
for (int i = 0; i < len; i++) |
|
|
|
{ |
|
|
|
for (int i = 0; i < len; i++) { |
|
|
|
itemArray[i].Refresh(source); |
|
|
|
values[i].ID = itemArray[i].ID; |
|
|
|
values[i].Value = itemArray[i].Value; |
|
|
|
values[i].TimeStamp = itemArray[i].TimeStamp; |
|
|
|
} |
|
|
|
|
|
|
|
return values; |
|
|
|
} |
|
|
|
|
|
|
|
public static int BatchWrite(IDictionary<ITag, object> items) |
|
|
|
{ |
|
|
|
public static int BatchWrite(IDictionary<ITag, object> items) { |
|
|
|
int rev = 0; |
|
|
|
foreach (var tag in items) |
|
|
|
{ |
|
|
|
foreach (var tag in items) { |
|
|
|
if (tag.Key.Write(tag.Value) < 0) |
|
|
|
rev = -1; |
|
|
|
} |
|
|
|
|
|
|
|
return rev; |
|
|
|
} |
|
|
|
|
|
|
|
public static List<PDUArea> AssignFromPDU(this ICache cacheReader, int PDU, params DeviceAddress[] addrsArr) |
|
|
|
{ |
|
|
|
public static List<PDUArea> AssignFromPDU(this ICache cacheReader, int PDU, params DeviceAddress[] addrsArr) { |
|
|
|
List<PDUArea> rangeList = new List<PDUArea>(); |
|
|
|
int count = addrsArr.Length; |
|
|
|
if (count > 0) |
|
|
|
{ |
|
|
|
if (count > 0) { |
|
|
|
//Array.Sort(addrsArr);
|
|
|
|
DeviceAddress start = addrsArr[0]; |
|
|
|
start.Bit = 0; |
|
|
|
int bitCount = cacheReader.ByteCount; |
|
|
|
if (count > 1) |
|
|
|
{ |
|
|
|
int cacheLength = 0;//缓冲区的大小
|
|
|
|
if (count > 1) { |
|
|
|
int cacheLength = 0; //缓冲区的大小
|
|
|
|
int cacheIndexStart = 0; |
|
|
|
int startIndex = 0; |
|
|
|
DeviceAddress segmentEnd, tagAddress; |
|
|
|
DeviceAddress segmentEnd, |
|
|
|
tagAddress; |
|
|
|
DeviceAddress segmentStart = start; |
|
|
|
for (int j = 1, i = 1; i < count; i++, j++) |
|
|
|
{ |
|
|
|
tagAddress = addrsArr[i];//当前变量地址
|
|
|
|
for (int j = 1, |
|
|
|
i = 1; |
|
|
|
i < count; |
|
|
|
i++, j++) { |
|
|
|
tagAddress = addrsArr[i]; //当前变量地址
|
|
|
|
int offset1 = cacheReader.GetOffset(tagAddress, segmentStart); |
|
|
|
if (offset1 > (PDU / cacheReader.ByteCount)) |
|
|
|
{ |
|
|
|
if (offset1 > (PDU / cacheReader.ByteCount)) { |
|
|
|
segmentEnd = addrsArr[i - 1]; |
|
|
|
int len = cacheReader.GetOffset(segmentEnd, segmentStart); |
|
|
|
len += segmentEnd.DataSize <= bitCount ? 1 : segmentEnd.DataSize / bitCount; |
|
|
|
tagAddress.CacheIndex = (ushort)(cacheIndexStart + len); |
|
|
|
tagAddress.CacheIndex = (ushort) (cacheIndexStart + len); |
|
|
|
addrsArr[i] = tagAddress; |
|
|
|
rangeList.Add(new PDUArea(segmentStart, len, startIndex, j)); |
|
|
|
startIndex += j; j = 0; |
|
|
|
cacheLength += len;//更新缓存长度
|
|
|
|
startIndex += j; |
|
|
|
j = 0; |
|
|
|
cacheLength += len; //更新缓存长度
|
|
|
|
cacheIndexStart = cacheLength; |
|
|
|
segmentStart = tagAddress;//更新数据片段的起始地址
|
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
tagAddress.CacheIndex = (ushort)(cacheIndexStart + offset1); |
|
|
|
segmentStart = tagAddress; //更新数据片段的起始地址
|
|
|
|
} else { |
|
|
|
tagAddress.CacheIndex = (ushort) (cacheIndexStart + offset1); |
|
|
|
addrsArr[i] = tagAddress; |
|
|
|
} |
|
|
|
if (i == count - 1) |
|
|
|
{ |
|
|
|
|
|
|
|
if (i == count - 1) { |
|
|
|
segmentEnd = addrsArr[i]; |
|
|
|
int segmentLength = cacheReader.GetOffset(segmentEnd, segmentStart); |
|
|
|
if (segmentLength > PDU / cacheReader.ByteCount) |
|
|
|
{ |
|
|
|
if (segmentLength > PDU / cacheReader.ByteCount) { |
|
|
|
segmentEnd = addrsArr[i - 1]; |
|
|
|
segmentLength = segmentEnd.DataSize <= bitCount ? 1 : segmentEnd.DataSize / bitCount; |
|
|
|
} |
|
|
|
tagAddress.CacheIndex = (ushort)(cacheIndexStart + segmentLength); |
|
|
|
|
|
|
|
tagAddress.CacheIndex = (ushort) (cacheIndexStart + segmentLength); |
|
|
|
addrsArr[i] = tagAddress; |
|
|
|
segmentLength += segmentEnd.DataSize <= bitCount ? 1 : segmentEnd.DataSize / bitCount; |
|
|
|
rangeList.Add(new PDUArea(segmentStart, segmentLength, startIndex, j + 1)); |
|
|
|
cacheLength += segmentLength; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
cacheReader.Size = cacheLength; |
|
|
|
} |
|
|
|
else |
|
|
|
cacheReader.Size = start.DataSize <= bitCount ? 1 : start.DataSize / bitCount;//改变Cache的Size属性值将创建Cache的内存区域
|
|
|
|
} else |
|
|
|
cacheReader.Size = |
|
|
|
start.DataSize <= bitCount ? 1 : start.DataSize / bitCount; //改变Cache的Size属性值将创建Cache的内存区域
|
|
|
|
} |
|
|
|
|
|
|
|
return rangeList; |
|
|
|
} |
|
|
|
|
|
|
|
//调用前应对地址数组排序(是否加锁?)
|
|
|
|
public static ItemData<Storage>[] PLCReadMultiple(this IPLCDriver plc, ICache cache, DeviceAddress[] addrsArr) |
|
|
|
{ |
|
|
|
public static ItemData<Storage>[] PLCReadMultiple(this IPLCDriver plc, ICache cache, DeviceAddress[] addrsArr) { |
|
|
|
if (addrsArr == null || cache == null || addrsArr.Length == 0) return null; |
|
|
|
int len = addrsArr.Length; |
|
|
|
ItemData<Storage>[] items = new ItemData<Storage>[len]; |
|
|
|
int offset = 0; long now = DateTime.Now.ToFileTime(); |
|
|
|
int offset = 0; |
|
|
|
long now = DateTime.Now.ToFileTime(); |
|
|
|
List<PDUArea> areas = cache.AssignFromPDU(plc.PDU, addrsArr); |
|
|
|
foreach (PDUArea area in areas) |
|
|
|
{ |
|
|
|
byte[] rcvBytes = plc.ReadBytes(area.Start, (ushort)area.Len); |
|
|
|
foreach (PDUArea area in areas) { |
|
|
|
byte[] rcvBytes = plc.ReadBytes(area.Start, (ushort) area.Len); |
|
|
|
Buffer.BlockCopy(rcvBytes, 0, cache.Cache, offset, rcvBytes.Length); |
|
|
|
offset += rcvBytes.Length / cache.ByteCount; |
|
|
|
} |
|
|
|
for (int i = 0; i < len; i++) |
|
|
|
{ |
|
|
|
switch (addrsArr[i].VarType) |
|
|
|
{ |
|
|
|
|
|
|
|
for (int i = 0; i < len; i++) { |
|
|
|
switch (addrsArr[i].VarType) { |
|
|
|
case DataType.BOOL: |
|
|
|
items[i].Value.Boolean = cache.ReadBit(addrsArr[i]).Value; |
|
|
|
break; |
|
|
|
@ -283,63 +264,66 @@ namespace DataService |
|
|
|
var item = cache.ReadString(addrsArr[i], addrsArr[i].DataSize); |
|
|
|
break; |
|
|
|
} |
|
|
|
|
|
|
|
items[i].Quality = QUALITIES.QUALITY_GOOD; |
|
|
|
items[i].TimeStamp = now; |
|
|
|
} |
|
|
|
|
|
|
|
return items; |
|
|
|
} |
|
|
|
|
|
|
|
public static int PLCWriteMultiple(this IPLCDriver plc, ICache cache, DeviceAddress[] addrArr, object[] buffer, int limit) |
|
|
|
{ |
|
|
|
public static int PLCWriteMultiple(this IPLCDriver plc, ICache cache, DeviceAddress[] addrArr, object[] buffer, |
|
|
|
int limit) { |
|
|
|
if (cache == null || addrArr == null || buffer == null || addrArr.Length != buffer.Length) return -1; |
|
|
|
if (addrArr.Length == 1) return plc.WriteValue(addrArr[0], buffer[0]); |
|
|
|
lock (plc)//不锁定会有并发冲突问题;锁定也不能保障绝对安全,如有人现场操作会导致数据刷新
|
|
|
|
lock (plc) //不锁定会有并发冲突问题;锁定也不能保障绝对安全,如有人现场操作会导致数据刷新
|
|
|
|
{ |
|
|
|
List<PDUArea> areas = cache.AssignFromPDU(plc.PDU, addrArr); |
|
|
|
int offset = 0; |
|
|
|
foreach (PDUArea area in areas) |
|
|
|
{ |
|
|
|
byte[] rcvBytes = plc.ReadBytes(area.Start, (ushort)area.Len); |
|
|
|
foreach (PDUArea area in areas) { |
|
|
|
byte[] rcvBytes = plc.ReadBytes(area.Start, (ushort) area.Len); |
|
|
|
if (rcvBytes == null) return -1; |
|
|
|
Buffer.BlockCopy(rcvBytes, 0, cache.Cache, offset, rcvBytes.Length); |
|
|
|
offset += rcvBytes.Length / cache.ByteCount; |
|
|
|
} |
|
|
|
|
|
|
|
DeviceAddress start = addrArr[0]; |
|
|
|
int startIndex = 0; |
|
|
|
int endIndex = 0; |
|
|
|
while (endIndex < addrArr.Length) |
|
|
|
{ |
|
|
|
if (start.Area != addrArr[endIndex].Area || start.DBNumber != addrArr[endIndex].DBNumber || endIndex - startIndex >= limit) |
|
|
|
{ |
|
|
|
for (int i = startIndex; i < endIndex; i++) |
|
|
|
{ |
|
|
|
while (endIndex < addrArr.Length) { |
|
|
|
if (start.Area != addrArr[endIndex].Area || start.DBNumber != addrArr[endIndex].DBNumber || |
|
|
|
endIndex - startIndex >= limit) { |
|
|
|
for (int i = startIndex; i < endIndex; i++) { |
|
|
|
cache.WriteValue(addrArr[i], buffer[i]); |
|
|
|
} |
|
|
|
int c1 = start.CacheIndex; int c2 = addrArr[endIndex - 1].CacheIndex; |
|
|
|
|
|
|
|
int c1 = start.CacheIndex; |
|
|
|
int c2 = addrArr[endIndex - 1].CacheIndex; |
|
|
|
byte[] bytes = new byte[cache.ByteCount * (c2 - c1 + 1)]; |
|
|
|
Buffer.BlockCopy(cache.Cache, c1, bytes, 0, bytes.Length); |
|
|
|
if (plc.WriteBytes(start, bytes) < 0) return -1; |
|
|
|
start = addrArr[endIndex]; |
|
|
|
startIndex = endIndex; |
|
|
|
} |
|
|
|
|
|
|
|
endIndex++; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// string RightFrom
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="text"></param>
|
|
|
|
/// <param name="length"></param>
|
|
|
|
/// <returns></returns>
|
|
|
|
public static string RightFrom(this string text, int index) |
|
|
|
{ |
|
|
|
public static string RightFrom(this string text, int index) { |
|
|
|
return text.Substring(index + 1, text.Length - index - 1); |
|
|
|
} |
|
|
|
|
|
|
|
public static string Right(this string text, int length) |
|
|
|
{ |
|
|
|
public static string Right(this string text, int length) { |
|
|
|
return text.Substring(text.Length - length, length); |
|
|
|
} |
|
|
|
|
|
|
|
@ -348,16 +332,12 @@ namespace DataService |
|
|
|
/// </summary>
|
|
|
|
/// <param name="filetime"></param>
|
|
|
|
/// <returns></returns>
|
|
|
|
|
|
|
|
public static DateTime ToDateTime(this long filetime) |
|
|
|
{ |
|
|
|
public static DateTime ToDateTime(this long filetime) { |
|
|
|
return filetime == 0 ? DateTime.Now : DateTime.FromFileTime(filetime); |
|
|
|
} |
|
|
|
|
|
|
|
public static Type ToType(this DataType dataType) |
|
|
|
{ |
|
|
|
switch (dataType) |
|
|
|
{ |
|
|
|
public static Type ToType(this DataType dataType) { |
|
|
|
switch (dataType) { |
|
|
|
case DataType.BOOL: |
|
|
|
return typeof(bool); |
|
|
|
case DataType.BYTE: |
|
|
|
@ -378,15 +358,13 @@ namespace DataService |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
public static string ToFormatString(this int num, int len) |
|
|
|
{ |
|
|
|
public static string ToFormatString(this int num, int len) { |
|
|
|
string str = num.ToString(); |
|
|
|
int off = len - str.Length; |
|
|
|
return off > 0 ? string.Concat(new string('0', off), str) : str; |
|
|
|
} |
|
|
|
|
|
|
|
public static bool IsEquals(this byte[] b1, byte[] b2) |
|
|
|
{ |
|
|
|
public static bool IsEquals(this byte[] b1, byte[] b2) { |
|
|
|
if (b1 == null || b2 == null) return false; |
|
|
|
if (b1.Length != b2.Length) return false; |
|
|
|
for (int i = 0; i < b1.Length; i++) |
|
|
|
@ -395,41 +373,38 @@ namespace DataService |
|
|
|
return true; |
|
|
|
} |
|
|
|
|
|
|
|
public static string ConvertToString(this byte[] bits) |
|
|
|
{ |
|
|
|
public static string ConvertToString(this byte[] bits) { |
|
|
|
char[] chars = new char[bits.Length]; |
|
|
|
for (int i = 0; i < bits.Length; i++) |
|
|
|
{ |
|
|
|
chars[i] = (char)bits[i]; |
|
|
|
for (int i = 0; i < bits.Length; i++) { |
|
|
|
chars[i] = (char) bits[i]; |
|
|
|
} |
|
|
|
|
|
|
|
return new string(chars); |
|
|
|
} |
|
|
|
|
|
|
|
public static byte[] ConvertToArray(this string bits) |
|
|
|
{ |
|
|
|
public static byte[] ConvertToArray(this string bits) { |
|
|
|
var chars = bits.ToCharArray(); |
|
|
|
byte[] arr = new byte[chars.Length]; |
|
|
|
for (int i = 0; i < chars.Length; i++) |
|
|
|
{ |
|
|
|
arr[i] = (byte)chars[i]; |
|
|
|
for (int i = 0; i < chars.Length; i++) { |
|
|
|
arr[i] = (byte) chars[i]; |
|
|
|
} |
|
|
|
|
|
|
|
return arr; |
|
|
|
} |
|
|
|
|
|
|
|
public static int BitSwap(this byte bit) |
|
|
|
{ |
|
|
|
public static int BitSwap(this byte bit) { |
|
|
|
return (bit < 8 ? bit + 8 : bit - 8); |
|
|
|
} |
|
|
|
|
|
|
|
[Obsolete] |
|
|
|
public static Storage ToStorage(this ITag tag, object obj) |
|
|
|
{ |
|
|
|
public static Storage ToStorage(this ITag tag, object obj) { |
|
|
|
Storage value = Storage.Empty; |
|
|
|
var str = obj as string; |
|
|
|
switch (tag.Address.VarType) |
|
|
|
{ |
|
|
|
switch (tag.Address.VarType) { |
|
|
|
case DataType.BOOL: |
|
|
|
value.Boolean = str == null ? Convert.ToBoolean(obj) : str == "0" ? false : str == "1" ? true : bool.Parse(str); |
|
|
|
value.Boolean = str == null ? Convert.ToBoolean(obj) : |
|
|
|
str == "0" ? false : |
|
|
|
str == "1" ? true : bool.Parse(str); |
|
|
|
break; |
|
|
|
case DataType.BYTE: |
|
|
|
value.Byte = Convert.ToByte(obj); |
|
|
|
@ -446,17 +421,16 @@ namespace DataService |
|
|
|
value.Single = Convert.ToSingle(obj); |
|
|
|
break; |
|
|
|
} |
|
|
|
|
|
|
|
return value; |
|
|
|
} |
|
|
|
|
|
|
|
public static byte[] ToByteArray(this ITag tag) |
|
|
|
{ |
|
|
|
switch (tag.Address.VarType) |
|
|
|
{ |
|
|
|
public static byte[] ToByteArray(this ITag tag) { |
|
|
|
switch (tag.Address.VarType) { |
|
|
|
case DataType.BOOL: |
|
|
|
return new byte[] { tag.Value.Boolean ? (byte)1 : (byte)0 }; |
|
|
|
return new byte[] {tag.Value.Boolean ? (byte) 1 : (byte) 0}; |
|
|
|
case DataType.BYTE: |
|
|
|
return new byte[] { tag.Value.Byte }; |
|
|
|
return new byte[] {tag.Value.Byte}; |
|
|
|
case DataType.WORD: |
|
|
|
case DataType.SHORT: |
|
|
|
return BitConverter.GetBytes(tag.Value.Int16); |
|
|
|
@ -471,14 +445,12 @@ namespace DataService |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
public static byte[] ToByteArray(this ITag tag, Storage value) |
|
|
|
{ |
|
|
|
switch (tag.Address.VarType) |
|
|
|
{ |
|
|
|
public static byte[] ToByteArray(this ITag tag, Storage value) { |
|
|
|
switch (tag.Address.VarType) { |
|
|
|
case DataType.BOOL: |
|
|
|
return new byte[] { value.Boolean ? (byte)1 : (byte)0 }; |
|
|
|
return new byte[] {value.Boolean ? (byte) 1 : (byte) 0}; |
|
|
|
case DataType.BYTE: |
|
|
|
return new byte[] { value.Byte }; |
|
|
|
return new byte[] {value.Byte}; |
|
|
|
case DataType.WORD: |
|
|
|
case DataType.SHORT: |
|
|
|
return BitConverter.GetBytes(value.Int16); |
|
|
|
@ -493,10 +465,8 @@ namespace DataService |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
public static object GetValue(this ITag tag, Storage value) |
|
|
|
{ |
|
|
|
switch (tag.Address.VarType) |
|
|
|
{ |
|
|
|
public static object GetValue(this ITag tag, Storage value) { |
|
|
|
switch (tag.Address.VarType) { |
|
|
|
case DataType.BOOL: |
|
|
|
return value.Boolean; |
|
|
|
case DataType.BYTE: |
|
|
|
@ -516,42 +486,35 @@ namespace DataService |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
public static float ValueToScale(this ITag tag, float value) |
|
|
|
{ |
|
|
|
public static float ValueToScale(this ITag tag, float value) { |
|
|
|
IDataServer srv = tag.Parent.Server; |
|
|
|
int ind = srv.GetScaleByID(tag.ID); |
|
|
|
Scaling meta = ind < 0 ? Scaling.Empty : srv.ScalingList[ind]; |
|
|
|
if (meta.ScaleType == ScaleType.None) |
|
|
|
{ |
|
|
|
if (meta.ScaleType == ScaleType.None) { |
|
|
|
return value; |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
} else { |
|
|
|
double temp = (value - meta.EULo) / (meta.EUHi - meta.EULo); |
|
|
|
if (meta.ScaleType == ScaleType.SquareRoot) |
|
|
|
temp = temp * temp; |
|
|
|
return (meta.RawHi - meta.RawLo) * (float)temp + meta.RawLo; |
|
|
|
return (meta.RawHi - meta.RawLo) * (float) temp + meta.RawLo; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
public static float ScaleToValue(this ITag tag, Storage value) |
|
|
|
{ |
|
|
|
public static float ScaleToValue(this ITag tag, Storage value) { |
|
|
|
DataType type = tag.Address.VarType; |
|
|
|
if (type == DataType.BOOL) return value.Boolean ? 1f : 0f; |
|
|
|
IDataServer srv = tag.Parent.Server; |
|
|
|
int ind = srv.GetScaleByID(tag.ID); |
|
|
|
Scaling meta = ind < 0 ? Scaling.Empty : srv.ScalingList[ind]; |
|
|
|
if (meta.ScaleType == ScaleType.None) |
|
|
|
{ |
|
|
|
switch (type) |
|
|
|
{ |
|
|
|
if (meta.ScaleType == ScaleType.None) { |
|
|
|
switch (type) { |
|
|
|
case DataType.BYTE: |
|
|
|
return (float)value.Byte; |
|
|
|
return (float) value.Byte; |
|
|
|
case DataType.WORD: |
|
|
|
case DataType.SHORT: |
|
|
|
return (float)value.Int16; |
|
|
|
return (float) value.Int16; |
|
|
|
case DataType.INT: |
|
|
|
return (float)value.Int32; |
|
|
|
return (float) value.Int32; |
|
|
|
case DataType.FLOAT: |
|
|
|
return value.Single; |
|
|
|
case DataType.STR: |
|
|
|
@ -559,12 +522,9 @@ namespace DataService |
|
|
|
default: |
|
|
|
return 0f; |
|
|
|
} |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
} else { |
|
|
|
double temp; |
|
|
|
switch (type) |
|
|
|
{ |
|
|
|
switch (type) { |
|
|
|
case DataType.BYTE: |
|
|
|
temp = (value.Byte - meta.RawLo) / (meta.RawHi - meta.RawLo); |
|
|
|
break; |
|
|
|
@ -581,73 +541,57 @@ namespace DataService |
|
|
|
default: |
|
|
|
return 0f; |
|
|
|
} |
|
|
|
|
|
|
|
if (meta.ScaleType == ScaleType.SquareRoot) |
|
|
|
temp = Math.Sqrt(temp); |
|
|
|
return (meta.EUHi - meta.EULo) * (float)temp + meta.EULo; |
|
|
|
return (meta.EUHi - meta.EULo) * (float) temp + meta.EULo; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
public static float ScaleToValue(this ITag tag) |
|
|
|
{ |
|
|
|
public static float ScaleToValue(this ITag tag) { |
|
|
|
return ScaleToValue(tag, tag.Value); |
|
|
|
} |
|
|
|
|
|
|
|
public static string GetTagName(this ITag tag) |
|
|
|
{ |
|
|
|
public static string GetTagName(this ITag tag) { |
|
|
|
IDataServer srv = tag.Parent.Server; |
|
|
|
int ind = srv.GetItemProperties(tag.ID); |
|
|
|
return ind < 0 ? null : srv.MetaDataList[ind].Name; |
|
|
|
} |
|
|
|
|
|
|
|
public static string GetTagName(this IDataServer srv, short id) |
|
|
|
{ |
|
|
|
public static string GetTagName(this IDataServer srv, short id) { |
|
|
|
int ind = srv.GetItemProperties(id); |
|
|
|
return ind < 0 ? null : srv.MetaDataList[ind].Name; |
|
|
|
} |
|
|
|
|
|
|
|
public static TagMetaData GetMetaData(this ITag tag) |
|
|
|
{ |
|
|
|
public static TagMetaData GetMetaData(this ITag tag) { |
|
|
|
IDataServer srv = tag.Parent.Server; |
|
|
|
int index = srv.GetItemProperties(tag.ID); |
|
|
|
return index < 0 ? new TagMetaData() : srv.MetaDataList[index]; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
public static class Utility |
|
|
|
{ |
|
|
|
public static class Utility { |
|
|
|
private static readonly ushort[] crcTable = { |
|
|
|
0X0000, 0XC0C1, 0XC181, 0X0140, 0XC301, 0X03C0, 0X0280, 0XC241, |
|
|
|
0XC601, 0X06C0, 0X0780, 0XC741, 0X0500, 0XC5C1, 0XC481, 0X0440, |
|
|
|
0XCC01, 0X0CC0, 0X0D80, 0XCD41, 0X0F00, 0XCFC1, 0XCE81, 0X0E40, |
|
|
|
0X0A00, 0XCAC1, 0XCB81, 0X0B40, 0XC901, 0X09C0, 0X0880, 0XC841, |
|
|
|
0XD801, 0X18C0, 0X1980, 0XD941, 0X1B00, 0XDBC1, 0XDA81, 0X1A40, |
|
|
|
0X1E00, 0XDEC1, 0XDF81, 0X1F40, 0XDD01, 0X1DC0, 0X1C80, 0XDC41, |
|
|
|
0X1400, 0XD4C1, 0XD581, 0X1540, 0XD701, 0X17C0, 0X1680, 0XD641, |
|
|
|
0XD201, 0X12C0, 0X1380, 0XD341, 0X1100, 0XD1C1, 0XD081, 0X1040, |
|
|
|
0XF001, 0X30C0, 0X3180, 0XF141, 0X3300, 0XF3C1, 0XF281, 0X3240, |
|
|
|
0X3600, 0XF6C1, 0XF781, 0X3740, 0XF501, 0X35C0, 0X3480, 0XF441, |
|
|
|
0X3C00, 0XFCC1, 0XFD81, 0X3D40, 0XFF01, 0X3FC0, 0X3E80, 0XFE41, |
|
|
|
0XFA01, 0X3AC0, 0X3B80, 0XFB41, 0X3900, 0XF9C1, 0XF881, 0X3840, |
|
|
|
0X2800, 0XE8C1, 0XE981, 0X2940, 0XEB01, 0X2BC0, 0X2A80, 0XEA41, |
|
|
|
0XEE01, 0X2EC0, 0X2F80, 0XEF41, 0X2D00, 0XEDC1, 0XEC81, 0X2C40, |
|
|
|
0XE401, 0X24C0, 0X2580, 0XE541, 0X2700, 0XE7C1, 0XE681, 0X2640, |
|
|
|
0X2200, 0XE2C1, 0XE381, 0X2340, 0XE101, 0X21C0, 0X2080, 0XE041, |
|
|
|
0XA001, 0X60C0, 0X6180, 0XA141, 0X6300, 0XA3C1, 0XA281, 0X6240, |
|
|
|
0X6600, 0XA6C1, 0XA781, 0X6740, 0XA501, 0X65C0, 0X6480, 0XA441, |
|
|
|
0X6C00, 0XACC1, 0XAD81, 0X6D40, 0XAF01, 0X6FC0, 0X6E80, 0XAE41, |
|
|
|
0XAA01, 0X6AC0, 0X6B80, 0XAB41, 0X6900, 0XA9C1, 0XA881, 0X6840, |
|
|
|
0X7800, 0XB8C1, 0XB981, 0X7940, 0XBB01, 0X7BC0, 0X7A80, 0XBA41, |
|
|
|
0XBE01, 0X7EC0, 0X7F80, 0XBF41, 0X7D00, 0XBDC1, 0XBC81, 0X7C40, |
|
|
|
0XB401, 0X74C0, 0X7580, 0XB541, 0X7700, 0XB7C1, 0XB681, 0X7640, |
|
|
|
0X7200, 0XB2C1, 0XB381, 0X7340, 0XB101, 0X71C0, 0X7080, 0XB041, |
|
|
|
0X5000, 0X90C1, 0X9181, 0X5140, 0X9301, 0X53C0, 0X5280, 0X9241, |
|
|
|
0X9601, 0X56C0, 0X5780, 0X9741, 0X5500, 0X95C1, 0X9481, 0X5440, |
|
|
|
0X9C01, 0X5CC0, 0X5D80, 0X9D41, 0X5F00, 0X9FC1, 0X9E81, 0X5E40, |
|
|
|
0X5A00, 0X9AC1, 0X9B81, 0X5B40, 0X9901, 0X59C0, 0X5880, 0X9841, |
|
|
|
0X8801, 0X48C0, 0X4980, 0X8941, 0X4B00, 0X8BC1, 0X8A81, 0X4A40, |
|
|
|
0X4E00, 0X8EC1, 0X8F81, 0X4F40, 0X8D01, 0X4DC0, 0X4C80, 0X8C41, |
|
|
|
0X4400, 0X84C1, 0X8581, 0X4540, 0X8701, 0X47C0, 0X4680, 0X8641, |
|
|
|
0X8201, 0X42C0, 0X4380, 0X8341, 0X4100, 0X81C1, 0X8081, 0X4040 |
|
|
|
0X0000, 0XC0C1, 0XC181, 0X0140, 0XC301, 0X03C0, 0X0280, 0XC241, 0XC601, 0X06C0, 0X0780, 0XC741, 0X0500, |
|
|
|
0XC5C1, 0XC481, 0X0440, 0XCC01, 0X0CC0, 0X0D80, 0XCD41, 0X0F00, 0XCFC1, 0XCE81, 0X0E40, 0X0A00, 0XCAC1, |
|
|
|
0XCB81, 0X0B40, 0XC901, 0X09C0, 0X0880, 0XC841, 0XD801, 0X18C0, 0X1980, 0XD941, 0X1B00, 0XDBC1, 0XDA81, |
|
|
|
0X1A40, 0X1E00, 0XDEC1, 0XDF81, 0X1F40, 0XDD01, 0X1DC0, 0X1C80, 0XDC41, 0X1400, 0XD4C1, 0XD581, 0X1540, |
|
|
|
0XD701, 0X17C0, 0X1680, 0XD641, 0XD201, 0X12C0, 0X1380, 0XD341, 0X1100, 0XD1C1, 0XD081, 0X1040, 0XF001, |
|
|
|
0X30C0, 0X3180, 0XF141, 0X3300, 0XF3C1, 0XF281, 0X3240, 0X3600, 0XF6C1, 0XF781, 0X3740, 0XF501, 0X35C0, |
|
|
|
0X3480, 0XF441, 0X3C00, 0XFCC1, 0XFD81, 0X3D40, 0XFF01, 0X3FC0, 0X3E80, 0XFE41, 0XFA01, 0X3AC0, 0X3B80, |
|
|
|
0XFB41, 0X3900, 0XF9C1, 0XF881, 0X3840, 0X2800, 0XE8C1, 0XE981, 0X2940, 0XEB01, 0X2BC0, 0X2A80, 0XEA41, |
|
|
|
0XEE01, 0X2EC0, 0X2F80, 0XEF41, 0X2D00, 0XEDC1, 0XEC81, 0X2C40, 0XE401, 0X24C0, 0X2580, 0XE541, 0X2700, |
|
|
|
0XE7C1, 0XE681, 0X2640, 0X2200, 0XE2C1, 0XE381, 0X2340, 0XE101, 0X21C0, 0X2080, 0XE041, 0XA001, 0X60C0, |
|
|
|
0X6180, 0XA141, 0X6300, 0XA3C1, 0XA281, 0X6240, 0X6600, 0XA6C1, 0XA781, 0X6740, 0XA501, 0X65C0, 0X6480, |
|
|
|
0XA441, 0X6C00, 0XACC1, 0XAD81, 0X6D40, 0XAF01, 0X6FC0, 0X6E80, 0XAE41, 0XAA01, 0X6AC0, 0X6B80, 0XAB41, |
|
|
|
0X6900, 0XA9C1, 0XA881, 0X6840, 0X7800, 0XB8C1, 0XB981, 0X7940, 0XBB01, 0X7BC0, 0X7A80, 0XBA41, 0XBE01, |
|
|
|
0X7EC0, 0X7F80, 0XBF41, 0X7D00, 0XBDC1, 0XBC81, 0X7C40, 0XB401, 0X74C0, 0X7580, 0XB541, 0X7700, 0XB7C1, |
|
|
|
0XB681, 0X7640, 0X7200, 0XB2C1, 0XB381, 0X7340, 0XB101, 0X71C0, 0X7080, 0XB041, 0X5000, 0X90C1, 0X9181, |
|
|
|
0X5140, 0X9301, 0X53C0, 0X5280, 0X9241, 0X9601, 0X56C0, 0X5780, 0X9741, 0X5500, 0X95C1, 0X9481, 0X5440, |
|
|
|
0X9C01, 0X5CC0, 0X5D80, 0X9D41, 0X5F00, 0X9FC1, 0X9E81, 0X5E40, 0X5A00, 0X9AC1, 0X9B81, 0X5B40, 0X9901, |
|
|
|
0X59C0, 0X5880, 0X9841, 0X8801, 0X48C0, 0X4980, 0X8941, 0X4B00, 0X8BC1, 0X8A81, 0X4A40, 0X4E00, 0X8EC1, |
|
|
|
0X8F81, 0X4F40, 0X8D01, 0X4DC0, 0X4C80, 0X8C41, 0X4400, 0X84C1, 0X8581, 0X4540, 0X8701, 0X47C0, 0X4680, |
|
|
|
0X8641, 0X8201, 0X42C0, 0X4380, 0X8341, 0X4100, 0X81C1, 0X8081, 0X4040 |
|
|
|
}; |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
@ -655,13 +599,12 @@ namespace DataService |
|
|
|
/// </summary>
|
|
|
|
/// <param name="numbers">The byte array</param>
|
|
|
|
/// <returns>An array of ASCII byte values</returns>
|
|
|
|
public static string GetAsciiBytes(byte[] numbers) |
|
|
|
{ |
|
|
|
public static string GetAsciiBytes(byte[] numbers) { |
|
|
|
string str = string.Empty; |
|
|
|
for (int i = 0; i < numbers.Length; i++) |
|
|
|
{ |
|
|
|
for (int i = 0; i < numbers.Length; i++) { |
|
|
|
str += numbers[i].ToString("X2"); |
|
|
|
} |
|
|
|
|
|
|
|
return str; |
|
|
|
} |
|
|
|
|
|
|
|
@ -670,13 +613,12 @@ namespace DataService |
|
|
|
/// </summary>
|
|
|
|
/// <param name="numbers">The ushort array</param>
|
|
|
|
/// <returns>An array of ASCII byte values</returns>
|
|
|
|
public static string GetAsciiBytes(ushort[] numbers) |
|
|
|
{ |
|
|
|
public static string GetAsciiBytes(ushort[] numbers) { |
|
|
|
string str = string.Empty; |
|
|
|
for (int i = 0; i < numbers.Length; i++) |
|
|
|
{ |
|
|
|
for (int i = 0; i < numbers.Length; i++) { |
|
|
|
str += numbers[i].ToString("X4"); |
|
|
|
} |
|
|
|
|
|
|
|
return str; |
|
|
|
} |
|
|
|
|
|
|
|
@ -685,8 +627,7 @@ namespace DataService |
|
|
|
/// </summary>
|
|
|
|
/// <param name="networkBytes">The network order byte array</param>
|
|
|
|
/// <returns>The host order ushort array</returns>
|
|
|
|
public static ushort[] NetworkBytesToHostUInt16(byte[] networkBytes) |
|
|
|
{ |
|
|
|
public static ushort[] NetworkBytesToHostUInt16(byte[] networkBytes) { |
|
|
|
if (networkBytes == null) |
|
|
|
throw new ArgumentNullException("networkBytes"); |
|
|
|
|
|
|
|
@ -696,7 +637,7 @@ namespace DataService |
|
|
|
ushort[] result = new ushort[networkBytes.Length / 2]; |
|
|
|
|
|
|
|
for (int i = 0; i < result.Length; i++) |
|
|
|
result[i] = (ushort)IPAddress.HostToNetworkOrder(BitConverter.ToInt16(networkBytes, i * 2)); |
|
|
|
result[i] = (ushort) IPAddress.HostToNetworkOrder(BitConverter.ToInt16(networkBytes, i * 2)); |
|
|
|
|
|
|
|
return result; |
|
|
|
} |
|
|
|
@ -706,8 +647,7 @@ namespace DataService |
|
|
|
/// </summary>
|
|
|
|
/// <param name="hex">The hex string</param>
|
|
|
|
/// <returns>Array of bytes</returns>
|
|
|
|
public static byte[] HexToBytes(string hex) |
|
|
|
{ |
|
|
|
public static byte[] HexToBytes(string hex) { |
|
|
|
if (string.IsNullOrEmpty(hex)) |
|
|
|
throw new ArgumentNullException("hex"); |
|
|
|
|
|
|
|
@ -727,16 +667,16 @@ namespace DataService |
|
|
|
/// </summary>
|
|
|
|
/// <param name="data">The data used in LRC</param>
|
|
|
|
/// <returns>LRC value</returns>
|
|
|
|
public static byte CalculateLrc(byte[] data, int len = 0) |
|
|
|
{ |
|
|
|
public static byte CalculateLrc(byte[] data, int len = 0) { |
|
|
|
if (data == null) |
|
|
|
throw new ArgumentNullException("data"); |
|
|
|
if (len == 0) len = data.Length; |
|
|
|
byte lrc = 0; |
|
|
|
for (int i = 0; i < len; i++) |
|
|
|
{ lrc += data[i]; } |
|
|
|
for (int i = 0; i < len; i++) { |
|
|
|
lrc += data[i]; |
|
|
|
} |
|
|
|
|
|
|
|
lrc = (byte)((lrc ^ 0xFF) + 1); |
|
|
|
lrc = (byte) ((lrc ^ 0xFF) + 1); |
|
|
|
|
|
|
|
return lrc; |
|
|
|
} |
|
|
|
@ -746,15 +686,13 @@ namespace DataService |
|
|
|
/// </summary>
|
|
|
|
/// <param name="data">The data used in CRC</param>
|
|
|
|
/// <returns>CRC value</returns>
|
|
|
|
public static byte[] CalculateCrc(byte[] data, int len = 0) |
|
|
|
{ |
|
|
|
public static byte[] CalculateCrc(byte[] data, int len = 0) { |
|
|
|
if (data == null) |
|
|
|
throw new ArgumentNullException("data"); |
|
|
|
if (len == 0) len = data.Length; |
|
|
|
ushort crc = ushort.MaxValue; |
|
|
|
for (int i = 0; i < len; i++) |
|
|
|
{ |
|
|
|
byte tableIndex = (byte)(crc ^ data[i]); |
|
|
|
for (int i = 0; i < len; i++) { |
|
|
|
byte tableIndex = (byte) (crc ^ data[i]); |
|
|
|
crc >>= 8; |
|
|
|
crc ^= crcTable[tableIndex]; |
|
|
|
} |
|
|
|
@ -762,50 +700,43 @@ namespace DataService |
|
|
|
return BitConverter.GetBytes(crc); |
|
|
|
} |
|
|
|
|
|
|
|
public static bool CheckSumCRC(byte[] frame) |
|
|
|
{ |
|
|
|
public static bool CheckSumCRC(byte[] frame) { |
|
|
|
int len = frame.Length; |
|
|
|
byte[] chk = CalculateCrc(frame, len - 2); |
|
|
|
return (chk[0] == frame[len - 2] && chk[1] == frame[len - 1]); |
|
|
|
} |
|
|
|
|
|
|
|
public static unsafe short NetToInt16(byte[] value, int startIndex) |
|
|
|
{ |
|
|
|
if (value == null || startIndex > value.Length - 2) |
|
|
|
{ |
|
|
|
public static unsafe short NetToInt16(byte[] value, int startIndex) { |
|
|
|
if (value == null || startIndex > value.Length - 2) { |
|
|
|
throw new NotImplementedException(); |
|
|
|
} |
|
|
|
fixed (byte* numRef = &(value[startIndex])) |
|
|
|
{ |
|
|
|
return (short)((numRef[0] << 8) | numRef[1]); |
|
|
|
|
|
|
|
fixed (byte* numRef = &(value[startIndex])) { |
|
|
|
return (short) ((numRef[0] << 8) | numRef[1]); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
public static unsafe int NetToInt32(byte[] value, int startIndex) |
|
|
|
{ |
|
|
|
if (value == null || startIndex > value.Length - 4) |
|
|
|
{ |
|
|
|
public static unsafe int NetToInt32(byte[] value, int startIndex) { |
|
|
|
if (value == null || startIndex > value.Length - 4) { |
|
|
|
throw new NotImplementedException(); |
|
|
|
} |
|
|
|
fixed (byte* numRef = &(value[startIndex])) |
|
|
|
{ |
|
|
|
return (int)((numRef[0] << 24) | (numRef[1] << 16) | (numRef[2] << 8) | numRef[3]); |
|
|
|
|
|
|
|
fixed (byte* numRef = &(value[startIndex])) { |
|
|
|
return (int) ((numRef[0] << 24) | (numRef[1] << 16) | (numRef[2] << 8) | numRef[3]); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
public static unsafe float NetToSingle(byte[] value, int startIndex) |
|
|
|
{ |
|
|
|
public static unsafe float NetToSingle(byte[] value, int startIndex) { |
|
|
|
int a = NetToInt32(value, startIndex); |
|
|
|
return *(float*)&a; |
|
|
|
return *(float*) &a; |
|
|
|
} |
|
|
|
|
|
|
|
public static string ConvertToString(byte[] bytes, int start = 0, int len = 0) |
|
|
|
{ |
|
|
|
public static string ConvertToString(byte[] bytes, int start = 0, int len = 0) { |
|
|
|
//西门子300、400
|
|
|
|
if (bytes == null || bytes.Length == 0) |
|
|
|
return string.Empty; |
|
|
|
var klen = bytes[start + 1]; |
|
|
|
return Encoding.ASCII.GetString(bytes, start + 2, klen).Trim((char)0); |
|
|
|
return Encoding.ASCII.GetString(bytes, start + 2, klen).Trim((char) 0); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |