public static T Deserialize <T>(NestedDictionary dict, params object[] ctorArgs) { T obj; if (!dict.ContainsKey("$type") && dict.Count > 1) { try { obj = (T)Activator.CreateInstance(typeof(T), ctorArgs); } catch (Exception) { obj = (T)Activator.CreateInstance(typeof(T)); } } else if (dict.ContainsKey("$type")) { var type = Assembly.GetAssembly(typeof(T)).GetType(dict["$type"]); if (type.GetConstructor(ctorArgs.Select(a => a.GetType()).ToArray()) != null) { obj = (T)Activator.CreateInstance(type, ctorArgs); } else { obj = (T)Activator.CreateInstance(type); } } else { return(default(T)); } DeserializeDynamic(dict, obj, ctorArgs); return(obj); }
private static List <NestedDictionary> PostProcessSingle(NestedDictionary p_ndf_dict) { List <NestedDictionary> p_processed_dictionaries = new List <NestedDictionary>(); List <string> p_removed_keys = new List <string>(); foreach (KeyValuePair <string, NestedDictionaryNode> ndf_entry in p_ndf_dict) { PostProcess(ndf_entry.Value.NestedDictionaries); if (ndf_entry.Key.StartsWith("@PP.Replace[") && ndf_entry.Key.EndsWith("]") && ndf_entry.Value.NestedDictionaries.Count > 0) { string p_inner_key = ndf_entry.Key.Substring("@PP.Replace[".Length, ndf_entry.Key.Length - "@PP.Replace[".Length - "]".Length); string[] p_variable_names = p_inner_key.Split(',').OrderByDescending(key => key.Length).ToArray(); foreach (NestedDictionary p_nested_dict in ndf_entry.Value) { NestedDictionary p_processed_dict = p_ndf_dict.Clone(); foreach (string p_var_name in p_variable_names) { if (!p_nested_dict.ContainsKey(p_var_name)) { throw new Exception("Post-Processor Replace does not have all required variables defined. Missing " + p_var_name); } ReplaceVariable(p_processed_dict, p_var_name, p_nested_dict[p_var_name]); } p_processed_dictionaries.Add(p_processed_dict); } p_removed_keys.Add(ndf_entry.Key); break; } string p_value = ndf_entry.Value.Value; if (p_value == null || !p_value.StartsWith("@PP.Expand[") || !p_value.EndsWith("]")) { continue; } string p_inner = p_value.Substring("@PP.Expand[".Length, p_value.Length - "@PP.Expand[".Length - "]".Length); string[] p_expanded_values = p_inner.Split(','); foreach (string p_expanded_value in p_expanded_values) { NestedDictionary p_processed_dict = p_ndf_dict.Clone(); p_processed_dict[ndf_entry.Key].Value = p_expanded_value; p_processed_dictionaries.Add(p_processed_dict); } break; } foreach (string p_removed_key in p_removed_keys) { foreach (NestedDictionary p_nested_dict in p_processed_dictionaries) { p_nested_dict.Remove(p_removed_key); } } return(p_processed_dictionaries); }
/// <summary> /// Returns a clone of this nested dictionary and all its descendants. /// </summary> /// <returns>A clone of this nested dictionary and all its descendants.</returns> public NestedDictionary Clone() { NestedDictionary p_clone = new NestedDictionary(); foreach (KeyValuePair <string, NestedDictionaryNode> ndf_entry in this) { p_clone.Add(ndf_entry.Key, ndf_entry.Value.Clone()); } return(p_clone); }
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(); }
public static NestedDictionary Serialize <T>(T value) { var ndf = new NestedDictionary(); ndf.Add("", new NestedDictionaryNode() { Key = "" }); if (value != null) { Serializer <T> .Serialize(ndf, value); } return(ndf); }
private static void ReplaceVariable(NestedDictionary p_dictionary, string p_variable_name, string p_substitute) { foreach (KeyValuePair <string, NestedDictionaryNode> ndf_entry in p_dictionary) { if (ndf_entry.Value.Value != null) { ndf_entry.Value.Value = ndf_entry.Value.Value.Replace(p_variable_name, p_substitute); } foreach (NestedDictionary p_nested_dict in ndf_entry.Value) { ReplaceVariable(p_nested_dict, p_variable_name, p_substitute); } } }
private static void AddNode(List <NestedDictionary> p_ndf, ref NestedDictionary p_current_dict, ref NestedDictionaryNode p_current_node) { string p_node_key = p_current_node.Key; if (p_node_key == null) { return; // only occurs should the "node" be a reference } if (!p_current_dict.ContainsKey(p_node_key)) { p_current_dict.Add(p_node_key, p_current_node); } else { p_ndf.Add(p_current_dict); p_current_dict = new NestedDictionary(); p_current_dict.Add(p_node_key, p_current_node); } p_current_node = new NestedDictionaryNode(); }
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); }
static void genericHelper <T>(NestedDictionary dict2, T obj2, params object[] ctorArgs2) => Serializer <T> .Deserialize(dict2, obj2, ctorArgs2);
private static void DeserializeDynamic(NestedDictionary dict, dynamic obj, params object[] ctorArgs) { genericHelper(dict, obj, ctorArgs); }
internal static void Deserialize(NestedDictionary dict, T value, params object[] ctorArgs) => deserializeMethod(dict, value, ctorArgs);
internal static void Serialize(NestedDictionary dict, T value) => serializeMethod(dict, value);