-
Notifications
You must be signed in to change notification settings - Fork 50
/
TagInfoPlcMapper.cs
100 lines (78 loc) · 2.98 KB
/
TagInfoPlcMapper.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
// Copyright (c) libplctag.NET contributors
// https://github.com/libplctag/libplctag.NET
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace libplctag.DataTypes
{
public class TagInfo
{
public uint Id { get; set; }
public ushort Type { get; set; }
public string Name { get; set; }
public ushort Length { get; set; }
public uint[] Dimensions { get; set; }
}
public class TagInfoPlcMapper : IPlcMapper<TagInfo[]>
{
const int TAG_STRING_SIZE = 200;
public PlcType PlcType { get; set; }
//TODO: Is null appropriate since it's unknown?
public int? ElementSize => null;
public int[] ArrayDimensions { get => null; set => throw new NotImplementedException("This plcMapper can only be used to read Tag Information"); }
public TagInfo Decode(Tag tag, int offset, out int elementSize)
{
var tagInstanceId = tag.GetUInt32(offset);
var tagType = tag.GetUInt16(offset + 4);
var tagLength = tag.GetUInt16(offset + 6);
var tagArrayDims = new uint[]
{
tag.GetUInt32(offset + 8),
tag.GetUInt32(offset + 12),
tag.GetUInt32(offset + 16)
};
var apparentTagNameLength = (int)tag.GetUInt16(offset + 20);
var actualTagNameLength = Math.Min(apparentTagNameLength, TAG_STRING_SIZE * 2 - 1);
var tagNameBytes = Enumerable.Range(offset + 22, actualTagNameLength)
.Select(o => tag.GetUInt8(o))
.Select(Convert.ToByte)
.ToArray();
var tagName = Encoding.ASCII.GetString(tagNameBytes);
elementSize = 22 + actualTagNameLength;
return new TagInfo()
{
Id = tagInstanceId,
Type = tagType,
Name = tagName,
Length = tagLength,
Dimensions = tagArrayDims
};
}
public TagInfo[] Decode(Tag tag)
{
var buffer = new List<TagInfo>();
var tagSize = tag.GetSize();
int offset = 0;
while (offset < tagSize)
{
buffer.Add(Decode(tag, offset, out int elementSize));
offset += elementSize;
}
return buffer.ToArray();
}
public void Encode(Tag tag, TagInfo[] value)
{
throw new NotImplementedException("This plcMapper can only be used to read Tag Information");
}
public int? GetElementCount()
{
//TODO: We know this value after we decode once. SHould we trigger a decode or cache the value after first decode?
return null;
}
}
}