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); } }
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); }
public CommandReceiver(Df2Stream stream) { _stream = stream; }
public CommandSender(Df2Stream stream) { _stream = stream; }