Example #1
0
        private static IEnumerable <IDataBlock> CreateArrayDataBlock(
            byte[] scanData,
            int scanOffset,
            List <XElement> enumerables,
            List <XElement> structs,
            XElement datablock,
            ref int autoAddr)
        {
            XAttribute keyNode     = datablock.Attribute("key");
            XAttribute addressNode = datablock.Attribute("address");
            XAttribute nameNode    = datablock.Attribute("displayname");

            XAttribute copyaddressNode = datablock.Attribute("copyaddress");
            XAttribute readOnlyNode    = datablock.Attribute("readonly");
            XAttribute dataLenghtNode  = datablock.Attribute("datasize");

            XAttribute minvalNode  = datablock.Attribute("minvalue");
            XAttribute maxvalNode  = datablock.Attribute("maxvalue");
            XAttribute warnvalNode = datablock.Attribute("warnvalue");

            XAttribute innerTypeNode = datablock.Attribute("innertype");
            XAttribute headTypeNode  = datablock.Attribute("headtype");
            XAttribute arraySizeNode = datablock.Attribute("arraysize");

            XAttribute metaKeyNode = datablock.Attribute("metakey");

            if (!addressNode.Value.Equals("auto", StringComparison.OrdinalIgnoreCase))
            {
                autoAddr = addressNode.Value.ToInt32();
            }

            bool ignore = keyNode == null;

            string key = keyNode == null
                ? String.Empty
                : keyNode.Value;

            if (innerTypeNode == null)
            {
                throw new Exception(string.Format("Inner Type not set for Array: {0}", key));
            }

            string innerType = innerTypeNode.Value;

            string name = nameNode == null
                ? key
                : nameNode.Value;

            var copyAddresses = copyaddressNode == null
                ? new int[0]
                : copyaddressNode.Value.Split(';')
                                .Select(Extensions.ToInt32)
                                .ToArray();

            IDataBlock baseBlock;
            string     arraySizeStr = arraySizeNode.Value;
            string     headKey      = key;

            if (arraySizeStr.Equals("auto", StringComparison.OrdinalIgnoreCase))
            {
                string headType = headTypeNode.Value;
                int    dataLenght;
                switch (headType)
                {
                default:
                case "byte":
                    dataLenght = 1;
                    break;

                case "int16":
                    dataLenght = 2;
                    break;

                case "int32":
                    dataLenght = 4;
                    break;
                }

                switch (dataLenght)
                {
                default:
                case 1:
                    baseBlock = new ByteDataBlock
                    {
                        Address       = autoAddr,
                        CopyAddresses = copyAddresses,
                        Key           = headKey,
                        Name          = name,
                        ReadOnly      = true
                    };
                    break;

                case 2:
                    baseBlock = new Int16DataBlock
                    {
                        Address       = autoAddr,
                        CopyAddresses = copyAddresses,
                        Key           = headKey,
                        Name          = name,
                        ReadOnly      = true
                    };
                    break;

                case 4:
                    baseBlock = new Int32DataBlock
                    {
                        Address       = autoAddr,
                        CopyAddresses = copyAddresses,
                        Key           = headKey,
                        Name          = name,
                        ReadOnly      = true
                    };
                    break;
                }
            }
            else
            {
                baseBlock = new DummyDataBlock
                {
                    Address       = autoAddr,
                    CopyAddresses = new int[0],
                    Key           = headKey,
                    Name          = name,
                    ReadOnly      = true,
                    DummyValue    = arraySizeStr.ToInt32()
                };
            }

            var outBlocks = new List <IDataBlock>();

            autoAddr += baseBlock.Size;
            outBlocks.Add(baseBlock);

            int elCount = Convert.ToInt32(baseBlock.Read(scanData, scanOffset));

            for (int i = 0; i < elCount; i++)
            {
                IDataBlock block      = null;
                XElement   innerBlock = new XElement("datablock",
                                                     new XAttribute("type", innerType),
                                                     //
                                                     new XAttribute("key", string.Format("{0}[{1}]", key, i)),
                                                     new XAttribute("address", "auto"),
                                                     new XAttribute("displayname",
                                                                    string.Format("{0} Element {1}", name, i)
                                                                    .Trim()),
                                                     //
                                                     readOnlyNode,
                                                     metaKeyNode,
                                                     dataLenghtNode,
                                                     //
                                                     minvalNode,
                                                     maxvalNode,
                                                     warnvalNode);

                switch (innerType)
                {
                case "dummy":
                    block = CreateDummyBlock(innerBlock, ref autoAddr);
                    break;

                case "bool":
                case "byte":
                case "int16":
                case "int32":
                case "color":
                case "string":
                case "encodedstring":
                    block = CreateValueDataBlock(innerType, innerBlock, ref autoAddr);
                    break;

                case "enum":
                    block = CreateEnumDataBlock(enumerables, innerBlock, ref autoAddr);
                    break;

                case "array":
                    throw new Exception("Arrays of Arrays are not supported, use a struct datatype");
                    break;

                case "struct":
                    var structBlocks = CreateStructDataBlock(scanData, scanOffset, enumerables, structs, innerBlock, ref autoAddr);
                    outBlocks.AddRange(structBlocks);
                    break;
                }
                if (block != null)
                {
                    outBlocks.Add(block);
                }
            }

            return(!ignore
                ? outBlocks
                : Enumerable.Empty <IDataBlock>());
        }
Example #2
0
        internal static IDataBlock CreateValueDataBlock(string type, XElement datablock, ref int autoAddr)
        {
            XAttribute addressNode = datablock.Attribute("address");
            XAttribute keyNode     = datablock.Attribute("key");
            XAttribute nameNode    = datablock.Attribute("displayname");

            XAttribute copyaddressNode = datablock.Attribute("copyaddress");
            XAttribute dataLenghtNode  = datablock.Attribute("datasize");
            XAttribute readonlyNode    = datablock.Attribute("readonly");

            XAttribute minvalNode  = datablock.Attribute("minvalue");
            XAttribute maxvalNode  = datablock.Attribute("maxvalue");
            XAttribute warnvalNode = datablock.Attribute("warnvalue");

            if (!addressNode.Value.Equals("auto", StringComparison.OrdinalIgnoreCase))
            {
                autoAddr = addressNode.Value.ToInt32();
            }

            bool ignore = keyNode == null;

            string key = keyNode == null
                ? String.Empty
                : keyNode.Value;

            string name = nameNode == null
                ? key
                : nameNode.Value;

            var copyAddresses = copyaddressNode == null
                ? new int[0]
                : copyaddressNode.Value.Split(';')
                                .Select(Extensions.ToInt32)
                                .ToArray();

            bool readOnly = bool.Parse(readonlyNode.Value);

            bool isRanged = minvalNode != null || maxvalNode != null;

            IDataBlock block = null;

            switch (type)
            {
            case "bool":

                block = new BoolDataBlock
                {
                    Key           = key,
                    Address       = autoAddr,
                    Name          = name,
                    CopyAddresses = copyAddresses,
                    ReadOnly      = readOnly
                };
                break;

            case "byte":
                block = new ByteDataBlock
                {
                    Key           = key,
                    Address       = autoAddr,
                    Name          = name,
                    CopyAddresses = copyAddresses,
                    ReadOnly      = readOnly,
                    IsRanged      = isRanged,
                    MinValue      = minvalNode == null
                            ? Byte.MinValue
                            : minvalNode.Value.ToByte(),
                    MaxValue = maxvalNode == null
                            ? Byte.MaxValue
                            : maxvalNode.Value.ToByte(),
                    WarnValue = warnvalNode == null
                            ? Byte.MaxValue
                            : warnvalNode.Value.ToByte(),
                };
                break;

            case "int16":
                block = new Int16DataBlock
                {
                    Key           = key,
                    Address       = autoAddr,
                    Name          = name,
                    CopyAddresses = copyAddresses,
                    ReadOnly      = readOnly,
                    IsRanged      = isRanged,
                    MinValue      = minvalNode == null
                            ? Int16.MinValue
                            : minvalNode.Value.ToInt16(),
                    MaxValue = maxvalNode == null
                            ? Int16.MaxValue
                            : maxvalNode.Value.ToInt16(),
                    WarnValue = warnvalNode == null
                            ? Int16.MaxValue
                            : warnvalNode.Value.ToInt16(),
                };
                break;

            case "int32":
                block = new Int32DataBlock
                {
                    Key           = key,
                    Address       = autoAddr,
                    Name          = name,
                    CopyAddresses = copyAddresses,
                    ReadOnly      = readOnly,
                    IsRanged      = isRanged,
                    MinValue      = minvalNode == null
                            ? Int32.MinValue
                            : minvalNode.Value.ToInt32(),
                    MaxValue = maxvalNode == null
                            ? Int32.MaxValue
                            : maxvalNode.Value.ToInt32(),
                    WarnValue = warnvalNode == null
                            ? Int32.MaxValue
                            : warnvalNode.Value.ToInt32(),
                };
                break;

            case "color":
                block = new ColorDataBlock
                {
                    Key           = key,
                    Address       = autoAddr,
                    Name          = name,
                    CopyAddresses = copyAddresses,
                    ReadOnly      = readOnly,
                };
                break;

            case "string":
                block = new StringDataBlock
                {
                    Key           = key,
                    Address       = autoAddr,
                    Name          = name,
                    CopyAddresses = copyAddresses,
                    ReadOnly      = readOnly,
                    Size          = dataLenghtNode.Value.ToInt32()
                };
                break;

            case "encodedstring":
                block = new EncodedStringDataBlock
                {
                    Key           = key,
                    Address       = autoAddr,
                    Name          = name,
                    CopyAddresses = copyAddresses,
                    ReadOnly      = readOnly,
                    Size          = dataLenghtNode.Value.ToInt32()
                };
                break;
            }
            if (block != null)
            {
                autoAddr += block.Size;
            }
            return(!ignore
                ? block
                : null);
        }