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)); }