private static void AddBuffer(NestedDictionaryNode p_node, NestedDictionary p_current_dict, EParsingPosition pos, StringBuilder p_buffer) { switch (pos) { case EParsingPosition.key: p_node.Key = p_buffer.ToString(); break; case EParsingPosition.value: p_node.Value = p_buffer.ToString(); break; } p_buffer.Clear(); }
internal static List <NestedDictionary> ParseNDF(TextReader p_reader) { List <NestedDictionary> p_ndf = new List <NestedDictionary>(); NestedDictionary p_current_dict = new NestedDictionary(); NestedDictionaryNode p_current_node = new NestedDictionaryNode(); EParsingPosition pos = EParsingPosition.key; bool is_escaped = false; StringBuilder p_buffer = new StringBuilder(); while (p_reader.Peek() != -1) { if (is_escaped) { p_buffer.Append((char)p_reader.Read()); // add to buffer for key or value continue; } switch (p_reader.Peek()) { // check for comment case (int)'/': p_reader.Read(); if (p_reader.Peek() == (int)'/') { int peek_val; StringBuilder p_comment = new StringBuilder(); do { p_reader.Read(); peek_val = p_reader.Peek(); p_comment.Append((char)peek_val); }while (peek_val != (int)'\n' && peek_val != -1); // comment terminates at EOF or line-end p_reader.Read(); } else { p_buffer.Append('/'); } break; case (int)':': // : are allowed for values, just not for keys if (pos == EParsingPosition.value) { goto default; } AddBuffer(p_current_node, p_current_dict, pos, p_buffer); // merge the key with the node p_reader.Read(); // consume pos = EParsingPosition.value; break; case (int)';': AddBuffer(p_current_node, p_current_dict, pos, p_buffer); // merge the value or the key with the node p_reader.Read(); // consume pos = EParsingPosition.key; AddNode(p_ndf, ref p_current_dict, ref p_current_node); // node end, so add the node break; case (int)'{': int trail_length = 0; for (int i = p_buffer.Length - 1; i > -1; --i) { switch (p_buffer[i]) { case '\r': case '\n': case '\t': case '\0': case ' ': ++trail_length; break; default: goto loop_end; } } loop_end: if (trail_length > 0) { p_buffer.Remove(p_buffer.Length - trail_length, trail_length); } AddBuffer(p_current_node, p_current_dict, pos, p_buffer); // merge the value or the key with the node p_reader.Read(); // consume before parsing the nested p_current_node.NestedDictionaries = ParseNDF(p_reader); // parse the nested dictionary AddNode(p_ndf, ref p_current_dict, ref p_current_node); // node end, so add the node pos = EParsingPosition.key; break; case (int)'}': p_reader.Read(); // consume before stopping execution if (p_current_dict.Count > 0) { p_ndf.Add(p_current_dict); // nested dictionary end } return(p_ndf); case (int)'\r': case (int)'\n': case (int)'\t': case (int)'\0': case (int)' ': if (pos == EParsingPosition.value) { p_buffer.Append((char)p_reader.Read()); } else { p_reader.Read(); // consume, ignored sign } break; case (int)'\\': is_escaped = true; p_reader.Read(); break; default: p_buffer.Append((char)p_reader.Read()); // add to buffer for key or value break; } } if (p_current_dict.Count > 0) { p_ndf.Add(p_current_dict); } PostProcess(p_ndf); return(p_ndf); }