/// <summary> Non-generic version of Set. You probably want to use Set. </summary> /// <param name="type"> the type to save the data as </param> /// <param name="key"> what the data is labeled as within the file </param> /// <param name="value"> the value to save </param> public void SetNonGeneric(Type type, string key, object value) { if (value == null) { throw new Exception("you can't serialize null"); } if (value.GetType() != type) { throw new InvalidCastException($"{value} is not of type {type}!"); } if (!KeyExists(key)) { var newnode = new KeyNode(indentation: 0, key, file: this); TopLevelNodes.Add(key, newnode); TopLevelLines.Add(newnode); } var node = TopLevelNodes[key]; NodeManager.SetNodeData(node, value, type, Style); if (AutoSave) { SaveAllData(); } }
public KeyNode GetChildAddressedByName(string name) { EnsureProperType(NodeChildrenType.key); foreach (var node in ChildNodes) { var keynode = node as KeyNode; if (keynode.Key == name) return keynode; } return CreateKeyNode(name); KeyNode CreateKeyNode(string key) { var newnode = new KeyNode(GetProperChildIndentation(), key, File); AddChild(newnode); return newnode; } }
private static Node GetNodeFromLine(string line, DataFile file) { var DataType = GetDataLineType(line); Node node = null; switch (DataType) { case DataLineType.key: node = new KeyNode(rawText: line, file); break; case DataLineType.list: node = new ListNode(rawText: line, file); break; default: throw new FormatException($"format error on line: {line}"); } return(node); }
/// <summary> /// Parses lines of SUCC into a data structure /// </summary> internal static (List <Line>, Dictionary <string, KeyNode>) DataStructureFromSUCC(string[] lines, DataFileBase 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); }