示例#1
0
#pragma warning restore 0414

        public Asn1Reader(
            ReadOnlySpan <byte> buffer,
            int maxDepth = 8)
        {
            if (maxDepth < 0 || maxDepth > 8)
            {
                throw new IndexOutOfRangeException();
            }

            _buffer   = buffer;
            _maxDepth = 1 + maxDepth;

            _depth  = 0;
            _failed = false;

            _stack0 = new StartAndLength(0, buffer.Length);
            _stack1 = default(StartAndLength);
            _stack2 = default(StartAndLength);
            _stack3 = default(StartAndLength);
            _stack4 = default(StartAndLength);
            _stack5 = default(StartAndLength);
            _stack6 = default(StartAndLength);
            _stack7 = default(StartAndLength);
            _stack8 = default(StartAndLength);
        }
示例#2
0
        public void Null()
        {
            StartAndLength bytes = Read(0x05);

            if (_failed || !bytes.IsEmpty)
            {
                Fail();
            }
        }
示例#3
0
        public void Null()
        {
            StartAndLength bytes = Read(0x05);

            if (_failed || bytes.Length != 0)
            {
                Fail();
            }
        }
示例#4
0
        public void BeginSequence()
        {
            StartAndLength bytes = Read(0x30);

            if (!_failed)
            {
                _depth++;
                Top = bytes;
            }
        }
示例#5
0
        public Asn1Reader(
            ref ReadOnlySpan <byte> buffer,
            int maxDepth = 8)
        {
#if UNSAFE
            _buffer = Unsafe.AsPointer(ref buffer);
#else
            _buffer = buffer;
#endif
            _depth  = 0;
            _failed = false;
            _stack  = new StartAndLength[maxDepth];
            Top     = new StartAndLength(0, buffer.Length);
        }
示例#6
0
        private StartAndLength Read(
            int tag)
        {
            StartAndLength      top    = Top;
            StartAndLength      result = default(StartAndLength);
            ReadOnlySpan <byte> span   = top.ApplyTo(_buffer);
            int length = 0;

            if (_failed || span.Length < 2 || span[0] != tag)
            {
                goto fail;
            }

            int pos = 2;

            if ((span[1] & 0x80) == 0)
            {
                length = span[1];
            }
            else
            {
                int c = span[1] & 0x7F;
                if (c == 0 || c > sizeof(int) || c > span.Length - 2 || span[2] == 0)
                {
                    goto fail;
                }
                while (c-- > 0)
                {
                    length = (length << 8) | span[pos++];
                }
                if (length < 0x80)
                {
                    goto fail;
                }
            }

            if (length > span.Length - pos)
            {
                goto fail;
            }

            result = top.Slice(pos, length);
            Top    = top.Slice(pos + length);
            goto done;
fail:
            Fail();
done:
            return(result);
        }
示例#7
0
        public static StartAndLength[] CalculateStartAndLengthForAllRanks(int totalLayers, Mpi mpi)
        {
            int size = mpi.Size;

            var result = new StartAndLength[size];

            for (int rank = 0; rank < result.Length; rank++)
            {
                int start  = DetermineStart(totalLayers, size, rank);
                int length = DetermineLength(totalLayers, size, rank);

                result[rank] = new StartAndLength(start, length);
            }

            return(result);
        }
示例#8
0
        private StartAndLength Read(
            int tag)
        {
            StartAndLength      top  = Unsafe.Add(ref _stack0, _depth);
            ReadOnlySpan <byte> span = top.ApplyTo(_buffer);

            if (_failed || span.Length < 2 || span[0] != tag)
            {
                goto fail;
            }

            int start  = 2;
            int length = 0;

            if ((span[1] & ~0x7F) == 0)
            {
                length = span[1];
            }
            else
            {
                int count = span[1] & 0x7F;
                if (count < 1 || count > sizeof(int) || count > span.Length - 2 || span[2] == 0)
                {
                    goto fail;
                }
                while (count-- > 0)
                {
                    length = (length << 8) | span[start++];
                }
                if (length < 0x80)
                {
                    goto fail;
                }
            }

            if (length > span.Length - start)
            {
                goto fail;
            }

            Unsafe.Add(ref _stack0, _depth) = top.Slice(start + length);
            return(top.Slice(start, length));

fail:
            Fail();
            return(default(StartAndLength));
        }
示例#9
0
        public void BeginSequence()
        {
            StartAndLength bytes = Read(0x30);

            if (_failed)
            {
                Fail();
            }
            else
            {
                _depth++;
                if (_depth == _maxDepth)
                {
                    throw new IndexOutOfRangeException();
                }
                Unsafe.Add(ref _stack0, _depth) = bytes;
            }
        }
示例#10
0
 private void Fail()
 {
     _failed = true;
     _depth  = 0;
     _stack0 = default(StartAndLength);
 }