Exemplo n.º 1
0
        // public static StateMap<T> Deserialize(IReader reader, Path? path = null) {
        public static StateMap <T> Deserialize(IReader reader, Path path = null)
        {
            // path ??= Path.Root;
            path = path ?? Path.Root;

            var entries = new Dictionary <UInt32, T>();

            while (!reader.EndOfStream())
            {
                var tag = reader.ReadUInt32();
                entries[tag] = reader.ReadValue <T>(path, tag);
            }

            return(new StateMap <T>(path, entries));
        }
Exemplo n.º 2
0
        // public static StateList<T> Deserialize(IReader reader, Path? path = null) {
        public static StateList <T> Deserialize(IReader reader, Path path = null)
        {
            // path ??= Path.Root;
            path = path ?? Path.Root;

            var items = new List <T>();
            var tag   = 0U;

            while (!reader.EndOfStream())
            {
                items.Add(reader.ReadValue <T>(path, tag++));
            }

            return(new StateList <T>(path, items));
        }
Exemplo n.º 3
0
        // public static Vector<T> Deserialize(IReader reader, Path? path = null) {
        public static Vector <T> Deserialize(IReader reader, Path path = null)
        {
            // path ??= Path.Root;
            path = path ?? Path.Root;

            var items = new List <T>();
            var tag   = 0U;

            while (!reader.EndOfStream())
            {
                // Though Vector doesn't support nested states, passing tags to its children is still helpful.
                items.Add(reader.ReadValue <T>(path, tag++));
            }

            return(new Vector <T>(path, items));
        }
Exemplo n.º 4
0
        // public static StateMap<T> Deserialize(IReader reader, Path? path = null) {
        public static StateMap <T> Deserialize(IReader reader, Path path = null)
        {
            // path ??= Path.Root;
            path = path ?? Path.Root;

            var entries = new Dictionary <UInt32, T>();

            while (!reader.EndOfStream())
            {
                var tag = reader.ReadKey().Tag;
                // TODO: Wire type should be considered here.
                entries[tag] = reader.ReadValue <T>(path, tag);
            }

            return(new StateMap <T>(path, entries));
        }
Exemplo n.º 5
0
        public static void Replace(this IState state, IReader reader, bool shouldNotify = true)
        {
            if (state is IEnumState)
            {
                var variant = reader.ReadUInt32();
                state.ReplaceAt(variant, WireType.Sized, reader, shouldNotify);
                return;
            }

            while (!reader.EndOfStream())
            {
                var(tag, wireType) = reader.ReadKey();
                var expectedWireType = state.GetWireType(tag);
                var fieldReader      = wireType == WireType.Sized ? reader.GetNested() : reader;

                // `expectedWireType` being `null` means that `state` either:
                // (1) doesn't recognize this field;
                // (2) has no clear expectation for the field's wire type (e.g. there are multiple valid wire types); or
                // (3) doesn't support update operations.
                //
                // An exception is expected to be thrown in case (3).
                // So, if we skip the field here, that would cause an exception leak
                // and make the program continue functioning with undefined behavior.
                //
                // That's why we leave to `state.ReplaceAt()` to handle instead,
                // since `state` knows best which case will happen.
                //
                // `state.ReplaceAt()` will then handle the cases as below:
                // * Case (1): It skips the unrecognized field.
                // * Case (2) or when wire types match: It reads the field based on passed `wireType`.
                // * Case (3): It throws an exception.
                //
                // On the other hand, if `expectedWireType` is clearly defined but doesn't match with `wireType`,
                // we don't hesitate to skip the field right here.

                if (expectedWireType != null && wireType != expectedWireType)
                {
                    var path = state.Path.GetNested(tag);
                    Console.Error.WriteLine("Expected wire type {0} for path {1}, got {2}.", expectedWireType, path, wireType);
                    fieldReader.SkipField(wireType);
                    continue;
                }

                state.ReplaceAt(tag, wireType, fieldReader, shouldNotify);
            }
        }