/// <summary> This constructor used when creating new lines to add to the file </summary> public Node(int indentation, ReadableDataFile file) { this.File = file ?? throw new ArgumentNullException("Nodes must belong to a file"); this.FileStyleRef = file as ReadableWritableDataFile; this.IndentationLevel = indentation; this.UnappliedStyle = true; }
public KeyNode(int indentation, string key, ReadableDataFile file) : base(indentation, file) { if (!Utilities.IsValidKey(key, out string whyNot)) { throw new FormatException(whyNot); } RawText += key + ":"; }
/// <summary> /// Parses lines of SUCC into a data structure /// </summary> internal static (List <Line>, Dictionary <string, KeyNode>) DataStructureFromSUCC(string[] lines, ReadableDataFile fileRef) // I am so, so sorry. If you need to understand this function for whatever reason... may god give you guidance. { // if the file is empty // do this because otherwise new files are created with a newline at the top if (lines.Length == 1 && lines[0] == "") { return(new List <Line>(), new Dictionary <string, KeyNode>()); } var TopLevelLines = new List <Line>(); var TopLevelNodes = new Dictionary <string, KeyNode>(); var NestingNodeStack = new Stack <Node>(); // the top of the stack is the node that new nodes should be children of bool DoingMultiLineString = false; var file = fileRef as DataFile; // this will be null if fileRef is a ReadOnlyDataFile // parse the input line by line for (int i = 0; i < lines.Length; i++) { var line = lines[i]; if (line.Contains('\t')) { throw new FormatException("a SUCC file cannot contain tabs. Please use spaces instead."); } if (DoingMultiLineString) { if (NestingNodeStack.Peek().ChildNodeType != NodeChildrenType.multiLineString) { throw new Exception("oh f**k, we were supposed to be doing a multi-line string but the top of the node stack isn't a multi-line string node!"); } var newboi = new MultiLineStringNode(rawText: line, file); NestingNodeStack.Peek().AddChild(newboi); if (newboi.IsTerminator) { DoingMultiLineString = false; NestingNodeStack.Pop(); } continue; } if (LineHasData(line)) { Node node = GetNodeFromLine(line, file); boobies: if (NestingNodeStack.Count == 0) // if this is a top-level node { if (!(node is KeyNode)) { throw new FormatException($"top level lines must be key nodes. Line {i} does not conform to this: '{line}'"); } TopLevelLines.Add(node); KeyNode heck = node as KeyNode; TopLevelNodes.Add(heck.Key, heck); } else // if this is NOT a top-level node { int StackTopIndentation = NestingNodeStack.Peek().IndentationLevel; int LineIndentation = line.GetIndentationLevel(); if (LineIndentation > StackTopIndentation) // if this should be a child of the stack top { Node newParent = NestingNodeStack.Peek(); if (newParent.ChildNodes.Count == 0) // if this is the first child of the parent, assign the parent's child type { if (node is KeyNode) { newParent.ChildNodeType = NodeChildrenType.key; } else if (node is ListNode) { newParent.ChildNodeType = NodeChildrenType.list; } else { throw new Exception("what the f**k?"); } } else // if the parent already has children, check for errors with this line { CheckNewSiblingForErrors(child: node, newParent: newParent); } newParent.AddChild(node); } else // if this should NOT be a child of the stack top { NestingNodeStack.Pop(); goto boobies; } } if (node.Value == "") // if this is a node with children { NestingNodeStack.Push(node); } if (node.Value == MultiLineStringNode.Terminator) // if this is the start of a multi line string { NestingNodeStack.Push(node); node.ChildNodeType = NodeChildrenType.multiLineString; DoingMultiLineString = true; } } else // line has no data { Line NoDataLine = new Line(rawText: line); if (NestingNodeStack.Count == 0) { TopLevelLines.Add(NoDataLine); } else { NestingNodeStack.Peek().AddChild(NoDataLine); } } } return(TopLevelLines, TopLevelNodes); }
/// <summary> /// Parses a string of SUCC into a data structure /// </summary> internal static (List <Line>, Dictionary <string, KeyNode>) DataStructureFromSUCC(string input, ReadableDataFile fileRef) => DataStructureFromSUCC(input.SplitIntoLines(), fileRef);
public ListNode(int indentation, ReadableDataFile file) : base(indentation, file) { RawText += "-"; }
public ListNode(string rawText, ReadableDataFile file) : base(rawText, file) { }
/// <summary> /// Adds a <see cref="ReadableDataFile"/> as a data source that this <see cref="DistributedData"/> can search through. /// </summary> public void AddDataSource(ReadableDataFile source) { _DataSources.Add(source); }
/// <summary> This constructor used when loading lines from file </summary> public Node(string rawText, ReadableDataFile file) : base(rawText) { this.File = file ?? throw new ArgumentNullException("Nodes must belong to a file"); this.FileStyleRef = file as ReadableWritableDataFile; }
/// <summary> /// Parses a string of SUCC into a data structure /// </summary> internal static (List <Line> topLevelLines, Dictionary <string, KeyNode> topLevelNodes) DataStructureFromSucc(string input, ReadableDataFile fileRef) => DataStructureFromSucc(input.SplitIntoLines(), fileRef);
public MultiLineStringNode(string rawText, ReadableDataFile file) : base(rawText, file) { }
public MultiLineStringNode(int indentation, ReadableDataFile file) : base(indentation, file) { this.UnappliedStyle = false; // currently, no styles apply to MultiLineStringNodes }
internal InvalidFileStructureException(ReadableDataFile dataFile, int lineIndex, string details) { DataFile = dataFile; LineIndex = lineIndex; Details = details; }