private void FlushRangeIfNecessary(ref CopyRange currentRange) { if (currentRange.Size > 0) { ranges.Add(currentRange); currentRange.SourceStart += currentRange.Size; currentRange.DestStart = -1; currentRange.Size = 0; } }
protected override void Execute(CodeActivityContext context) { try { base.LoadVariables(context); strCopyRange = CopyRange.Get(context); this.CopyXlData(); } catch (Exception ex) { throw ex; } }
/// <summary> /// Compute copy operations. Assumes destination layout is sequential. /// </summary> /// <param name="dest"></param> /// <param name="source"></param> /// <param name="keyRoot"></param> public void Compile(ParameterCollection dest, ParameterCollection source, string keyRoot) { ranges = new List <CopyRange>(); destination = dest; var sourceLayout = new ParameterCollectionLayout(); // Helper structures to try to keep range contiguous and have as few copy operations as possible (note: there can be some padding) var currentDataRange = new CopyRange { IsData = true, DestStart = -1 }; var currentResourceRange = new CopyRange { IsResource = true, DestStart = -1 }; // Iterate over each variable in dest, and if they match keyRoot, create the equivalent layout in source foreach (var parameterKeyInfo in dest.Layout.LayoutParameterKeyInfos) { bool isResource = parameterKeyInfo.BindingSlot != -1; bool isData = parameterKeyInfo.Offset != -1; if (parameterKeyInfo.Key.Name.EndsWith(keyRoot)) { // That's a match var subkeyName = parameterKeyInfo.Key.Name.Substring(0, parameterKeyInfo.Key.Name.Length - keyRoot.Length); var subkey = ParameterKeys.FindByName(subkeyName); if (isData) { // First time since range reset, let's setup destination offset if (currentDataRange.DestStart == -1) { currentDataRange.DestStart = parameterKeyInfo.Offset; } // Might be some empty space (padding) currentDataRange.Size = parameterKeyInfo.Offset - currentDataRange.DestStart; sourceLayout.LayoutParameterKeyInfos.Add(new ParameterKeyInfo(subkey, currentDataRange.SourceStart + currentDataRange.Size, parameterKeyInfo.Count)); var elementCount = parameterKeyInfo.Count; var elementSize = parameterKeyInfo.Key.Size; var size = (elementSize + 15) / 16 * 16 * (elementCount - 1) + elementSize; currentDataRange.Size += size; } else if (isResource) { // First time since range reset, let's setup destination offset if (currentResourceRange.DestStart == -1) { currentResourceRange.DestStart = parameterKeyInfo.BindingSlot; } // Might be some empty space (padding) (probably unlikely for resources...) currentResourceRange.Size = parameterKeyInfo.BindingSlot - currentResourceRange.DestStart; sourceLayout.LayoutParameterKeyInfos.Add(new ParameterKeyInfo(subkey, currentResourceRange.SourceStart + currentResourceRange.Size)); currentResourceRange.Size += parameterKeyInfo.Count; } } else { // Found one item not part of the range, let's finish it if (isData) { FlushRangeIfNecessary(ref currentDataRange); } else if (isResource) { FlushRangeIfNecessary(ref currentResourceRange); } } } // Finish ranges FlushRangeIfNecessary(ref currentDataRange); FlushRangeIfNecessary(ref currentResourceRange); // Update sizes sourceLayout.BufferSize = currentDataRange.SourceStart; sourceLayout.ResourceCount = currentResourceRange.SourceStart; source.UpdateLayout(sourceLayout); }