using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Tools;
namespace napdump
{
[Flags]
public enum WritingOption : uint
{
///
/// Serialize dump IBInfos
///
Dump = 1 << 0,
///
/// Serialize as binary IBInfos
///
Binary = 1 << 1,
///
/// Serialize as text IBInfos
///
Text = 1<<2,
///
/// (flag) GZ compress IBInfos
///
Gz = 1 << 3,
///
/// (flag) File system serialise format
///
Fs = 1 << 4,
///
/// Archive serialise format
///
Ar = 1 << 5,
}
public static class BinWriter
{
public static WritingOption Options { get; private set; }
public static void Initialise(WritingOption opt)
{
Options = opt;
}
public static async Task SaveOptions(Stream to)
{
await to.WriteValueUnmanagedAsync((uint)Options);
}
public static async Task LoadOptions(Stream from, CancellationToken token = default)
{
var opt = (WritingOption)await from.ReadValueUnmanagedAsync(token);
Initialise(opt);
return opt;
}
public static async Task WriteEntry(Stream to, T toWrite, CancellationToken token=default) where T : ISerializable, IBinaryWritable, ITextWritable
{
var Options = BinWriter.Options;
if (Options.HasFlag(WritingOption.Gz))
to = new GZipStream(to, CompressionLevel.Optimal);
try
{
if (Options.HasFlag(WritingOption.Dump))
{
var binf = new BinaryFormatter();
await Task.Yield();
token.ThrowIfCancellationRequested();
binf.Serialize(to, toWrite);
}
else if (Options.HasFlag(WritingOption.Binary))
{
await to.WriteStringAsync(toWrite.GetType().AssemblyQualifiedName, token);
await toWrite.WriteBinaryAsync(to, token);
}
else if (Options.HasFlag(WritingOption.Text))
{
using (var textWriter = new StreamWriter(to))
{
await textWriter.WriteLineAsync($"Type={toWrite.GetType().AssemblyQualifiedName}".AsMemory(), token);
await textWriter.WriteLineAsync(new ReadOnlyMemory(), token);
await toWrite.WriteTextAsync(textWriter, token);
}
}
}
finally
{
if (Options.HasFlag(WritingOption.Gz))
await to.DisposeAsync();
}
}
public static async Task