private bool ReadFrame()
        {
            FlushPeek();

            var magic = TryPeek32();

            if (!magic.HasValue)
            {
                return(false);
            }

            if (magic != 0x184D2204)
            {
                throw MagicNumberExpected();
            }

            FlushPeek();

            var FLG_BD = Peek16();

            var FLG = FLG_BD & 0xFF;
            var BD  = (FLG_BD >> 8) & 0xFF;

            var version = (FLG >> 6) & 0x11;

            if (version != 1)
            {
                throw UnknownFrameVersion(version);
            }

            var blockChaining   = ((FLG >> 5) & 0x01) == 0;
            var blockChecksum   = ((FLG >> 4) & 0x01) != 0;
            var hasContentSize  = ((FLG >> 3) & 0x01) != 0;
            var contentChecksum = ((FLG >> 2) & 0x01) != 0;
            var hasDictionary   = (FLG & 0x01) != 0;
            var blockSizeCode   = (BD >> 4) & 0x07;

            var contentLength = hasContentSize ? (long?)Peek64() : null;
            var dictionaryId  = hasDictionary ? (uint?)Peek32() : null;

            var actualHC   = (byte)(XXH32.DigestOf(_buffer16, 0, _index16) >> 8);
            var expectedHC = Peek8();

            if (actualHC != expectedHC)
            {
                throw InvalidHeaderChecksum();
            }

            var blockSize = MaxBlockSize(blockSizeCode);

            if (hasDictionary)
            {
                throw NotImplemented(
                          "Predefined dictionaries feature is not implemented");               // Write32(dictionaryId);
            }
            // ReSharper disable once ExpressionIsAlwaysNull
            _frameInfo = new LZ4Descriptor(
                contentLength, contentChecksum, blockChaining, blockChecksum, dictionaryId,
                blockSize);
            _decoder = _decoderFactory(_frameInfo);
            _buffer  = new byte[blockSize];

            return(true);
        }