예제 #1
0
 public static IEnumerable <T> DeserializeMultiple <T>(NestedDictionaryNode dicts, params object[] ctorArgs)
 {
     foreach (var dict in dicts)
     {
         yield return(Deserialize <T>(dict, ctorArgs));
     }
 }
예제 #2
0
        public static NestedDictionaryNode SerializeMultiple <T>(IEnumerable <T> values)
        {
            var node = new NestedDictionaryNode();

            foreach (var value in values)
            {
                node.NestedDictionaries.Add(SerializeDynamic(value));
            }

            return(node);
        }
예제 #3
0
        /// <summary>
        /// Parses the given ndf data into this nested dictionary node. This node will act as the root node for the parsed ndf data.
        /// </summary>
        /// <param name="p_ndf">The ndf data to parse.</param>
        public static NestedDictionaryNode ParseFromNdfString(string p_ndf)
        {
            var node = new NestedDictionaryNode();

            StringReader p_reader = new StringReader(p_ndf);

            node.NestedDictionaries = NestedDictionaryParser.ParseNDF(p_reader);
            p_reader.Close();

            return(node);
        }
예제 #4
0
        /// <summary>
        /// Returns a copy of this nested dictionary node and all its descendants.
        /// </summary>
        /// <returns>A copy of this nested dictionary node and all its descendants.</returns>
        public NestedDictionaryNode Clone()
        {
            NestedDictionaryNode p_clone = new NestedDictionaryNode();

            for (int i = 0; i < NestedDictionaries.Count; ++i)
            {
                p_clone.NestedDictionaries.Add(NestedDictionaries[i].Clone());
            }

            p_clone.Key   = Key;
            p_clone.Value = Value;
            return(p_clone);
        }
예제 #5
0
        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();
        }
예제 #6
0
        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();
        }
예제 #7
0
        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);
        }