/// <summary> /// Gets the node at the given address. May be used to build structure. /// </summary> /// <param name="args">An ordered list of keys, like a path</param> /// <param name="create">If true, will create any nodes it does not find along the path.</param> /// <param name="index">Start index of the arg array</param> /// <returns>The FileNode at the given location, or null if the location was not found / created</returns> public VdfFileNode GetNodeAt(string[] args, bool create = true, int index = 0) { if (index >= args.Length) { return(this); } if (NodeType == ValueType.Array) { Dictionary <string, VdfFileNode> data = (Dictionary <string, VdfFileNode>)NodeData; if (ContainsKey(args[index])) { return(data[args[index]].GetNodeAt(args, create, index + 1)); } if (create) { VdfFileNode newNode = new VdfFileNode(); data.Add(args[index], newNode); return(newNode.GetNodeAt(args, true, index + 1)); } } return(null); }
/// <summary> /// Loads a FileNode from stream. /// </summary> /// <param name="stream">Stream to load from</param> /// <param name="useFirstAsRoot"></param> /// <returns>FileNode representing the contents of the stream.</returns> public static VdfFileNode LoadFromText(StreamReader stream, bool useFirstAsRoot = false) { VdfFileNode thisLevel = useFirstAsRoot ? null : new VdfFileNode(); ReadText_SkipWhitespace(stream); while (!stream.EndOfStream) { ReadText_SkipWhitespace(stream); // Get key char nextChar = (char)stream.Read(); String key; if (stream.EndOfStream || (nextChar == '}')) { break; } if (nextChar == '"') { key = ReadText_GetStringToken(stream); } else { throw new ParseException(string.Format(GlobalStrings.TextVdfFile_UnexpectedCharacterKey, nextChar)); } ReadText_SkipWhitespace(stream); // Get value nextChar = (char)stream.Read(); VdfFileNode newNode; if (nextChar == '"') { newNode = new VdfFileNode(ReadText_GetStringToken(stream)); } else if (nextChar == '{') { newNode = LoadFromText(stream); } else { throw new ParseException( string.Format(GlobalStrings.TextVdfFile_UnexpectedCharacterValue, nextChar)); } if (useFirstAsRoot) { return(newNode); } thisLevel[key] = newNode; } return(thisLevel); }
/// <summary> /// Loads a FileNode from stream. /// </summary> /// <param name="stream">Stream to load from</param> /// <param name="streamLength"></param> /// <returns>FileNode representing the contents of the stream.</returns> public static VdfFileNode LoadFromBinary(BinaryReader stream, long streamLength = -1) { if (streamLength == -1) { streamLength = stream.BaseStream.Length; } if (stream.BaseStream.Position == streamLength) { return(null); } VdfFileNode thisLevel = new VdfFileNode(); bool endOfStream = false; while (!endOfStream) { byte nextByte; try { nextByte = stream.ReadByte(); } catch (EndOfStreamException) { endOfStream = true; nextByte = 8; } // Get key string key = string.Empty; if (endOfStream || (nextByte == 8) || (stream.BaseStream.Position == streamLength)) { break; } if (nextByte == 0) { key = ReadBin_GetStringToken(stream); VdfFileNode newNode = LoadFromBinary(stream, streamLength); thisLevel[key] = newNode; } else if (nextByte == 1) { key = ReadBin_GetStringToken(stream); thisLevel[key] = new VdfFileNode(ReadBin_GetStringToken(stream)); } else if (nextByte == 2) { key = ReadBin_GetStringToken(stream); int val = stream.ReadInt32(); thisLevel[key] = new VdfFileNode(val); } else if (nextByte == 7) { key = ReadBin_GetStringToken(stream); ulong val = stream.ReadUInt64(); thisLevel[key] = new VdfFileNode(val); } else if (nextByte == 0xFF) { return(null); } else { throw new ParseException(string.Format(GlobalStrings.TextVdfFile_UnexpectedCharacterKey, nextByte)); } } return(thisLevel); }