public XnbFile <T> Deserialize <T>(Stream stream)
        {
            if (stream == null)
            {
                throw new ArgumentNullException(nameof(stream));
            }

            var xnbResult = new XnbFile <T>();

            var xnbStreamReader = new XnbStreamReader(stream);

            // check if file starts with XNB
            ValidatePrefix(xnbStreamReader);

            // read the XNB target OS
            xnbResult.XnbTargetOs = ReadTargetOs(xnbStreamReader);

            // read the XNB format version
            xnbResult.FormatVersion = ReadFormatVersion(xnbStreamReader);

            // read the XNB flag
            var flags = xnbResult.Flags = ReadFlags(xnbStreamReader);

            // read the file size
            var size = xnbResult.Size = (int)xnbStreamReader.ReadUInt32();

            // check if encoded. If so, decode stream
            xnbStreamReader = DecodeXnbStreamReader(xnbStreamReader, flags, size);

            var xnbReaderManager = new XnbReaderManager();

            xnbReaderManager.ReadReaders(xnbStreamReader);

            // ensure there are no shared resources
            var sharedResourcesCount = xnbStreamReader.Read7BitEncodedInt();

            if (sharedResourcesCount != 0)
            {
                throw new NotSupportedException("Shared resources are not supported");
            }

            int readerIndex = xnbStreamReader.Read7BitEncodedInt();
            var reader      = xnbReaderManager.XnbReaderFromIndex(readerIndex);

            if (reader == null)
            {
                xnbResult.Content = default(T);
            }
            else if (reader.Read(xnbReaderManager, xnbStreamReader) is T content)
            {
                xnbResult.Content = content;
            }
            else
            {
                throw new XnbException("Invalid type");
            }

            return(xnbResult);
        }
        private XnbStreamReader DecodeXnbStreamReader(XnbStreamReader endcodedXnbStreamReader, XnbFlags flags, int size)
        {
            // check if file size is equal to stream size
            if (endcodedXnbStreamReader.BaseStream.Length != size)
            {
                throw new XnbException("XNB file has been truncated!");
            }

            // check if stream is compressed
            if (!flags.HasFlag(XnbFlags.ContentCompressedLzx))
            {
                return(endcodedXnbStreamReader);
            }

            var decompressedSize   = (int)endcodedXnbStreamReader.ReadUInt32();
            var compressedSize     = size - XnbCompressedPrologueSize;
            var decompressedStream = new LzxDecoderStream(endcodedXnbStreamReader.BaseStream, decompressedSize, compressedSize);

            return(new XnbStreamReader(decompressedStream));
        }