public static ListRand Deserealize(string str) { if (string.IsNullOrEmpty(str)) { return(new ListRand()); // deserialization of empty lists } var serializedNodes = str.Split(new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries); var map = new Dictionary <string, ValueTuple <string, string, string, string> >(); // using ValueTuple just because it is not required to write generic serializer foreach (var serializedNode in serializedNodes) { var parts = serializedNode.Split(new[] { _delim }, StringSplitOptions.RemoveEmptyEntries); if (parts.Length < 5) { // let's just throw an exception and write a good unit test throw new InvalidDataException("There are less parts in serialization data than we expect"); } // at some moment we will use more memory than we really need, optimisation isn't performed var id = parts[0].Split(_sep)[1]; var data = StringsEscaper.UnEscape(parts[1].Split(_sep)[1]); var rndIdx = parts[2].Split(_sep)[1]; var prevIdx = parts[3].Split(_sep)[1]; var nextIdx = parts[4].Split(_sep)[1]; map[id] = (data, rndIdx, prevIdx, nextIdx); } var lst = new ListRand(); var restoredNodes = new Dictionary <string, ListNode>(); var restoredNode = new ListNode(); foreach (var kv in map) { restoredNode = RestoreNode(kv.Key, map, restoredNodes); restoredNode.Rand = RestoreNode(kv.Value.Item2, map, restoredNodes); restoredNode.Prev = RestoreNode(kv.Value.Item3, map, restoredNodes); restoredNode.Next = RestoreNode(kv.Value.Item4, map, restoredNodes); } lst.Head = restoredNode; while (lst.Head.Next != null) // guess we can get rid of this, but as there is no requirement of high performance, no optimisation performed { lst.Head = lst.Head.Next; } lst.Tail = lst.Head.Prev; lst.Count = map.Count; return(lst); }
public ListSerializer(ListRand lst) { if (lst == null) { throw new ArgumentNullException(nameof(lst)); } _serializedList = lst; _objectToString = new Dictionary <object, string>(); _objectToIndex = new Dictionary <object, int>(); _index = 1; }