/// <summary> /// Create Raw Read operations for Array Elements /// </summary> private void HandleArray(int offset, PlcArray array, KeyValuePair <string, Tuple <int, PlcObject> > item, PlcRawData pred, string dimension = "") { var arrayOffset = offset; for (var i = array.From; i <= array.To; i++) { var index = $"[{i}]"; var element = array.ArrayType is PlcStruct ? new PlcObjectRef(index, array.ArrayType) : PlcObjectFactory.CreatePlcObjectForArrayIndex(array.ArrayType, i, array.From); var name = $"{item.Key}{index}"; var elemName = string.IsNullOrWhiteSpace(dimension) ? name : $"{dimension}{index}"; if (element is PlcArray) { pred.AddReference(elemName, arrayOffset, element); HandleArray(arrayOffset, element as PlcArray, item, pred, name); arrayOffset += array.ArrayType.Size.Bytes; } else { pred.AddReference(elemName, arrayOffset, element); arrayOffset += array.ArrayType.Size.Bytes; } } }
/// <summary> /// Create Raw Read operations for Array Elements /// </summary> private void HandleArray(int offset, PlcArray array, KeyValuePair <string, Tuple <int, PlcObject> > item, PlcRawData pred, string dimension = "") { var arrayOffset = offset; for (var i = array.From; i <= array.To; i++) { var element = array.ArrayType is PlcStruct ? new PlcObjectRef(string.Format("[{0}]", i), array.ArrayType) : PlcObjectFactory.CreatePlcObjectForArrayIndex(array.ArrayType, i, array.From); if (element is PlcArray) { var elemName = string.IsNullOrWhiteSpace(dimension) ? string.Format("{0}[{1}]", item.Key, i) : dimension + string.Format("[{0}]", i); pred.AddReference(elemName, arrayOffset, element); HandleArray(arrayOffset, element as PlcArray, item, pred, string.Format("{0}[{1}]", item.Key, i)); arrayOffset += array.ArrayType.Size.Bytes; } else { var elemName = string.IsNullOrWhiteSpace(dimension) ? string.Format("{0}[{1}]", item.Key, i) : dimension + string.Format("[{0}]", i); pred.AddReference(elemName, arrayOffset, element); arrayOffset += array.ArrayType.Size.Bytes; } } }
/// <summary> /// Try to get Meta data from MetaTree. If the data are not in the tree, try to create and add it. /// All the calculation of the offsets will be made in this method. the tree has two parts, one for MetaData and one for The Mappings. /// The mappings have only a Reference of the Meta data, so you shouldn't change the Offsets while using. /// </summary> private static PlcObject GetMetaData(ITree tree, Type t) { var nodePathStack = new Stack <string>(); var name = NormalizeTypeName(t.FullName); nodePathStack.Push(RootNodeName); nodePathStack.Push(MetaDataNodeName); nodePathStack.Push(name); var path = PlcMetaDataTreePath.CreateAbsolutePath(nodePathStack.Reverse().ToArray()); var offset = 0; if (!tree.TryGet(path, ref offset, out var obj)) { var byteOffset = 0; var bitOffset = 0; nodePathStack.Pop(); var parent = new PlcStruct(name, t); PlcObject.AddPlcObjectToTree(parent, tree, PlcMetaDataTreePath.CreateAbsolutePath(nodePathStack.Reverse().ToArray())); nodePathStack.Push(parent.Name); PlcObject pred = null; DebugOutPut("{0}{{", name); foreach (var pi in t.GetTypeInfo().DeclaredProperties) { var plcObject = PlcObjectFactory.CreatePlcObject(pi); if (plcObject is PlcArray plcObjectArray && (plcObjectArray.LeafElementType ?? plcObjectArray.ArrayType) is PlcStruct) { plcObjectArray.ArrayType = GetMetaData(tree, plcObjectArray.ElemenType); } else if (plcObject is PlcStruct) { plcObject = new PlcObjectRef(plcObject.Name, GetMetaData(tree, pi.PropertyType)); } var hasCustomOffset = PlcObjectFactory.GetOffsetFromAttribute(pi, ref byteOffset, ref bitOffset); AddPlcObject(tree, pred, plcObject, nodePathStack, ref byteOffset, ref bitOffset, hasCustomOffset); pred = plcObject; }