static void updatePath(Asn1TreeNode source, String path, Int32 index) { source.Value.Path = source.Path = path + "/" + index; source.MyIndex = index; Int32 deepness = source.Value.Path.Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries).Length; source.Value.Deepness = deepness; for (Int32 i = 0; i < source.Children.Count; i++) { updatePath(source.Children[i], source.Path, i); } }
public Asn1Lite(Asn1Reader root, Asn1TreeNode tree, Int32 index) { initialize(root); Depth = tree.Value.Depth + 1; Path = $"{tree.Value.Path}/{index}"; if (Tag == (Byte)Asn1Type.BIT_STRING) { if (root.PayloadLength > 0) { UnusedBits = root.RawData[root.PayloadStartOffset]; } } }
public void RemoveChild(Asn1TreeNode node) { notifySizeChanged(node, -node.Value.TagLength); Children.RemoveAt(node.MyIndex); // update path only below removed node for (Int32 childIndex = node.MyIndex; childIndex < Children.Count; childIndex++) { updatePath(this[childIndex], Path, childIndex); } if (Children.Count == 0 && !Value.IsRoot) { Value.IsContainer = false; } }
public void AddChild(Asn1Lite value, Boolean forcePathUpdate = false) { var node = new Asn1TreeNode(value) { Parent = this }; Children.Add(node); if (forcePathUpdate) { notifySizeChanged(node, node.Value.TagLength); updatePath(node, Path, Children.Count - 1); } Value.IsContainer = true; }
void updateNodeHeader(Asn1TreeNode node, NodeViewOptions options) { if (node.Value.Tag == (Byte)Asn1Type.INTEGER) { updateIntValue(node.Value, options.IntegerAsInteger); } var outerList = new List <String>(); var innerList = new List <String>(); if (options.ShowNodePath) { outerList.Add($"({node.Path})"); } if (options.ShowTagNumber) { innerList.Add(options.ShowInHex ? $"T:{node.Value.Tag:x2}" : $"T:{node.Value.Tag}"); } if (options.ShowNodeOffset) { innerList.Add(options.ShowInHex ? $"O:{node.Value.Offset:x4}" : $"O:{node.Value.Offset}"); } if (options.ShowNodeLength) { innerList.Add(options.ShowInHex ? $"L:{node.Value.PayloadLength:x4}" : $"L:{node.Value.PayloadLength}"); } if (innerList.Count > 0) { outerList.Add("(" + String.Join(", ", innerList) + ")"); } outerList.Add(node.Value.TagName); if (options.ShowContent) { if (!String.IsNullOrEmpty(node.Value.ExplicitValue)) { outerList.Add(":"); outerList.Add(node.Value.ExplicitValue); } } node.Value.Header = String.Join(" ", outerList); node.Value.ToolTip = writeToolTip(node); foreach (Asn1TreeNode child in node.Children) { updateNodeHeader(child, options); } }
public void InsertChildNode(Asn1TreeNode nodeToInsert, Asn1TreeNode caller, NodeAddOption option) { Int32 indexToInsert, newOffset; nodeToInsert.Parent = this; nodeToInsert.Value.IsRoot = false; //Int32 headerLength = nodeToInsert.Value.HeaderLength; switch (option) { case NodeAddOption.Before: indexToInsert = Children.IndexOf(caller); newOffset = caller.Value.Offset; break; case NodeAddOption.After: indexToInsert = Children.IndexOf(caller) + 1; newOffset = caller.Value.Offset + caller.Value.TagLength; break; case NodeAddOption.Last: indexToInsert = Children.Count; newOffset = Value.Offset + Value.TagLength; break; default: return; } Value.IsContainer = true; if (indexToInsert < 0) { return; } nodeToInsert.Value.Offset = newOffset; Children.Insert(indexToInsert, nodeToInsert); notifySizeChanged(nodeToInsert, nodeToInsert.Value.TagLength); for (Int32 index = indexToInsert; index < Children.Count; index++) { updatePath(Children[index], Path, index); } foreach (Asn1TreeNode child in Children[indexToInsert].Children) { child.updateOffset(newOffset); } }
String writeToolTip(Asn1TreeNode node) { var sb = new StringBuilder(); sb.AppendFormat( Resources.TagEditorHeaderTemp, node.Value.Tag, node.Value.TagName, node.Value.Offset, node.Value.TagLength, node.Value.Depth, node.Value.Path); sb.AppendLine(); if (!node.Value.IsContainer) { sb.Append("Value:"); if (node.Value.PayloadLength == 0) { sb.AppendLine(" NULL"); } else { sb.AppendLine(); Int32 skip = node.Value.PayloadStartOffset; Int32 take = node.Value.PayloadLength; Boolean writeUnusedBits = false; if (node.Value.Tag == (Byte)Asn1Type.BIT_STRING) { skip++; take--; writeUnusedBits = true; } if (writeUnusedBits) { sb.AppendLine($"Unused Bits: {node.Value.UnusedBits}"); } Byte[] binData = _dataSource.RawData.Skip(skip).Take(take).ToArray(); sb.Append(binData.Length == 0 ? "EMPTY" : AsnFormatter.BinaryToString(binData, EncodingType.Hex).TrimEnd()); } } return(sb.ToString()); }
void notifySizeChanged(Asn1TreeNode source, Int32 difference) { Asn1TreeNode t = this; do { if (t.Children.Count > 0) { // update offset of every node below modified (source) node Int32 callerIndex = t.Children.IndexOf(source); if (callerIndex < 0) { return; } for (Int32 index = callerIndex + 1; index < t.Children.Count; index++) { t.Children[index].updateOffset(difference); } } Byte[] newLenBytes = Asn1Utils.GetLengthBytes(t.Value.PayloadLength + difference); App.Container.Resolve <IDataSource>().RawData.RemoveRange(t.Value.Offset + 1, t.Value.HeaderLength - 1); App.Container.Resolve <IDataSource>().RawData.InsertRange(t.Value.Offset + 1, newLenBytes); // check if extra length byte is added. If so, add this byte to difference variable Int32 diff = newLenBytes.Length - (t.Value.HeaderLength - 1); if (diff != 0) { // shift payload start offset to extra length bytes t.Value.PayloadStartOffset += diff; t.updateOffset(diff); t.Value.Offset -= diff; // TODO this: updateOffset method updates current node as well which is not neccessary } source = t; t = t.Parent; source.Value.PayloadLength += difference; difference += diff; } while (t != null); }
protected Boolean Equals(Asn1TreeNode other) { return(String.Equals(Path, other.Path)); }