示例#1
0
            static void WriteValueCommand(Df2Stream stream, uint?handle = null, bool commandName = true)
            {
                if (handle is not null)
                {
                    stream.BaseWriter !.Write((byte)Command.EditValueByHandle);
                    stream.BaseWriter !.WriteDf2UInt(handle.Value);
                }

                if (commandName)
                {
                    stream.BaseWriter !.Write((byte)Command.Value);
                }
            }
示例#2
0
        public bool ProcessCommand()
        {
            if (_stream.BaseReader is null)
            {
                throw new NotSupportedException("Stream is not configured for reading");
            }

            var cmd = (Command)_stream.BaseReader !.ReadByte();

            switch (cmd)
            {
            case Command.End:
            {
                _stream.HasReceivedEnd = true;
#if DEBUG
                _stream.CoreReceiveEvent("End;");
#endif
                return(false);
            }

            case Command.Group:
            {
                var path = Df2Stream.GetFullPath(_stream.BaseReader.ReadDf2String(),
                                                 _stream.InboundCurrentGroup?.AbsolutePath ?? "/");
#if DEBUG
                _stream.CoreReceiveEvent($"Group ({path});");
#endif
                if (string.IsNullOrWhiteSpace(path))
                {
                    if (path == string.Empty)
                    {
                        _stream.InboundCurrentGroup = null;
                        break;
                    }

                    throw new InvalidOperationException();
                }

                var previousPath = Df2Stream.GetFullPath("..", path);
                var parentValue  = _stream.GetValue(previousPath);
                if (parentValue is Value)
                {
                    throw new InvalidOperationException(
                              "The path to contain the group refers to a value instead of a group or the document root.");
                }

                var parentGroupDictionary =
                    (ValueDictionary)(parentValue is null ? _stream.Values : ((Group)parentValue).Values);

                var name = Path.GetFileName(path);
                if (!parentGroupDictionary.TryGetValue(name, out var value))
                {
                    parentGroupDictionary.Add(value = new Group(parentValue ?? _stream, name));
                }

                _stream.InboundCurrentGroup = (Group)value;
                break;
            }

            case Command.Value:
            {
                var kind = (ValueKind)_stream.BaseReader.ReadByte();
                var path = Df2Stream.GetFullPath(_stream.BaseReader.ReadDf2String(),
                                                 _stream.InboundCurrentGroup?.AbsolutePath ?? "/").TrimEnd('/');
                ValueTuple <ValueKind, string, object> recv = (kind, path, null);
                if (string.IsNullOrWhiteSpace(path))
                {
                    throw new InvalidOperationException("Path should not be null or whitespace");
                }

                var previousPath = Df2Stream.GetFullPath("..", path);
                var parentValue  = _stream.GetValue(previousPath);
                if (parentValue is Value)
                {
                    throw new InvalidOperationException(
                              "The path to contain the group refers to a value instead of a group or the document root.");
                }

                var currentDictionary =
                    (ValueDictionary)(parentValue is null ? _stream.Values : ((Group)parentValue).Values);
                var name = Path.GetFileName(path);
                if (currentDictionary.TryGetValue(name, out var val))
                {
                    ((Value)val).UpdateValue(kind, recv.Item3 = ReadValue(kind, out _));
                }
                else
                {
                    currentDictionary.Add(new Value((IGroupInternal)parentValue ?? _stream, name, kind,
                                                    recv.Item3 = ReadValue(kind, out _)));
                }

#if DEBUG
                _stream.CoreReceiveEvent(
                    $"Value {recv.Item1} ({recv.Item2}) ({Helpers.CoreToString(recv.Item3)});");
#endif

                break;
            }

            case Command.Remove:
            {
                var path = Df2Stream.GetFullPath(_stream.BaseReader.ReadDf2String(),
                                                 _stream.InboundCurrentGroup?.AbsolutePath ?? "/").TrimEnd('/');
                if (string.IsNullOrWhiteSpace(path))
                {
                    throw new InvalidOperationException("Path should not be null or whitespace");
                }

#if DEBUG
                _stream.CoreReceiveEvent($"Remove ({path});");
#endif

                var previousPath          = Df2Stream.GetFullPath("..", path);
                var parentValue           = _stream.GetValue(previousPath);
                var parentGroupDictionary =
                    (ValueDictionary)(parentValue is null ? _stream.Values : ((Group)parentValue).Values);
                parentGroupDictionary.Remove(Path.GetFileName(path));
                break;
            }

            case Command.Handle:
            {
                var rawPath = _stream.BaseReader.ReadDf2String();
                if (string.IsNullOrWhiteSpace(rawPath))
                {
                    ((IDictionary <uint, IValue>)_stream.Handles).Remove(_stream.BaseReader.ReadDf2UInt());
                    break;
                }

                var path = Df2Stream.GetFullPath(rawPath,
                                                 _stream.InboundCurrentGroup?.AbsolutePath ?? "/").TrimEnd('/');

                var value = _stream.GetValue(path);
                if (value is null)
                {
                    throw new InvalidOperationException("Can't assign a handle to the root of the document");
                }

                uint handle;
                ((IValueInternal)value).UpdateHandle(handle = _stream.BaseReader.ReadDf2UInt());
                ((IDictionary <uint, IValue>)_stream.Handles).Add(handle, value);
#if DEBUG
                _stream.CoreReceiveEvent($"Handle ({path}) {handle};");
#endif
                break;
            }

            case Command.EditValueByHandle:
            {
                uint handle;
                var  val = _stream.Handles[handle = _stream.BaseReader.ReadDf2UInt()];
                if (val is not Value value)
                {
                    throw new InvalidOperationException("Can only set a value of a handle referring to a value");
                }

                object read;
                value.UpdateValue(val.Kind, read = ReadValue(val.Kind, out _));
#if DEBUG
                _stream.CoreReceiveEvent($"EditValueByHandle {handle} ({Helpers.CoreToString(read)});");
#endif
                break;
            }

            case Command.GroupByHandle:
            {
                uint handle;
                var  val = _stream.Handles[handle = _stream.BaseReader.ReadDf2UInt()];
                if (val is not Group value)
                {
                    throw new InvalidOperationException("Can only set a value of a handle referring to a value");
                }

                _stream.InboundCurrentGroup = value;
#if DEBUG
                _stream.CoreReceiveEvent($"GroupByHandle {handle};");
#endif
                break;
            }

            default:
                throw new ArgumentOutOfRangeException();
            }

            return(true);
        }
示例#3
0
 public CommandReceiver(Df2Stream stream)
 {
     _stream = stream;
 }
示例#4
0
 public CommandSender(Df2Stream stream)
 {
     _stream = stream;
 }