private static EcfBlock ReadBlock(bool isChild, string line, Func <string> nextLine) { var currentLine = line.Substring(1).Trim(); var nameDelimiterPos = isChild ? currentLine.Length : currentLine.IndexOf(' '); var block = new EcfBlock() { Name = nameDelimiterPos > 0 ? currentLine.Substring(0, nameDelimiterPos).Trim() : null }; if (block.Name != null && block.Name.StartsWith("+")) { block.Name = block.Name.Substring(1); } if (nameDelimiterPos == currentLine.Length) { currentLine = string.Empty; } else if (nameDelimiterPos > 0) { currentLine = currentLine.Substring(nameDelimiterPos).Trim(); } int unnamedChild = 0; bool firstLine = true; do { if (currentLine.StartsWith("{")) { var childBlock = ReadBlock(true, currentLine, nextLine); if (block.Childs == null) { block.Childs = new Dictionary <string, EcfBlock>(); } block.Childs.Add(childBlock.Name ?? unnamedChild++.ToString(), childBlock); childBlock.EcfValues?.Values .Where(A => A.Name != null && !block.EcfValues.ContainsKey(A.Name)) .ToList() .ForEach(A => { block.Values.Add(A.Name, A.Value); block.EcfValues.Add(A.Name, A); }); } else { var attr = ReadAttribute(currentLine); if (attr != null) { if (block.Attr == null) { block.Attr = new List <EcfAttribute>(); } if (block.Values == null) { block.Values = new Dictionary <string, object>(); } if (block.EcfValues == null) { block.EcfValues = new Dictionary <string, EcfAttribute>(); } block.Attr.Add(attr); if (attr.Name != null && !block.EcfValues.ContainsKey(attr.Name)) { block.Values.Add(attr.Name, attr.Value); block.EcfValues.Add(attr.Name, attr); } if (firstLine) { attr.AddOns?.ToList().ForEach(A => { block.Values.Add(A.Key, A.Value); block.EcfValues.Add(A.Key, new EcfAttribute() { Name = A.Key, Value = A.Value }); }); } firstLine = false; } } currentLine = nextLine().Trim(); } while (!currentLine.StartsWith("}")); return(block); }
public static void MergeWith(this EcfBlock destination, EcfBlock source) { if (source == null) { return; } destination.Name = source.Name; source.Attr?.ForEach(A => { if (destination.Attr == null) { destination.Attr = new List <EcfAttribute>(); } if (destination.Values == null) { destination.Values = new Dictionary <string, object>(); } if (destination.EcfValues == null) { destination.EcfValues = new Dictionary <string, EcfAttribute>(); } var foundAttr = destination.Attr.FirstOrDefault(a => a.Name == A.Name); if (foundAttr == null) { destination.Attr.Add(foundAttr = new EcfAttribute() { Name = A.Name, Value = A.Value, AddOns = A.AddOns == null ? null : new Dictionary <string, object>(A.AddOns) }); if (A.Name != null && !destination.EcfValues.ContainsKey(A.Name)) { destination.EcfValues.Add(A.Name, foundAttr); } if (A.Name != null && !destination.Values.ContainsKey(A.Name)) { destination.Values.Add(A.Name, foundAttr.Value); } } else { MergeEcfAttribute(foundAttr, A); if (A.Name != null && !destination.EcfValues.ContainsKey(A.Name)) { destination.EcfValues.Add(A.Name, foundAttr); } if (A.Name != null && !destination.Values.ContainsKey(A.Name)) { destination.Values.Add(A.Name, foundAttr.Value); } } }); if (destination.Childs == null && source.Childs != null) { destination.Childs = source.Childs .ToDictionary(B => B.Key, B => { var block = new EcfBlock(); block.MergeWith(B.Value); return(block); }); } else { source.Childs? .ToList() .ForEach(B => { if (destination.Childs.TryGetValue(B.Key, out var block)) { block.MergeWith(B.Value); } else { var newBlock = new EcfBlock(); newBlock.MergeWith(B.Value); destination.Childs.Add(B.Key, newBlock); } }); } destination.Childs?.Values .ToList() .ForEach(B => { B.EcfValues?.Where(A => !destination.EcfValues.ContainsKey(A.Key)) .ToList() .ForEach(A => { if (destination.EcfValues == null) { destination.EcfValues = new Dictionary <string, EcfAttribute>(); } if (destination.Values == null) { destination.Values = new Dictionary <string, object>(); } destination.EcfValues.Add(A.Key, A.Value); destination.Values.Add(A.Key, A.Value.Value); }); }); if (source.EcfValues != null && destination.EcfValues == null) { destination.EcfValues = new Dictionary <string, EcfAttribute>(source.EcfValues); } else if (source.EcfValues != null) { foreach (var item in source.EcfValues) { if (destination.EcfValues.TryGetValue(item.Key, out var attr)) { MergeEcfAttribute(attr, item.Value); } else { destination.EcfValues.Add(item.Key, item.Value); } } } if (source.Values != null && destination.Values == null) { destination.Values = new Dictionary <string, object>(source.Values); } else if (source.Values != null) { foreach (var item in source.Values) { if (destination.Values.ContainsKey(item.Key)) { destination.Values[item.Key] = item.Value; } else { destination.Values.Add(item.Key, item.Value); } } } }