/// <summary> /// Serialize linked list and write to file stream. /// </summary> /// <param name="fs">File stream for writing serialized list</param> /// <param name="list">Linked list to serialize</param> public static void Serialize(FileStream fs, ListRand list) { Dictionary <ListNode, int> nodeToIndex = GetNodeToIndex(list); string listJson = GetListJson(list, nodeToIndex); byte[] bytes = new UTF8Encoding(true).GetBytes(listJson); fs.Write(bytes, 0, bytes.Length); }
/// <summary> /// Restore linked list fields and node references. /// </summary> /// <param name="list">Linked list to restore</param> /// <param name="nodeInfos">List of NodeInfo with nodes and their field values</param> private static void FillList(ListRand list, List <NodeInfo> nodeInfos) { if (nodeInfos.Count <= 0) { return; } ConnectNodes(nodeInfos); list.Head = nodeInfos.First().Node; list.Tail = nodeInfos.Last().Node; list.Count = nodeInfos.Count; }
/// <summary> /// Create a dictionary where each node is paired with it's index, if it was a simple array. /// Stop creating dictionary when next node is null or hit cycle. /// </summary> /// <param name="list">Linked list</param> /// <returns>Dictionary with nodes paired with their indexes</returns> private static Dictionary <ListNode, int> GetNodeToIndex(ListRand list) { Dictionary <ListNode, int> nodeToIndex = new Dictionary <ListNode, int>(); ListNode node = list.Head; int index = 0; while (node != null && !nodeToIndex.ContainsKey(node)) { nodeToIndex.Add(node, index++); node = node.Next; } return(nodeToIndex); }
/// <summary> /// Deserialize linked list from file stream. /// </summary> /// <param name="fs">File stream to read from</param> /// <param name="list">List to deserialize to</param> /// <exception cref="UnexpectedEndException">Thrown when reach end of stream before finished deserializing</exception> /// <exception cref="UnexpectedCharException">Thrown when found unexpected char</exception> public static void Deserialize(FileStream fs, ListRand list) { CheckStreamBeginning(fs); List <NodeInfo> nodeInfos = new List <NodeInfo>(); bool readNode = false; while (true) { int b = fs.ReadByte(); if (b == '{' && !readNode) { readNode = true; nodeInfos.Add(DeserializeNode(fs)); } else if (b == ',' && readNode) { readNode = false; } else if (b == -1) { throw new UnexpectedEndException(); } else if (b == ']') { break; } else { throw new UnexpectedCharException((char)b); } } FillList(list, nodeInfos); }
/// <summary> /// Write list with all nodes to string in json format. /// Stop writing json when next node is null or hit cycle. /// </summary> /// <param name="list">List to write to json</param> /// <param name="nodeToIndex">Dictionary with nodes paired with their indexes</param> /// <returns>List in json format</returns> private static string GetListJson(ListRand list, Dictionary <ListNode, int> nodeToIndex) { StringBuilder sb = new StringBuilder(); sb.Append("["); HashSet <ListNode> visitedNodes = new HashSet <ListNode>(); ListNode node = list.Head; while (node != null) { visitedNodes.Add(node); WriteNode(node, sb, nodeToIndex); node = node.Next; if (node == null || visitedNodes.Contains(node)) { break; } sb.Append(","); } sb.Append("]"); return(sb.ToString()); }