From cee712105850ac3385cd0091a923438167433f9f Mon Sep 17 00:00:00 2001
From: TSR Berry <20988865+TSRBerry@users.noreply.github.com>
Date: Sat, 8 Apr 2023 01:22:00 +0200
Subject: Move solution and projects to src
---
.../Shader/DiskCache/BinarySerializer.cs | 216 +++++++++++++++++++++
1 file changed, 216 insertions(+)
create mode 100644 src/Ryujinx.Graphics.Gpu/Shader/DiskCache/BinarySerializer.cs
(limited to 'src/Ryujinx.Graphics.Gpu/Shader/DiskCache/BinarySerializer.cs')
diff --git a/src/Ryujinx.Graphics.Gpu/Shader/DiskCache/BinarySerializer.cs b/src/Ryujinx.Graphics.Gpu/Shader/DiskCache/BinarySerializer.cs
new file mode 100644
index 00000000..50e37033
--- /dev/null
+++ b/src/Ryujinx.Graphics.Gpu/Shader/DiskCache/BinarySerializer.cs
@@ -0,0 +1,216 @@
+using System;
+using System.IO;
+using System.IO.Compression;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+namespace Ryujinx.Graphics.Gpu.Shader.DiskCache
+{
+ ///
+ /// Binary data serializer.
+ ///
+ struct BinarySerializer
+ {
+ private readonly Stream _stream;
+ private Stream _activeStream;
+
+ ///
+ /// Creates a new binary serializer.
+ ///
+ /// Stream to read from or write into
+ public BinarySerializer(Stream stream)
+ {
+ _stream = stream;
+ _activeStream = stream;
+ }
+
+ ///
+ /// Reads data from the stream.
+ ///
+ /// Type of the data
+ /// Data read
+ public void Read(ref T data) where T : unmanaged
+ {
+ Span buffer = MemoryMarshal.Cast(MemoryMarshal.CreateSpan(ref data, 1));
+ for (int offset = 0; offset < buffer.Length;)
+ {
+ offset += _activeStream.Read(buffer.Slice(offset));
+ }
+ }
+
+ ///
+ /// Tries to read data from the stream.
+ ///
+ /// Type of the data
+ /// Data read
+ /// True if the read was successful, false otherwise
+ public bool TryRead(ref T data) where T : unmanaged
+ {
+ // Length is unknown on compressed streams.
+ if (_activeStream == _stream)
+ {
+ int size = Unsafe.SizeOf();
+ if (_activeStream.Length - _activeStream.Position < size)
+ {
+ return false;
+ }
+ }
+
+ Read(ref data);
+ return true;
+ }
+
+ ///
+ /// Reads data prefixed with a magic and size from the stream.
+ ///
+ /// Type of the data
+ /// Data read
+ /// Expected magic value, for validation
+ public void ReadWithMagicAndSize(ref T data, uint magic) where T : unmanaged
+ {
+ uint actualMagic = 0;
+ int size = 0;
+ Read(ref actualMagic);
+ Read(ref size);
+
+ if (actualMagic != magic)
+ {
+ throw new DiskCacheLoadException(DiskCacheLoadResult.FileCorruptedInvalidMagic);
+ }
+
+ // Structs are expected to expand but not shrink between versions.
+ if (size > Unsafe.SizeOf())
+ {
+ throw new DiskCacheLoadException(DiskCacheLoadResult.FileCorruptedInvalidLength);
+ }
+
+ Span buffer = MemoryMarshal.Cast(MemoryMarshal.CreateSpan(ref data, 1)).Slice(0, size);
+ for (int offset = 0; offset < buffer.Length;)
+ {
+ offset += _activeStream.Read(buffer.Slice(offset));
+ }
+ }
+
+ ///
+ /// Writes data into the stream.
+ ///
+ /// Type of the data
+ /// Data to be written
+ public void Write(ref T data) where T : unmanaged
+ {
+ Span buffer = MemoryMarshal.Cast(MemoryMarshal.CreateSpan(ref data, 1));
+ _activeStream.Write(buffer);
+ }
+
+ ///
+ /// Writes data prefixed with a magic and size into the stream.
+ ///
+ /// Type of the data
+ /// Data to write
+ /// Magic value to write
+ public void WriteWithMagicAndSize(ref T data, uint magic) where T : unmanaged
+ {
+ int size = Unsafe.SizeOf();
+ Write(ref magic);
+ Write(ref size);
+ Span buffer = MemoryMarshal.Cast(MemoryMarshal.CreateSpan(ref data, 1));
+ _activeStream.Write(buffer);
+ }
+
+ ///
+ /// Indicates that all data that will be read from the stream has been compressed.
+ ///
+ public void BeginCompression()
+ {
+ CompressionAlgorithm algorithm = CompressionAlgorithm.None;
+ Read(ref algorithm);
+
+ if (algorithm == CompressionAlgorithm.Deflate)
+ {
+ _activeStream = new DeflateStream(_stream, CompressionMode.Decompress, true);
+ }
+ }
+
+ ///
+ /// Indicates that all data that will be written into the stream should be compressed.
+ ///
+ /// Compression algorithm that should be used
+ public void BeginCompression(CompressionAlgorithm algorithm)
+ {
+ Write(ref algorithm);
+
+ if (algorithm == CompressionAlgorithm.Deflate)
+ {
+ _activeStream = new DeflateStream(_stream, CompressionLevel.SmallestSize, true);
+ }
+ }
+
+ ///
+ /// Indicates the end of a compressed chunck.
+ ///
+ ///
+ /// Any data written after this will not be compressed unless is called again.
+ /// Any data read after this will be assumed to be uncompressed unless is called again.
+ ///
+ public void EndCompression()
+ {
+ if (_activeStream != _stream)
+ {
+ _activeStream.Dispose();
+ _activeStream = _stream;
+ }
+ }
+
+ ///
+ /// Reads compressed data from the stream.
+ ///
+ ///
+ /// must have the exact length of the uncompressed data,
+ /// otherwise decompression will fail.
+ ///
+ /// Stream to read from
+ /// Buffer to write the uncompressed data into
+ public static void ReadCompressed(Stream stream, Span data)
+ {
+ CompressionAlgorithm algorithm = (CompressionAlgorithm)stream.ReadByte();
+
+ switch (algorithm)
+ {
+ case CompressionAlgorithm.None:
+ stream.Read(data);
+ break;
+ case CompressionAlgorithm.Deflate:
+ stream = new DeflateStream(stream, CompressionMode.Decompress, true);
+ for (int offset = 0; offset < data.Length;)
+ {
+ offset += stream.Read(data.Slice(offset));
+ }
+ stream.Dispose();
+ break;
+ }
+ }
+
+ ///
+ /// Compresses and writes the compressed data into the stream.
+ ///
+ /// Stream to write into
+ /// Data to compress
+ /// Compression algorithm to be used
+ public static void WriteCompressed(Stream stream, ReadOnlySpan data, CompressionAlgorithm algorithm)
+ {
+ stream.WriteByte((byte)algorithm);
+
+ switch (algorithm)
+ {
+ case CompressionAlgorithm.None:
+ stream.Write(data);
+ break;
+ case CompressionAlgorithm.Deflate:
+ stream = new DeflateStream(stream, CompressionLevel.SmallestSize, true);
+ stream.Write(data);
+ stream.Dispose();
+ break;
+ }
+ }
+ }
+}
\ No newline at end of file
--
cgit v1.2.3