private static IEnumerable <ReadPackage> CreateReadPackages(SiemensPlcProtocolContext s7Context, IEnumerable <ReadItem> vars) { var result = new List <ReadPackage>(); foreach (var item in vars.OrderByDescending(x => x.NumberOfItems).ToList()) { var currentPackage = result.FirstOrDefault(package => package.TryAdd(item)); if (currentPackage == null) { if (item.NumberOfItems > s7Context.ReadItemMaxLength) { var bytesToRead = item.NumberOfItems; ushort processed = 0; while (bytesToRead > 0) { var slice = Math.Min(s7Context.ReadItemMaxLength, bytesToRead); var child = ReadItem.CreateChild(item, (item.Offset + processed), slice); if (slice < s7Context.ReadItemMaxLength) { currentPackage = result.FirstOrDefault(package => package.TryAdd(child)); } if (currentPackage == null) { currentPackage = new ReadPackage(s7Context.PduSize); if (currentPackage.TryAdd(child)) { if (currentPackage.Full) { yield return(currentPackage.Return()); if (currentPackage.Handled) { currentPackage = null; } } else { result.Add(currentPackage); } } else { ThrowHelper.ThrowCouldNotAddPackageException(nameof(ReadPackage)); } } processed += slice; bytesToRead -= slice; } } else { currentPackage = new ReadPackage(s7Context.PduSize); result.Add(currentPackage); if (!currentPackage.TryAdd(item)) { ThrowHelper.ThrowCouldNotAddPackageException(nameof(ReadPackage)); } } } if (currentPackage != null) { if (currentPackage.Full) { yield return(currentPackage.Return()); } if (currentPackage.Handled) { result.Remove(currentPackage); } } } foreach (var package in result) { yield return(package.Return()); } }
private IEnumerable <ReadPackage> CreateReadPackages(SiemensPlcProtocolContext s7Context, IEnumerable <ReadItem> vars) { var result = new List <ReadPackage>(); foreach (var item in vars.ToList().OrderByDescending(x => x.Length)) { var currentPackage = result.FirstOrDefault(package => package.TryAdd(item)); if (currentPackage == null) { if (item.Length > s7Context.ReadItemMaxLength) { ushort bytesToRead = item.Length; ushort processed = 0; while (bytesToRead > 0) { var slice = Math.Min(_s7Context.ReadItemMaxLength, bytesToRead); var child = ReadItem.CreateChild(item, (ushort)(item.Offset + processed), slice); if (slice < _s7Context.ReadItemMaxLength) { currentPackage = result.FirstOrDefault(package => package.TryAdd(child)); } if (currentPackage == null) { currentPackage = new ReadPackage(s7Context.PduSize); if (currentPackage.TryAdd(child)) { if (currentPackage.Full) { yield return(currentPackage.Return()); if (currentPackage.Handled) { currentPackage = null; } } else { result.Add(currentPackage); } } else { throw new InvalidOperationException(); } } processed += slice; bytesToRead -= slice; } } else { currentPackage = new ReadPackage(s7Context.PduSize); result.Add(currentPackage); if (!currentPackage.TryAdd(item)) { throw new InvalidOperationException(); } } } if (currentPackage != null) { if (currentPackage.Full) { yield return(currentPackage.Return()); } if (currentPackage.Handled) { result.Remove(currentPackage); } } } foreach (var package in result) { yield return(package.Return()); } }