BITKit/Packages/Core/Assets/BITAssets.cs

136 lines
4.5 KiB
C#

using System;
using System.Collections.Generic;
using Unity.SharpZipLib.Zip;
using Newtonsoft.Json;
using System.IO;
using Unity.SharpZipLib.Core;
using System.Linq;
using System.Diagnostics;
using System.Text;
using Unity.SharpZipLib.GZip;
using System.Threading.Tasks;
namespace BITKit.IO
{
record BITHeader
{
public string Name { get; set; }
public DateTime CreateTime;
public DateTime LastModifiedTime;
public List<string> Files = new List<string>();
}
class MemoryBytes : IStaticDataSource
{
byte[] buffer;
public MemoryBytes(byte[] buffer)
{
this.buffer = buffer;
}
public Stream GetSource()
{
Stream s = new MemoryStream(buffer);
return s;
}
}
public class BITAssets : List<IAsset>
{
public static void Build(string path, params IAsset[] assets)
{
List<IAsset> assetList = new();
BITHeader header = new BITHeader();
header.Name = path;
header.CreateTime = DateTime.Now;
header.LastModifiedTime = DateTime.Now;
foreach (var asset in assets)
{
header.Files.Add(asset.Name);
}
assetList.Add(new BITAsset()
{
Name = "manifest.json",
Buffer = StringHelper.GetBytes(JsonConvert.SerializeObject(header, Formatting.Indented)),
});
assetList.AddRange(assets);
using (ZipFile zipFile = ZipFile.Create(path))
{
zipFile.BeginUpdate();
foreach (var x in assetList)
{
using (var ms = new MemoryStream(x.Buffer))
{
zipFile.Add(new MemoryBytes(x.Buffer), x.Name);
}
}
zipFile.CommitUpdate();
}
}
public static T Read<T>(string path, string bufferPath, IStorageFile provider = null)
{
var json = ReadText(path, bufferPath, provider);
return Read<T>(json);
}
public static async Task<T> ReadAsync<T>(string path, string bufferPath, IStorageFile provider = null)
{
var json = await ReadTextAsync(path, bufferPath, provider);
return Read<T>(json);
}
public static T Read<T>(string json)
{
return JsonConvert.DeserializeObject<T>(json);
}
public static async Task<IAsset> ReadAseetAsync(string path, string bufferPath, IStorageFile provider = null)
{
provider = provider ?? new FileProvider(path);
return ReadAsset(await provider.OpenReadAsync(), bufferPath);
}
public static IAsset ReadAseet(string path, string bufferPath, IStorageFile provider = null)
{
provider = provider ?? new FileProvider(path);
return ReadAsset(provider.OpenRead(), bufferPath);
}
public static IAsset ReadAsset(Stream stream, string bufferPath)
{
BITAsset asset = new();
using (var zipFile = new ZipFile(stream))
{
foreach (ZipEntry zipEntry in zipFile)
{
if (zipEntry.IsFile && zipEntry.Name == bufferPath)
{
asset.Name = zipEntry.Name;
using (var fs = zipFile.GetInputStream(zipEntry))
{
using (MemoryStream ms = new())
{
fs.CopyTo(ms);
asset.Buffer = ms.GetBuffer();
}
}
return asset;
}
}
}
throw new System.IO.FileNotFoundException();
}
public static string ReadText(string path, string bufferPath, IStorageFile provider = null)
{
var asset = ReadAseet(path, bufferPath, provider);
return StringHelper.GetString(asset.Buffer);
}
public static async Task<string> ReadTextAsync(string path, string bufferPath, IStorageFile provider = null)
{
var asset = await ReadAseetAsync(path, bufferPath, provider);
return StringHelper.GetString(asset.Buffer);
}
public void Build(string path)
{
Build(path, ToArray());
}
}
}