コード例 #1
0
        /// <summary>
        ///     组合地址
        /// </summary>
        /// <param name="addresses">需要组合的地址</param>
        /// <returns>组合后的地址</returns>
        public override IEnumerable <CommunicationUnit <TKey> > Combine(IEnumerable <AddressUnit <TKey> > addresses)
        {
            var groupedAddresses = from address in addresses
                                   orderby
                                   AddressHelper.GetProtocalCoordinate(address.Address, address.SubAddress,
                                                                       AddressTranslator.GetAreaByteLength(address.Area))
                                   group address by address.Area
                                   into grouped
                                   select grouped;

            var ans = new List <CommunicationUnit <TKey> >();

            foreach (var groupedAddress in groupedAddresses)
            {
                var    area              = groupedAddress.Key;
                double initNum           = -1;
                double preNum            = -1;
                Type   preType           = null;
                var    originalAddresses = new List <AddressUnit <TKey> >();
                var    orderedAddresses  =
                    groupedAddress.OrderBy(
                        address =>
                        AddressHelper.GetProtocalCoordinate(address.Address, address.SubAddress,
                                                            AddressTranslator.GetAreaByteLength(address.Area)));
                foreach (var address in orderedAddresses)
                {
                    if (initNum < 0)
                    {
                        initNum = AddressHelper.GetProtocalCoordinate(address.Address, address.SubAddress,
                                                                      AddressTranslator.GetAreaByteLength(address.Area));
                        originalAddresses.Add(address);
                    }
                    else
                    {
                        if (AddressHelper.GetProtocalCoordinate(address.Address, address.SubAddress,
                                                                AddressTranslator.GetAreaByteLength(address.Area)) <
                            AddressHelper.GetProtocalCoordinateNextPosition(preNum,
                                                                            preType,
                                                                            AddressTranslator.GetAreaByteLength(address.Area)))
                        {
                            originalAddresses.Add(address);
                            //如果当前地址的末尾被记录,表示地址被记录的地址域覆盖,这个地址没有记录的必要
                            if (AddressHelper.GetProtocalCoordinateNextPosition(
                                    AddressHelper.GetProtocalCoordinate(address.Address, address.SubAddress,
                                                                        AddressTranslator.GetAreaByteLength(address.Area)),
                                    address.DataType,
                                    AddressTranslator.GetAreaByteLength(address.Area)) <=
                                AddressHelper.GetProtocalCoordinateNextPosition(preNum,
                                                                                preType,
                                                                                AddressTranslator.GetAreaByteLength(address.Area)))
                            {
                                continue;
                            }
                        }

                        else if (AddressHelper.GetProtocalCoordinate(address.Address, address.SubAddress,
                                                                     AddressTranslator.GetAreaByteLength(address.Area)) >
                                 AddressHelper.GetProtocalCoordinateNextPosition(preNum,
                                                                                 preType,
                                                                                 AddressTranslator.GetAreaByteLength(address.Area)))
                        {
                            ans.Add(new CommunicationUnit <TKey>
                            {
                                Area     = area,
                                Address  = (int)Math.Floor(initNum),
                                GetCount =
                                    (int)
                                    Math.Ceiling(
                                        AddressHelper.MapProtocalGetCountToAbstractByteCount(
                                            preNum - (int)Math.Floor(initNum),
                                            AddressTranslator.GetAreaByteLength(address.Area),
                                            BigEndianValueHelper.Instance.ByteLength[preType.FullName])),
                                DataType          = typeof(byte),
                                OriginalAddresses = originalAddresses.ToList()
                            });
                            initNum = address.Address;
                            originalAddresses.Clear();
                            originalAddresses.Add(address);
                        }
                        else
                        {
                            //地址连续,压入当前记录的结果
                            originalAddresses.Add(address);
                        }
                    }
                    //把当前地址变为上一个地址
                    preNum = AddressHelper.GetProtocalCoordinate(address.Address, address.SubAddress,
                                                                 AddressTranslator.GetAreaByteLength(address.Area));
                    preType = address.DataType;
                }
                //最后一个地址域压入返回结果
                ans.Add(new CommunicationUnit <TKey>
                {
                    Area     = area,
                    Address  = (int)Math.Floor(initNum),
                    GetCount =
                        (int)
                        Math.Ceiling(
                            AddressHelper.MapProtocalGetCountToAbstractByteCount(
                                preNum - (int)Math.Floor(initNum), AddressTranslator.GetAreaByteLength(area),
                                BigEndianValueHelper.Instance.ByteLength[preType.FullName])),
                    DataType          = typeof(byte),
                    OriginalAddresses = originalAddresses.ToList()
                });
            }
            var newAns = new List <CommunicationUnit <TKey> >();

            foreach (var communicationUnit in ans)
            {
                var oldByteCount = communicationUnit.GetCount *
                                   BigEndianValueHelper.Instance.ByteLength[communicationUnit.DataType.FullName];
                while (oldByteCount * BigEndianValueHelper.Instance.ByteLength[communicationUnit.DataType.FullName] >
                       MaxLength)
                {
                    var newOriginalAddresses = new List <AddressUnit <TKey> >();
                    var oldOriginalAddresses = communicationUnit.OriginalAddresses.ToList();
                    var newByteCount         = 0.0;
                    do
                    {
                        var currentAddressUnit = oldOriginalAddresses.First();
                        newByteCount += BigEndianValueHelper.Instance.ByteLength[currentAddressUnit.DataType.FullName];
                        if (newByteCount > MaxLength)
                        {
                            break;
                        }
                        oldByteCount -= BigEndianValueHelper.Instance.ByteLength[currentAddressUnit.DataType.FullName];
                        newOriginalAddresses.Add(currentAddressUnit);
                        oldOriginalAddresses.RemoveAt(0);
                    } while (newByteCount < MaxLength);


                    var newCommunicationUnit = new CommunicationUnit <TKey>
                    {
                        Area       = communicationUnit.Area,
                        Address    = communicationUnit.Address,
                        SubAddress = communicationUnit.SubAddress,
                        DataType   = communicationUnit.DataType,
                        GetCount   =
                            (int)
                            Math.Ceiling(newByteCount /
                                         BigEndianValueHelper.Instance.ByteLength[communicationUnit.DataType.FullName]),
                        OriginalAddresses = newOriginalAddresses
                    };

                    newAns.Add(newCommunicationUnit);
                }
                communicationUnit.GetCount =
                    (int)
                    Math.Ceiling(oldByteCount /
                                 BigEndianValueHelper.Instance.ByteLength[communicationUnit.DataType.FullName]);
                newAns.Add(communicationUnit);
            }
            return(newAns);
        }
コード例 #2
0
        public override IEnumerable <CommunicationUnit> Combine(IEnumerable <AddressUnit> addresses)
        {
            //按从小到大的顺序对地址进行排序
            var groupedAddresses = from address in addresses
                                   orderby
                                   AddressHelper.GetProtocalCoordinate(address.Address, address.SubAddress,
                                                                       AddressTranslator.GetAreaByteLength(address.Area))
                                   group address by address.Area
                                   into grouped
                                   select grouped;

            var ans = new List <CommunicationUnit>();

            foreach (var groupedAddress in groupedAddresses)
            {
                var area = groupedAddress.Key;
                //初始地址
                double initNum = -1;
                //上一个地址
                double preNum = -1;
                //上一个地址类型
                Type preType = null;
                //记录一个地址组合当中的所有原始地址
                var originalAddresses = new List <AddressUnit>();
                //对组合内地址从小到大进行排序
                var orderedAddresses =
                    groupedAddress.OrderBy(
                        address =>
                        AddressHelper.GetProtocalCoordinate(address.Address, address.SubAddress,
                                                            AddressTranslator.GetAreaByteLength(address.Area)));
                foreach (var address in orderedAddresses)
                {
                    //第一次进入时直接压入地址
                    if (initNum < 0)
                    {
                        initNum = AddressHelper.GetProtocalCoordinate(address.Address, address.SubAddress,
                                                                      AddressTranslator.GetAreaByteLength(address.Area));
                        originalAddresses.Add(address);
                    }
                    else
                    {
                        //如果当前地址小于已经记录的地址域,表示这个地址的开始已经记录过了
                        if (AddressHelper.GetProtocalCoordinate(address.Address, address.SubAddress,
                                                                AddressTranslator.GetAreaByteLength(address.Area)) <
                            AddressHelper.GetProtocalCoordinateNextPosition(preNum,
                                                                            preType,
                                                                            AddressTranslator.GetAreaByteLength(address.Area)))
                        {
                            originalAddresses.Add(address);
                            //如果当前地址的末尾被记录,表示地址被记录的地址域覆盖,这个地址没有记录的必要
                            if (AddressHelper.GetProtocalCoordinateNextPosition(
                                    AddressHelper.GetProtocalCoordinate(address.Address, address.SubAddress,
                                                                        AddressTranslator.GetAreaByteLength(address.Area)),
                                    address.DataType,
                                    AddressTranslator.GetAreaByteLength(address.Area)) <=
                                AddressHelper.GetProtocalCoordinateNextPosition(preNum,
                                                                                preType,
                                                                                AddressTranslator.GetAreaByteLength(address.Area)))
                            {
                                continue;
                            }
                        }
                        //如果当前地址大于记录的地址域的开头,则表示地址已经不连续了
                        else if (AddressHelper.GetProtocalCoordinate(address.Address, address.SubAddress,
                                                                     AddressTranslator.GetAreaByteLength(address.Area)) >
                                 AddressHelper.GetProtocalCoordinateNextPosition(preNum,
                                                                                 preType,
                                                                                 AddressTranslator.GetAreaByteLength(address.Area)))
                        {
                            //上一个地址域压入返回结果,并把当前记录的结果清空。
                            ans.Add(new CommunicationUnit
                            {
                                Area     = area,
                                Address  = (int)Math.Floor(initNum),
                                GetCount =
                                    (int)
                                    Math.Ceiling(
                                        AddressHelper.MapProtocalGetCountToAbstractByteCount(
                                            preNum - (int)Math.Floor(initNum),
                                            AddressTranslator.GetAreaByteLength(address.Area),
                                            BigEndianValueHelper.Instance.ByteLength[preType.FullName])),
                                DataType          = typeof(byte),
                                OriginalAddresses = originalAddresses.ToList()
                            });
                            initNum = address.Address;
                            originalAddresses.Clear();
                            originalAddresses.Add(address);
                        }
                        else
                        {
                            //地址连续,压入当前记录的结果
                            originalAddresses.Add(address);
                        }
                    }
                    //把当前地址变为上一个地址
                    preNum = AddressHelper.GetProtocalCoordinate(address.Address, address.SubAddress,
                                                                 AddressTranslator.GetAreaByteLength(address.Area));
                    preType = address.DataType;
                }
                //最后一个地址域压入返回结果
                ans.Add(new CommunicationUnit
                {
                    Area     = area,
                    Address  = (int)Math.Floor(initNum),
                    GetCount =
                        (int)
                        Math.Ceiling(
                            AddressHelper.MapProtocalGetCountToAbstractByteCount(
                                preNum - (int)Math.Floor(initNum), AddressTranslator.GetAreaByteLength(area),
                                BigEndianValueHelper.Instance.ByteLength[preType.FullName])),
                    DataType          = typeof(byte),
                    OriginalAddresses = originalAddresses.ToList()
                });
            }
            return(ans);
        }