Răsfoiți Sursa

Lib enhancements

Brian Fiete 6 luni în urmă
părinte
comite
0efdecb719
2 a modificat fișierele cu 169 adăugiri și 3 ștergeri
  1. 2 2
      BeefLibs/FMOD/src/FMod.bf
  2. 167 1
      BeefLibs/MiniZ/src/Zip.bf

+ 2 - 2
BeefLibs/FMOD/src/FMod.bf

@@ -2012,14 +2012,14 @@ namespace FMOD
 
             return result;
         }
-        public RESULT createSound            (uint8[] data, MODE mode, ref CREATESOUNDEXINFO exinfo, out Sound sound)
+        public RESULT createSound            (Span<uint8> data, MODE mode, ref CREATESOUNDEXINFO exinfo, out Sound sound)
         {
             sound = null;
 
             exinfo.cbsize = (int32)sizeof(CREATESOUNDEXINFO);
 
             int soundraw;
-            RESULT result = FMOD_System_CreateSound(rawPtr, (char8*)&data[0], mode, ref exinfo, out soundraw);
+            RESULT result = FMOD_System_CreateSound(rawPtr, (.)data.Ptr, mode, ref exinfo, out soundraw);
             sound = new Sound(soundraw);
 
             return result;

+ 167 - 1
BeefLibs/MiniZ/src/Zip.bf

@@ -34,21 +34,91 @@ Implements RFC 1950: http://www.ietf.org/rfc/rfc1950.txt and RFC 1951: http://ww
 using System;
 using System.IO;
 using System.Diagnostics;
+using System.Collections;
 
 #define TINFL_USE_64BIT_BITBUF
 #define MINIZ_HAS_64BIT_REGISTERS
 #define MINIZ_LITTLE_ENDIAN
 #define MINIZ_USE_UNALIGNED_LOADS_AND_STORES
 
+#if BF_PLATFORM_WINDOWS
+#define ALLOW_FILE_MAPPING
+#endif
+
 namespace MiniZ
 {
 	class ZipFile
 	{
+		class RangeStream : Stream
+		{
+			public bool mOwnsStream;
+			public Stream mStream ~ { if (mOwnsStream) delete _; };
+			public Range mRange;
+
+			public override bool CanRead => mStream.CanRead;
+			public override bool CanWrite => mStream.CanWrite;
+			public override int64 Length => mRange.Length;
+
+			public override int64 Position
+			{
+				get
+				{
+					return mStream.Position - mRange.Start;
+				}
+
+				set
+				{
+					mStream.Position = value + mRange.Start;
+				}
+			}
+			
+			public override Result<void> Seek(int64 pos, SeekKind seekKind = .Absolute)
+			{
+				//return mStream.Seek(pos, seekKind);
+
+				switch (seekKind)
+				{
+				case .Absolute:
+					return mStream.Seek(pos + mRange.Start, .Absolute);
+				case .Relative:
+					return mStream.Seek(pos, .Relative);
+				case .FromEnd:
+					return mStream.Seek(mRange.End - pos);
+				}
+			}
+
+			public override Result<int> TryRead(Span<uint8> data)
+			{
+				return mStream.TryRead(data);
+			}
+
+			public override Result<int, FileError> TryRead(Span<uint8> data, int timeoutMS)
+			{
+				return mStream.TryRead(data, timeoutMS);
+			}
+
+			public override Result<int> TryWrite(Span<uint8> data)
+			{
+				return mStream.TryWrite(data);
+			}
+
+			public override Result<void> Close()
+			{
+				return mStream.Close();
+			}
+
+			public override Result<void> Flush()
+			{
+				return mStream.Flush();
+			}
+		}
+
 		public class Entry
 		{
 			ZipFile mZipFile;
 			MiniZ.ZipArchiveFileStat mFileStat;
 			int32 mFileIdx;
+			Span<uint8> mAllocatedData ~ delete mAllocatedData.Ptr;
 
 			public bool IsDirectory
 			{
@@ -65,6 +135,17 @@ namespace MiniZ
 				return .Ok;
 			}
 
+			public Result<Span<uint8>> ExtractToMemory()
+			{
+				if (mAllocatedData.IsEmpty)
+				{
+					mAllocatedData = .(new uint8[mFileStat.mUncompSize]*, mFileStat.mUncompSize);
+					if (!MiniZ.ZipReaderExtractToMem(&mZipFile.[Friend]mFile, mFileIdx, mAllocatedData.Ptr, mAllocatedData.Length, .None))
+						return .Err;
+				}
+				return .Ok(mAllocatedData);
+			}
+
 			int GetStrLen(char8* ptr, int max)
 			{
 				int i = 0;
@@ -97,10 +178,27 @@ namespace MiniZ
 				outComment.Append(&mFileStat.mComment, GetStrLen(&mFileStat.mComment, mFileStat.mComment.Count));
 				return .Ok;
 			}
+
+			public DateTime GetDateTime()
+			{
+				int64 time = (int64)mFileStat.mTime * 10000000L + 116444736000000000L;
+				return DateTime(time);
+			}
+
+			public Platform.BfpTimeStamp GetTimestamp()
+			{
+				return (.)(mFileStat.mTime * 10000000L + 116444736000000000L);
+			}
 		}
 
 		MiniZ.ZipArchive mFile;
 		bool mInitialized;
+#if ALLOW_FILE_MAPPING
+		Windows.FileHandle mShareFileHandle ~ _.Close();
+		Windows.Handle mShareFileMapping ~ _.Close();
+		Span<uint8> mMappedData;
+#endif
+		Stream mOwnedStream ~ delete _;
 
 		public ~this()
 		{
@@ -117,6 +215,74 @@ namespace MiniZ
 			return .Ok;
 		}
 
+		public Result<void> Open(StringView fileName, Range range)
+		{
+			Debug.Assert(!mInitialized);
+
+			FileStream fileStream = new FileStream();
+			if (fileStream.Open(fileName, .Read, .Read) case .Err)
+			{
+				delete fileStream;
+				return .Err;
+			}
+
+			RangeStream rangeStream = new RangeStream() { mStream = fileStream, mOwnsStream = true, mRange = range };
+			mOwnedStream = rangeStream;
+			if (!MiniZ.ZipReaderInitStream(&mFile, rangeStream, .None))
+				return .Err;
+			mInitialized = true;
+			return .Ok;
+		}
+
+		public Result<void> Open(Span<uint8> data)
+		{
+			Debug.Assert(!mInitialized);
+			if (!MiniZ.ZipReaderInitMem(&mFile, data.Ptr, data.Length, .None))
+				return .Err;
+			mInitialized = true;
+			return .Ok;
+		}
+
+		public Result<void> OpenMapped(StringView fileName)
+		{
+#if ALLOW_FILE_MAPPING
+			mShareFileHandle = Windows.CreateFileA(fileName.ToScopeCStr!(), Windows.GENERIC_READ, .Read, null, .Open, 0, default);
+			uint32 sizeHigh = 0;
+			uint32 sizeLow = (.)Windows.GetFileSize(mShareFileHandle, (.)&sizeHigh);
+			mShareFileMapping = Windows.CreateFileMappingA(mShareFileHandle, null, Windows.PAGE_READONLY, sizeHigh, sizeLow, null);
+			mMappedData = .((.)Windows.MapViewOfFile(mShareFileMapping, Windows.FILE_MAP_READ, 0, 0, sizeLow), sizeLow);
+
+			Debug.Assert(!mInitialized);
+			if (!MiniZ.ZipReaderInitMem(&mFile, mMappedData.Ptr, mMappedData.Length, .None))
+				return .Err;
+			mInitialized = true;
+			return .Ok;
+#else
+			return Open(fileName);
+#endif
+		}
+
+		public Result<void> OpenMapped(StringView fileName, Range range)
+		{
+#if ALLOW_FILE_MAPPING
+			mShareFileHandle = Windows.CreateFileA(fileName.ToScopeCStr!(), Windows.GENERIC_READ, .Read, null, .Open, 0, default);
+			uint32 sizeHigh = 0;
+			uint32 sizeLow = (.)range.End;
+
+			mShareFileMapping = Windows.CreateFileMappingA(mShareFileHandle, null, Windows.PAGE_READONLY, sizeHigh, sizeLow, null);
+			uint8* ptr = (.)Windows.MapViewOfFile(mShareFileMapping, Windows.FILE_MAP_READ, 0, 0, sizeLow);
+			mMappedData = .(ptr + range.Start, range.Length);
+
+			Debug.Assert(!mInitialized);
+			if (!MiniZ.ZipReaderInitMem(&mFile, mMappedData.Ptr, mMappedData.Length, .None))
+				return .Err;
+			mInitialized = true;
+			return .Ok;
+#else
+			return Open(fileName, range);
+#endif
+		}
+
 		public Result<void> Init(Stream stream)
 		{
 			Debug.Assert(!mInitialized);
@@ -3115,7 +3281,7 @@ namespace MiniZ
 			return s;
 		}
 
-		static bool zip_reader_init_mem(ZipArchive* pZip, void* pMem, int size, ZipFlags flags)
+		public static bool ZipReaderInitMem(ZipArchive* pZip, void* pMem, int size, ZipFlags flags)
 		{
 			if (!zip_reader_init_internal(pZip, flags))
 				return false;