// guards against cases where the caller attempts to skip when reader is not positioned at the start of a value
 static void ValidatePop(CborReaderState state, int depth)
 {
     if (depth == 0)
     {
         throw new InvalidOperationException(SR.Format(SR.Cbor_Reader_Skip_InvalidState, state));
     }
 }
Beispiel #2
0
 // guards against cases where the caller attempts to skip when reader is not positioned at the start of a value
 static void ValidatePop(CborReaderState state, int depth)
 {
     if (depth == 0)
     {
         throw new InvalidOperationException($"Reader state {state} is not at start of a data item.");
     }
 }
Beispiel #3
0
        public void SkipDataItem()
        {
            CborReaderHeader header = GetHeader();

            switch (header.MajorType)
            {
            case CborMajorType.PositiveInteger:
            case CborMajorType.NegativeInteger:
                ReadInteger();
                break;

            case CborMajorType.ByteString:
            case CborMajorType.TextString:
                ReadSizeAndBytes();
                break;

            case CborMajorType.Array:
                SkipArray();
                break;

            case CborMajorType.Map:
                SkipMap();
                break;

            case CborMajorType.SemanticTag:
                _state = CborReaderState.Data;
                break;

            case CborMajorType.Primitive:
                switch (header.Primitive)
                {
                case CborPrimitive.False:
                case CborPrimitive.True:
                case CborPrimitive.Null:
                case CborPrimitive.Undefined:
                case CborPrimitive.SimpleValue:
                case CborPrimitive.Break:
                    _state = CborReaderState.Data;
                    break;

                case CborPrimitive.HalfFloat:
                    Advance(2);
                    break;

                case CborPrimitive.SingleFloat:
                    Advance(4);
                    break;

                case CborPrimitive.DoubleFloat:
                    Advance(8);
                    break;

                case CborPrimitive.DecimalFloat:
                    Advance(16);
                    break;
                }
                break;
            }
        }
Beispiel #4
0
 public void ReturnToBookmark(CborReaderBookmark bookmark)
 {
     _buffer             = bookmark.buffer;
     _currentPos         = bookmark.currentPos;
     _state              = bookmark.state;
     _header             = bookmark.header;
     _remainingItemCount = bookmark.remainingItemCount;
 }
Beispiel #5
0
 public CborReader(ReadOnlySpan <byte> buffer)
 {
     _buffer             = buffer;
     _currentPos         = 0;
     _state              = CborReaderState.Start;
     _header             = new CborReaderHeader();
     _remainingItemCount = 0;
 }
Beispiel #6
0
 private void SkipSemanticTag()
 {
     if (Accept(CborMajorType.SemanticTag))
     {
         ReadInteger();
         _state = CborReaderState.Data;
         return;
     }
 }
Beispiel #7
0
 private void Advance(int length = 1)
 {
     if (_state == CborReaderState.Header)
     {
         _state = CborReaderState.Data;
     }
     _buffer      = _buffer.Slice(length);
     _currentPos += length;
 }
Beispiel #8
0
        private bool Accept(CborPrimitive primitive)
        {
            if (Accept(CborMajorType.Primitive) && _header.Primitive == primitive)
            {
                _state = CborReaderState.Data;
                return(true);
            }

            return(false);
        }
Beispiel #9
0
        public int ReadSize()
        {
            if (GetHeader().AdditionalValue == INDEFINITE_LENGTH)
            {
                _state = CborReaderState.Data;
                return(-1);
            }

            return((int)ReadInteger(int.MaxValue));
        }
Beispiel #10
0
        private void SkipArray()
        {
            int size = ReadSize();

            while (size > 0 || size < 0 && GetCurrentDataItemType() != CborDataItemType.Break)
            {
                SkipDataItem();
                size--;
            }

            _state = CborReaderState.Start;
        }
Beispiel #11
0
        public bool TryReadSemanticTag(out ulong semanticTag)
        {
            if (Accept(CborMajorType.SemanticTag))
            {
                semanticTag = ReadInteger();
                _state      = CborReaderState.Data;
                return(true);
            }

            semanticTag = 0;
            return(false);
        }
Beispiel #12
0
        public void ReadArray <TC>(ICborArrayReader <TC> arrayReader, ref TC context)
        {
            ReadBeginArray();

            int size = ReadSize();

            arrayReader.ReadBeginArray(size, ref context);

            while (size > 0 || size < 0 && GetCurrentDataItemType() != CborDataItemType.Break)
            {
                arrayReader.ReadArrayItem(ref this, ref context);
                size--;
            }

            _state = CborReaderState.Start;
        }
        private static CborObject Read(CborReader reader)
        {
            CborReaderState s = reader.PeekState();

            return(s switch
            {
                CborReaderState.StartMap => ReadMap(reader),
                CborReaderState.StartArray => ReadArray(reader),
                CborReaderState.TextString => new CborTextString(reader.ReadTextString()),
                CborReaderState.Boolean => new CborBoolean(reader.ReadBoolean()),
                CborReaderState.ByteString => new CborByteString(reader.ReadByteString()),
                CborReaderState.UnsignedInteger => new CborInteger(reader.ReadInt64()),
                CborReaderState.NegativeInteger => new CborInteger(reader.ReadInt64()),
                CborReaderState.Null => ReadNull(reader),
                _ => throw new Exception($"Unhandled state. Was {s}")
            });
Beispiel #14
0
        private ulong ReadInteger(ulong maxValue = ulong.MaxValue)
        {
            CborReaderHeader header = GetHeader();

            ulong value;

            switch (header.AdditionalValue)
            {
            // 8 bits
            case 24:
                value = ReadBytes(1)[0];
                break;

            // 16 bits
            case 25:
                value = BinaryPrimitives.ReadUInt16BigEndian(ReadBytes(2));
                break;

            // 32 bits
            case 26:
                value = BinaryPrimitives.ReadUInt32BigEndian(ReadBytes(4));
                break;

            // 64 bits
            case 27:
                value = BinaryPrimitives.ReadUInt64BigEndian(ReadBytes(8));
                break;

            case 28:
            case 29:
            case 30:
            case 31:
                throw BuildException($"Unexpected additional value {header.AdditionalValue}");

            default:
                value  = header.AdditionalValue;
                _state = CborReaderState.Data;
                break;
            }

            if (value > maxValue)
            {
                throw BuildException("Invalid signed integer");
            }

            return(value);
        }
        public static void ReadMap_DuplicateKeys_StrictConformance_ShouldThrowFormatException(CborConformanceLevel level, object dupeKey, string hexEncoding)
        {
            var reader = new CborReader(hexEncoding.HexToByteArray(), level);

            reader.ReadStartMap();
            Helpers.VerifyValue(reader, dupeKey);
            reader.ReadInt32();

            int             bytesRead = reader.BytesRead;
            CborReaderState state     = reader.PeekState();

            Assert.Throws <FormatException>(() => Helpers.VerifyValue(reader, dupeKey));

            // ensure reader state is preserved
            Assert.Equal(bytesRead, reader.BytesRead);
            Assert.Equal(state, reader.PeekState());
        }
Beispiel #16
0
        public void ReadMap <TC>(ICborMapReader <TC> mapReader, ref TC context)
        {
            ReadBeginMap();

            int previousRemainingItemCount = _remainingItemCount;

            _remainingItemCount = ReadSize();

            mapReader.ReadBeginMap(_remainingItemCount, ref context);

            while (MoveNextMapItem())
            {
                mapReader.ReadMapItem(ref this, ref context);
            }

            _state = CborReaderState.Start;
            _remainingItemCount = previousRemainingItemCount;
        }
        public static void ReadMap_UnsortedKeys_ConformanceRequiringSortedKeys_ShouldThrowFormatException(CborConformanceLevel level, object[] keySequence, string hexEncoding)
        {
            var reader = new CborReader(hexEncoding.HexToByteArray(), level);

            reader.ReadStartMap();
            foreach (object key in keySequence.SkipLast(1))
            {
                Helpers.VerifyValue(reader, key); // verify key
                reader.ReadInt32();               // value is always an integer
            }

            int             bytesRead = reader.BytesRead;
            CborReaderState state     = reader.PeekState();

            // the final element violates sorting invariant
            Assert.Throws <FormatException>(() => Helpers.VerifyValue(reader, keySequence.Last()));

            // ensure reader state is preserved
            Assert.Equal(bytesRead, reader.BytesRead);
            Assert.Equal(state, reader.PeekState());
        }
Beispiel #18
0
        private CborReaderHeader GetHeader()
        {
            if (_state == CborReaderState.Header)
            {
                return(_header);
            }

            ExpectLength(1);

            _header.MajorType       = (CborMajorType)((_buffer[0] >> 5) & 0x07);
            _header.AdditionalValue = (byte)(_buffer[0] & 0x1f);

            if (_header.MajorType > CborMajorType.Max)
            {
                throw new CborException($"Invalid major type {_header.MajorType}");
            }

            Advance();
            _state = CborReaderState.Header;

            return(_header);
        }
Beispiel #19
0
                static void VerifyPeekInteger(CborReader reader, bool isUnsignedInteger)
                {
                    CborReaderState expectedState = isUnsignedInteger ? CborReaderState.UnsignedInteger : CborReaderState.NegativeInteger;

                    Assert.Equal(expectedState, reader.PeekState());
                }
Beispiel #20
0
        /// <summary>
        /// The try parse special.
        /// </summary>
        /// <returns>
        /// The <see cref="bool"/>.
        /// </returns>
        /// <exception cref="CborException">
        /// </exception>
        private bool TryParseSpecial()
        {
            if (!this._input.HasBytes(this._size))
            {
                return false;
            }

            uint code;

            switch (this._size)
            {
                case 1:
                    code = this._input.GetInt8();
                    break;
                case 2:
                    code = this._input.GetInt16();
                    break;
                case 4:
                    code = this._input.GetInt32();
                    break;
                case 8:
                    throw new CborException("8 bytes special codes not supported");
                default:
                    throw new CborException("invalid special code size");
            }

            switch (code)
            {
                case 27: // double
                    this._size = 8;
                    this._state = CborReaderState.FloatData;
                    break;
                default:
                    this._listener.OnSpecial(code);
                    this._state = CborReaderState.Type;
                    break;
            }

            return true;
        }
Beispiel #21
0
        /// <summary>
        /// The try parse pint.
        /// </summary>
        /// <returns>
        /// The <see cref="bool"/>.
        /// </returns>
        /// <exception cref="CborException">
        /// </exception>
        private bool TryParsePint()
        {
            if (!this._input.HasBytes(this._size))
            {
                return false;
            }

            switch (this._size)
            {
                case 1:
                    this._listener.OnInteger(this._input.GetInt8(), 1);
                    break;
                case 2:
                    this._listener.OnInteger(this._input.GetInt16(), 1);
                    break;
                case 4:
                    this._listener.OnInteger(this._input.GetInt32(), 1);
                    break;
                case 8:
                    this._listener.OnLong(this._input.GetInt64(), 1);
                    break;
                default:
                    throw new CborException("invalid positive integer size");
            }

            this._state = CborReaderState.Type;

            return true;
        }
Beispiel #22
0
        /// <summary>
        /// The try parse string data.
        /// </summary>
        /// <returns>
        /// The <see cref="bool"/>.
        /// </returns>
        private bool TryParseStringData()
        {
            if (!this._input.HasBytes(this._size))
            {
                return false;
            }

            this._listener.OnString(Encoding.UTF8.GetString(this._input.GetBytes(this._size)));
            this._state = CborReaderState.Type;
            return true;
        }
Beispiel #23
0
        /// <summary>
        /// The try parse string size.
        /// </summary>
        /// <returns>
        /// The <see cref="bool"/>.
        /// </returns>
        /// <exception cref="CborException">
        /// </exception>
        private bool TryParseStringSize()
        {
            if (!this._input.HasBytes(this._size))
            {
                return false;
            }

            switch (this._size)
            {
                case 1:
                    this._size = (int)this._input.GetInt8();
                    break;
                case 2:
                    this._size = (int)this._input.GetInt16();
                    break;
                case 4:
                    this._size = (int)this._input.GetInt32();
                    break;
                case 8:
                    throw new CborException("8 bytes string size not supported");
                default:
                    throw new CborException("invalid string size");
            }

            this._state = CborReaderState.StringData;

            return true;
        }
Beispiel #24
0
        /// <summary>
        /// The try parse tag.
        /// </summary>
        /// <returns>
        /// The <see cref="bool"/>.
        /// </returns>
        /// <exception cref="CborException">
        /// </exception>
        private bool TryParseTag()
        {
            if (!this._input.HasBytes(this._size))
            {
                return false;
            }

            switch (this._size)
            {
                case 1:
                    this._listener.OnTag(this._input.GetInt8());
                    break;
                case 2:
                    this._listener.OnTag(this._input.GetInt16());
                    break;
                case 4:
                    this._listener.OnTag(this._input.GetInt32());
                    break;
                case 8:
                    throw new CborException("8 bytes tags not supported");
                default:
                    throw new CborException("invalid tag size");
            }

            this._state = CborReaderState.Type;

            return true;
        }
Beispiel #25
0
        /// <summary>
        /// The try parse type.
        /// </summary>
        /// <returns>
        /// The <see cref="bool"/>.
        /// </returns>
        /// <exception cref="CborException">
        /// </exception>
        private bool TryParseType()
        {
            if (!this._input.HasBytes(1))
            {
                return false;
            }

            int type = this._input.GetByte();
            int majorType = type >> 5;
            int minorType = type & 31;

            switch (majorType)
            {
                case 0: // positive integer
                    if (minorType < 24)
                    {
                        this._listener.OnInteger((uint)minorType, 1);
                    }
                    else if (minorType == 24)
                    {
                        this._state = CborReaderState.Pint;
                        this._size = 1;
                    }
                    else if (minorType == 25)
                    {
                        this._state = CborReaderState.Pint;
                        this._size = 2;
                    }
                    else if (minorType == 26)
                    {
                        this._state = CborReaderState.Pint;
                        this._size = 4;
                    }
                    else if (minorType == 27)
                    {
                        this._state = CborReaderState.Pint;
                        this._size = 8;
                    }
                    else
                    {
                        throw new CborException("invalid positive integer constructor");
                    }

                    break;
                case 1: // negative integer
                    if (minorType < 24)
                    {
                        this._listener.OnInteger((uint)minorType, -1);
                    }
                    else if (minorType == 24)
                    {
                        this._state = CborReaderState.Nint;
                        this._size = 1;
                    }
                    else if (minorType == 25)
                    {
                        this._state = CborReaderState.Nint;
                        this._size = 2;
                    }
                    else if (minorType == 26)
                    {
                        this._state = CborReaderState.Nint;
                        this._size = 4;
                    }
                    else if (minorType == 27)
                    {
                        this._state = CborReaderState.Nint;
                        this._size = 8;
                    }
                    else
                    {
                        throw new CborException("invalid negative integer constructor");
                    }

                    break;
                case 2: // bytes
                    if (minorType < 24)
                    {
                        this._state = CborReaderState.BytesData;
                        this._size = minorType;
                    }
                    else if (minorType == 24)
                    {
                        this._state = CborReaderState.BytesSize;
                        this._size = 1;
                    }
                    else if (minorType == 25)
                    {
                        this._state = CborReaderState.BytesSize;
                        this._size = 2;
                    }
                    else if (minorType == 26)
                    {
                        this._state = CborReaderState.BytesSize;
                        this._size = 4;
                    }
                    else if (minorType == 27)
                    {
                        this._state = CborReaderState.BytesSize;
                        this._size = 8;
                    }
                    else
                    {
                        throw new CborException("invalid bytes constructor");
                    }

                    break;
                case 3: // string
                    if (minorType < 24)
                    {
                        this._state = CborReaderState.StringData;
                        this._size = minorType;
                    }
                    else if (minorType == 24)
                    {
                        this._state = CborReaderState.StringSize;
                        this._size = 1;
                    }
                    else if (minorType == 25)
                    {
                        this._state = CborReaderState.StringSize;
                        this._size = 2;
                    }
                    else if (minorType == 26)
                    {
                        this._state = CborReaderState.StringSize;
                        this._size = 4;
                    }
                    else if (minorType == 27)
                    {
                        this._state = CborReaderState.StringSize;
                        this._size = 8;
                    }
                    else
                    {
                        throw new CborException("invalid string constructor");
                    }

                    break;
                case 4: // array
                    if (minorType < 24)
                    {
                        this._listener.OnArray(minorType);
                    }
                    else if (minorType == 24)
                    {
                        this._state = CborReaderState.Array;
                        this._size = 1;
                    }
                    else if (minorType == 25)
                    {
                        this._state = CborReaderState.Array;
                        this._size = 2;
                    }
                    else if (minorType == 26)
                    {
                        this._state = CborReaderState.Array;
                        this._size = 4;
                    }
                    else if (minorType == 27)
                    {
                        this._state = CborReaderState.Array;
                        this._size = 8;
                    }
                    else
                    {
                        throw new CborException("invalid array constructor");
                    }

                    break;
                case 5: // map
                    if (minorType < 24)
                    {
                        this._listener.OnMap(minorType);
                    }
                    else if (minorType == 24)
                    {
                        this._state = CborReaderState.Map;
                        this._size = 1;
                    }
                    else if (minorType == 25)
                    {
                        this._state = CborReaderState.Map;
                        this._size = 2;
                    }
                    else if (minorType == 26)
                    {
                        this._state = CborReaderState.Map;
                        this._size = 4;
                    }
                    else if (minorType == 27)
                    {
                        this._state = CborReaderState.Map;
                        this._size = 8;
                    }
                    else
                    {
                        throw new CborException("invalid map constructor");
                    }

                    break;
                case 6: // tag
                    if (minorType < 24)
                    {
                        this._listener.OnTag((uint)minorType);
                    }
                    else if (minorType == 24)
                    {
                        this._state = CborReaderState.Tag;
                        this._size = 1;
                    }
                    else if (minorType == 25)
                    {
                        this._state = CborReaderState.Tag;
                        this._size = 2;
                    }
                    else if (minorType == 26)
                    {
                        this._state = CborReaderState.Tag;
                        this._size = 4;
                    }
                    else if (minorType == 27)
                    {
                        this._state = CborReaderState.Tag;
                        this._size = 8;
                    }
                    else
                    {
                        throw new CborException("invalid map constructor");
                    }

                    break;
                case 7: // special
                    if (minorType < 24)
                    {
                        this._listener.OnSpecial((uint)minorType);
                    }
                    else if (minorType == 24)
                    {
                        this._state = CborReaderState.Special;
                        this._size = 1;
                    }
                    else if (minorType == 25)
                    {
                        this._state = CborReaderState.Special;
                        this._size = 2;
                    }
                    else if (minorType == 26)
                    {
                        this._state = CborReaderState.Special;
                        this._size = 4;
                    }
                    else if (minorType == 27)
                    {
                        this._state = CborReaderState.Special;
                        this._size = 8;
                    }
                    else
                    {
                        throw new CborException("invalid map constructor");
                    }

                    break;
            }

            return true;
        }
Beispiel #26
0
        /// <summary>
        /// The try parse float.
        /// </summary>
        /// <returns>
        /// The <see cref="bool"/>.
        /// </returns>
        /// <exception cref="CborException">
        /// </exception>
        private bool TryParseFloat()
        {
            if (!this._input.HasBytes(this._size))
            {
                return false;
            }

            byte[] data = this._input.GetBytes(8);

            // logger.info("parse float: {0}", BitConverter.ToString(data).Replace("-","").ToLower());
            switch (this._size)
            {
                case 8: // double
                    this._listener.OnDouble(BitConverter.ToDouble(data, 0));
                    break;
                default:
                    throw new CborException("invalid float size");
            }

            this._state = CborReaderState.Type;

            return true;
        }
Beispiel #27
0
        public static void Peek_SingleByteBuffer_ShouldReturnExpectedState(byte majorType, CborReaderState expectedResult)
        {
            ReadOnlyMemory <byte> buffer = new byte[] { (byte)(majorType << 5) };
            var reader = new CborReader(buffer);

            Assert.Equal(expectedResult, reader.PeekState());
        }
Beispiel #28
0
        /// <summary>
        /// The try parse bytes data.
        /// </summary>
        /// <returns>
        /// The <see cref="bool"/>.
        /// </returns>
        private bool TryParseBytesData()
        {
            if (!this._input.HasBytes(this._size))
            {
                return false;
            }

            this._listener.OnBytes(this._input.GetBytes(this._size));
            this._state = CborReaderState.Type;
            return true;
        }