private void CollectNodeArrayContents(dynamic node, ref List <dynamic> alreadyCollected) { if (node == null) { return; } foreach (var o in alreadyCollected.Where(x => !IEnumerableCompare.TypeNotEqual(x.GetType(), node.GetType()))) { if (node is string) { if (o == node) { return; } } else if (node is IEnumerable) { if (IEnumerableCompare.IsEqual(node, o)) { return; } } else if (node == o) { return; } } alreadyCollected.Add(node); if (node is string) { if (!_stringArray.Contains((string)node)) { _stringArray.Add((string)node); } } else if (node is List <ByamlPathPoint> ) { _pathArray.Add((List <ByamlPathPoint>)node); } else if (node is IDictionary <string, dynamic> ) { foreach (KeyValuePair <string, dynamic> entry in node) { if (!_nameArray.Contains(entry.Key)) { _nameArray.Add(entry.Key); } CollectNodeArrayContents(entry.Value, ref alreadyCollected); } } else if (node is IList <dynamic> ) { foreach (dynamic childNode in node) { CollectNodeArrayContents(childNode, ref alreadyCollected); } } }
private void WriteValueContents(BinaryDataWriter writer, Offset offset, ByamlNodeType type, dynamic value) { if (alreadyWrittenNodes.ContainsKey(value)) { offset.Satisfy((int)alreadyWrittenNodes[value]); return; } else if (value is IEnumerable) { foreach (var d in alreadyWrittenNodes.Keys.Where(x => x is IEnumerable && x.Count == value.Count)) { if (IEnumerableCompare.IsEqual(d, value)) { offset.Satisfy((int)alreadyWrittenNodes[d]); return; } } } // Satisfy the offset to the complex node value which must be 4-byte aligned. writer.Align(4); offset.Satisfy(); // Write the value contents. switch (type) { case ByamlNodeType.Dictionary: alreadyWrittenNodes.Add(value, (uint)writer.Position); WriteDictionaryNode(writer, value); break; case ByamlNodeType.StringArray: WriteStringArrayNode(writer, value); break; case ByamlNodeType.PathArray: alreadyWrittenNodes.Add(value, (uint)writer.Position); WritePathArrayNode(writer, value); break; case ByamlNodeType.Array: alreadyWrittenNodes.Add(value, (uint)writer.Position); WriteArrayNode(writer, value); break; case ByamlNodeType.Double: case ByamlNodeType.ULong: case ByamlNodeType.Long: writer.Write(value); break; default: throw new ByamlException($"{type} not supported as complex node."); } }
private Offset WriteValue(BinaryDataWriter writer, dynamic value) { // Only reserve and return an offset for the complex value contents, write simple values directly. ByamlNodeType type = GetNodeType(value); switch (type) { case ByamlNodeType.StringIndex: WriteStringIndexNode(writer, value); return(null); case ByamlNodeType.PathIndex: WritePathIndexNode(writer, value); return(null); case ByamlNodeType.Dictionary: case ByamlNodeType.Array: foreach (var d in alreadyWrittenNodes.Keys.Where(x => x is IEnumerable && x.Count == value.Count)) { if (IEnumerableCompare.IsEqual(d, value)) { writer.Write(alreadyWrittenNodes[d]); return(null); } } return(writer.ReserveOffset()); case ByamlNodeType.Boolean: writer.Write(value ? 1 : 0); return(null); case ByamlNodeType.Integer: case ByamlNodeType.Float: case ByamlNodeType.Uinteger: writer.Write(value); return(null); case ByamlNodeType.Double: case ByamlNodeType.ULong: case ByamlNodeType.Long: return(writer.ReserveOffset()); case ByamlNodeType.Null: writer.Write(0x0); return(null); default: throw new ByamlException($"{type} not supported as value node."); } }