示例#1
0
 public LiteralCommand(ulong length)
 {
     if (length <= _baseCommand)
     {
         _shortLiteralLength = (byte)length;
         _lengthArg          = default;
     }
     else
     {
         _lengthArg          = new CommandArg(length);
         _shortLiteralLength = 0;
     }
 }
示例#2
0
        public static OperationStatus ReadFrom(
            ReadOnlySpan <byte> span,
            CommandModifier modifier,
            out CommandArg arg)
        {
            bool  ok;
            ulong value;
            int   size;

            switch (modifier)
            {
            case CommandModifier.ZeroBytes:
                size  = 0;
                ok    = true;
                value = 0;
                break;

            case CommandModifier.OneByte:
                size  = 1;
                ok    = span.Length >= 1;
                value = ok ? span[0] : 0UL;
                break;

            case CommandModifier.TwoBytes:
                size  = 2;
                ok    = BinaryPrimitives.TryReadUInt16BigEndian(span, out var valShort);
                value = valShort;
                break;

            case CommandModifier.FourBytes:
                size  = 4;
                ok    = BinaryPrimitives.TryReadUInt32BigEndian(span, out var valInt);
                value = valInt;
                break;

            case CommandModifier.EightBytes:
                size = 8;
                ok   = BinaryPrimitives.TryReadUInt64BigEndian(span, out value);
                break;

            default:
                throw new ArgumentException($"{nameof(CommandModifier)}.{modifier}");
            }
            if (!ok)
            {
                arg = default;
                return(OperationStatus.NeedMoreData);
            }
            arg = new CommandArg(value, size, modifier);
            return(OperationStatus.Done);
        }
示例#3
0
        public OperationStatus ReadFrom(
            ReadOnlySpan <byte> span,
            out CopyCommand copy)
        {
            if (span.Length < _minSize)
            {
                copy = default;
                return(OperationStatus.NeedMoreData);
            }
            byte       command    = span[0];
            const byte minCommand = _baseCommand +
                                    4 * (byte)CommandModifier.OneByte +
                                    (byte)CommandModifier.OneByte;
            const byte maxCommand = _baseCommand +
                                    4 * (byte)CommandModifier.EightBytes +
                                    (byte)CommandModifier.EightBytes;

            if (command < minCommand || command > maxCommand)
            {
                copy = default;
                return(OperationStatus.InvalidData);
            }
            command -= _baseCommand;

            var startModifier = (CommandModifier)(command >> 2);
            var opStatus      = CommandArg.ReadFrom(
                span.Slice(1),
                startModifier,
                out var startArg);

            if (opStatus != OperationStatus.Done)
            {
                copy = default;
                return(opStatus);
            }

            var lengthModifier = (CommandModifier)(command & 0x03);

            opStatus = CommandArg.ReadFrom(
                span.Slice(1 + startArg.Size),
                lengthModifier,
                out var lengthArg);
            if (opStatus != OperationStatus.Done)
            {
                copy = default;
                return(opStatus);
            }

            copy = new CopyCommand(startArg, lengthArg);
            return(OperationStatus.Done);
        }
示例#4
0
        public OperationStatus ReadFrom(
            ReadOnlySpan <byte> span,
            out LiteralCommand literal)
        {
            if (span.Length < _minSize)
            {
                literal = default;
                return(OperationStatus.NeedMoreData);
            }
            byte       command    = span[0];
            const byte maxCommand = _baseCommand + (byte)CommandModifier.EightBytes;

            if (command == 0 || command > maxCommand)
            {
                literal = default;
                return(OperationStatus.InvalidData);
            }
            else if (command < _baseCommand)
            {
                literal = new LiteralCommand(length: command);
                return(OperationStatus.Done);
            }

            var argModifier = (CommandModifier)(command - _baseCommand);
            var opStatus    = CommandArg.ReadFrom(
                span.Slice(1),
                argModifier,
                out var arg);

            if (opStatus != OperationStatus.Done)
            {
                literal = default;
                return(opStatus);
            }
            literal = new LiteralCommand(arg);
            return(OperationStatus.Done);
        }
示例#5
0
 private CopyCommand(CommandArg startArg, CommandArg lengthArg)
 {
     _start  = startArg;
     _length = lengthArg;
 }
示例#6
0
 public CopyCommand(LongRange range)
 {
     _start  = new CommandArg((ulong)range.Start);
     _length = new CommandArg((ulong)range.Length);
 }
示例#7
0
 private LiteralCommand(CommandArg arg)
 {
     _lengthArg          = arg;
     _shortLiteralLength = 0;
 }