Esempio n. 1
0
        /// <summary>
        ///  Read existing items in an existing Dictionary instance.
        ///  Used with Dictionaries of specific things which may or may not be present in the file, like Table.Columns.
        /// </summary>
        /// <typeparam name="T">Type of values in Dictionary</typeparam>
        /// <param name="reader">ITreeReader to read from</param>
        /// <param name="dictionary">Dictionary containing items to read</param>
        /// <param name="throwOnUnknown">True to throw for property name not in Dictionary, false to quietly skip over it</param>
        public static void ReadDictionaryItems <T>(this ITreeReader reader, Dictionary <string, T> dictionary, bool throwOnUnknown = true) where T : ITreeSerializable
        {
            reader.Expect(TreeToken.StartObject);
            reader.Read();

            while (reader.TokenType == TreeToken.PropertyName)
            {
                string itemName = reader.ReadAsString();
                reader.Read();

                if (dictionary.TryGetValue(itemName, out T item))
                {
                    item.Read(reader);
                    reader.Read();
                }
                else
                {
                    if (throwOnUnknown)
                    {
                        throw new IOException($"Found unknown {typeof(T).Name} property \"{itemName}\", expected one of \"{String.Join("; ", dictionary.Keys)}\" at {reader.Position:n0} using {reader.GetType().Name}.");
                    }
                    else
                    {
                        reader.Skip();
                    }
                }
            }

            reader.Expect(TreeToken.EndObject);
        }
Esempio n. 2
0
        /// <summary>
        ///  ReadObject wraps the loop to read each property in an object and call the corresponding
        ///  setter to set it.
        /// </summary>
        /// <remarks>
        ///  This works for classes only, as the instance can't be passed by ref.
        ///  Structs can serialize as arrays or directly implement the loop to decode themselves.
        ///  Setters take a reference to the instance so that the Dictionary can be static per type,
        ///  which is critical for acceptable performance.
        /// </remarks>
        /// <typeparam name="T">Type being deserialized</typeparam>
        /// <param name="reader">ITreeReader being read from</param>
        /// <param name="instance">T instance being initialized</param>
        /// <param name="setters">Dictionary of setter per field name</param>
        /// <param name="throwOnUnknown">Throw if property name not in setters found</param>
        public static void ReadObject <T>(this ITreeReader reader, T instance, Dictionary <string, Setter <T> > setters, bool throwOnUnknown = true) where T : ITreeSerializable
        {
            // Ensure object state reset before Read
            instance.Clear();

            reader.Expect(TreeToken.StartObject);
            reader.Read();

            while (reader.TokenType == TreeToken.PropertyName)
            {
                string propertyName = reader.ReadAsString();
                reader.Read();

                if (setters.TryGetValue(propertyName, out Setter <T> setter))
                {
                    setter(reader, instance);
                    reader.Read();
                }
                else
                {
                    if (throwOnUnknown)
                    {
                        throw new IOException($"Found unknown {typeof(T).Name} property, \"{propertyName}\", expected one of \"{String.Join("; ", setters.Keys)}\" at {reader.Position:n0} using {reader.GetType().Name}.");
                    }
                    else
                    {
                        reader.Skip();
                    }
                }
            }

            reader.Expect(TreeToken.EndObject);
            // EndObject must be left for caller to handle
        }
Esempio n. 3
0
        public static Dictionary <int, T> ReadIntDictionary <T>(this ITreeReader reader, Func <T> ctor) where T : ITreeSerializable
        {
            if (reader.TokenType == TreeToken.Null)
            {
                return(null);
            }
            Dictionary <int, T> result = new Dictionary <int, T>();

            reader.Expect(TreeToken.StartArray);
            reader.Read();

            int[] keys = reader.ReadBlockArray <int>();

            reader.Read();
            reader.Expect(TreeToken.StartArray);
            reader.Read();

            for (int i = 0; i < keys.Length; ++i)
            {
                int key = keys[i];

                T value = ctor();
                value.Read(reader);

                result[key] = value;

                reader.Read();
            }

            reader.Expect(TreeToken.EndArray);
            reader.Read();

            reader.Expect(TreeToken.EndArray);
            return(result);
        }
Esempio n. 4
0
        public static Dictionary <string, T> ReadStringDictionary <T>(this ITreeReader reader, Func <T> ctor) where T : ITreeSerializable
        {
            if (reader.TokenType == TreeToken.Null)
            {
                return(null);
            }
            Dictionary <string, T> result = new Dictionary <string, T>();

            reader.Expect(TreeToken.StartObject);
            reader.Read();

            while (reader.TokenType == TreeToken.PropertyName)
            {
                string key = reader.ReadAsString();
                reader.Read();

                T value = ctor();
                value.Read(reader);

                result[key] = value;

                reader.Read();
            }

            reader.Expect(TreeToken.EndObject);
            return(result);
        }
        public void CreateTree()
        {
            _reader.Read();
            var lines = _reader.Lines;

            foreach (string line in lines)
            {
                _binaryTree.AddLineBottom(CreateList(line));
            }
        }
Esempio n. 6
0
        private static void TestIntegers(TreeFormat format)
        {
            TreeSerializationSettings settings = new TreeSerializationSettings()
            {
                LeaveStreamOpen = true
            };

            using (MemoryStream stream = new MemoryStream())
            {
                using (ITreeWriter writer = Writer(format, stream, settings))
                {
                    writer.WriteStartArray();

                    for (int i = -1; i < 300; i += 7)
                    {
                        writer.WriteValue(i);
                    }

                    writer.WriteEndArray();
                }

                long bytesWritten = stream.Position;
                stream.Seek(0, SeekOrigin.Begin);

                using (ITreeReader reader = Reader(format, stream, settings))
                {
                    Assert.Equal(TreeToken.StartArray, reader.TokenType);

                    for (int i = -1; i < 300; i += 7)
                    {
                        Assert.True(reader.Read());
                        Assert.Equal(TreeToken.Integer, reader.TokenType);
                        Assert.Equal(i, reader.ReadAsInt32());
                    }

                    Assert.True(reader.Read());
                    Assert.Equal(TreeToken.EndArray, reader.TokenType);
                    Assert.False(reader.Read());
                }

                Assert.Equal(bytesWritten, stream.Position);
            }
        }
Esempio n. 7
0
        public static void VerifySkip <T>(T value, TreeFormat format) where T : ITreeSerializable
        {
            // Test serialization details
            using (MemoryStream stream = new MemoryStream())
            {
                TreeSerializationSettings settings = new TreeSerializationSettings()
                {
                    LeaveStreamOpen = true
                };

                using (ITreeWriter writer = Writer(format, stream, settings))
                {
                    value.Write(writer);
                }

                long bytesWritten = stream.Position;

                // Read tokens individually and verify 'None' returned at end
                stream.Seek(0, SeekOrigin.Begin);
                using (ITreeReader reader = Reader(format, stream, settings))
                {
                    while (reader.Read())
                    {
                        // Verify each token type is coming back properly (no reading random bytes)
                        Assert.True((byte)reader.TokenType <= (byte)TreeToken.BlockArray);
                    }

                    Assert.Equal(TreeToken.None, reader.TokenType);
                    Assert.Equal(bytesWritten, stream.Position);
                }

                // Verify Skip once skips everything (each ITreeSerializable must be one value or one root array or object
                stream.Seek(0, SeekOrigin.Begin);
                using (ITreeReader reader = Reader(format, stream, settings))
                {
                    reader.Skip();
                    Assert.Equal(TreeToken.None, reader.TokenType);
                    Assert.Equal(bytesWritten, stream.Position);
                }

                // For objects, verify each property can be skipped correctly
                // Each Skip should read the value, so that the next token is the next PropertyName
                stream.Seek(0, SeekOrigin.Begin);
                using (ITreeReader reader = Reader(format, stream, settings))
                {
                    if (reader.TokenType == TreeToken.StartObject)
                    {
                        Empty empty = new Empty();
                        empty.Read(reader);

                        Assert.Equal(bytesWritten, stream.Position);
                    }
                }
            }
        }
Esempio n. 8
0
        public static List <T> ReadList <T>(this ITreeReader reader, Func <T> ctor) where T : ITreeSerializable
        {
            if (reader.TokenType == TreeToken.Null)
            {
                return(null);
            }
            List <T> result = new List <T>();

            reader.Expect(TreeToken.StartArray);
            reader.Read();

            while (reader.TokenType != TreeToken.EndArray)
            {
                T item = ctor();
                item.Read(reader);

                result.Add(item);

                reader.Read();
            }

            return(result);
        }
Esempio n. 9
0
        /// <summary>
        ///  Skip the current token.
        ///  Reads a single token, or skips over an entire subtree for containers.
        /// </summary>
        /// <param name="reader">ITreeReader to skip next token from</param>
        public static void Skip(this ITreeReader reader)
        {
            int depth = 0;

            do
            {
                switch (reader.TokenType)
                {
                case TreeToken.StartArray:
                case TreeToken.StartObject:
                    depth++;
                    break;

                case TreeToken.EndArray:
                case TreeToken.EndObject:
                    depth--;
                    break;
                }

                reader.Read();
            } while (depth > 0);
        }