Skip to content

Instantly share code, notes, and snippets.

@dcuccia
Created November 2, 2023 01:06
Show Gist options
  • Save dcuccia/552c52716211cfecaf48dd84fe254f8b to your computer and use it in GitHub Desktop.
Save dcuccia/552c52716211cfecaf48dd84fe254f8b to your computer and use it in GitHub Desktop.
Version of BinaryArraySerializerFactory that avoids all the different nested iterator loops
using System;
using System.IO;
using System.Numerics;
using System.Runtime.InteropServices;
namespace Vts.IO;
public static class BinaryArraySerializerFactory
{
/// <summary>
/// Factory method that writes an array item to a binary file
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="item"></param>
/// <param name="name"></param>
/// <param name="fileTag"></param>
/// <returns></returns>
public static BinaryArraySerializer GetSerializer<T>(T item, string name, string fileTag)
{
return new BinaryArraySerializer
{
Name = name,
FileTag = fileTag,
WriteData = GetWriteDataArrayAction(item),
ReadData = GetReadDataArrayAction(item)
};
}
internal static Action<BinaryWriter> GetWriteDataArrayAction<T>(T dataArray)
{
return dataArray switch
{
double[] d1 => bw => WriteDataArray(bw, ref d1[0], d1.Length),
double[,] d2 => bw => WriteDataArray(bw, ref d2[0,0], d2.Length),
double[,,] d3 => bw => WriteDataArray(bw, ref d3[0,0,0], d3.Length),
double[,,,] d4 => bw => WriteDataArray(bw, ref d4[0,0,0,0], d4.Length),
double[,,,,] d5 => bw => WriteDataArray(bw, ref d5[0,0,0,0,0], d5.Length),
double[,,,,,] d6 => bw => WriteDataArray(bw, ref d6[0,0,0,0,0,0], d6.Length),
Complex[] c1 => bw => WriteDataArray(bw, ref c1[0], c1.Length),
Complex[,] c2 => bw => WriteDataArray(bw, ref c2[0,0], c2.Length),
Complex[,,] c3 => bw => WriteDataArray(bw, ref c3[0,0,0], c3.Length),
Complex[,,,] c4 => bw => WriteDataArray(bw, ref c4[0,0,0,0], c4.Length),
Complex[,,,,] c5 => bw => WriteDataArray(bw, ref c5[0,0,0,0,0], c5.Length),
Complex[,,,,,] c6 => bw => WriteDataArray(bw, ref c6[0, 0, 0, 0, 0, 0], c6.Length),
_ => throw new NotImplementedException()
};
}
internal static Action<BinaryReader> GetReadDataArrayAction<T>(T dataArray)
{
return dataArray switch
{
double[] d1 => br => ReadIntoDataArray(br, ref d1[0], d1.Length),
double[,] d2 => br => ReadIntoDataArray(br, ref d2[0,0], d2.Length),
double[,,] d3 => br => ReadIntoDataArray(br, ref d3[0,0,0], d3.Length),
double[,,,] d4 => br => ReadIntoDataArray(br, ref d4[0,0,0,0], d4.Length),
double[,,,,] d5 => br => ReadIntoDataArray(br, ref d5[0,0,0,0,0], d5.Length),
double[,,,,,] d6 => br => ReadIntoDataArray(br, ref d6[0,0,0,0,0,0], d6.Length),
Complex[] c1 => br => ReadIntoDataArray(br, ref c1[0], c1.Length),
Complex[,] c2 => br => ReadIntoDataArray(br, ref c2[0,0], c2.Length),
Complex[,,] c3 => br => ReadIntoDataArray(br, ref c3[0,0,0], c3.Length),
Complex[,,,] c4 => br => ReadIntoDataArray(br, ref c4[0,0,0,0], c4.Length),
Complex[,,,,] c5 => br => ReadIntoDataArray(br, ref c5[0,0,0,0,0], c5.Length),
Complex[,,,,,] c6 => br => ReadIntoDataArray(br, ref c6[0, 0, 0, 0, 0, 0], c6.Length),
_ => throw new NotImplementedException()
};
}
internal static void WriteDataArray(BinaryWriter binaryWriter, ref double dataArrayRef, int length)
{
var span = MemoryMarshal.CreateReadOnlySpan(ref dataArrayRef, length);
for (int i = 0; i < length; i++)
{
binaryWriter.Write(span[i]);
}
}
internal static void WriteDataArray(BinaryWriter binaryWriter, ref Complex dataArrayRef, int length)
{
var span = MemoryMarshal.CreateReadOnlySpan(ref dataArrayRef, length);
for (int i = 0; i < length; i++)
{
binaryWriter.Write(span[i].Real);
binaryWriter.Write(span[i].Imaginary);
}
}
internal static void ReadIntoDataArray(BinaryReader binaryReader, ref double dataArrayRef, int length)
{
var span = MemoryMarshal.CreateSpan(ref dataArrayRef, length);
for (int i = 0; i < length; i++)
{
span[i] = binaryReader.ReadDouble();
}
}
internal static void ReadIntoDataArray(BinaryReader binaryReader, ref Complex dataArrayRef, int length)
{
var span = MemoryMarshal.CreateSpan(ref dataArrayRef, length);
for (int i = 0; i < length; i++)
{
var real = binaryReader.ReadDouble();
var imaginary = binaryReader.ReadDouble();
span[i] = new Complex(real, imaginary);
}
}
}
@lmalenfant
Copy link

This code makes me happy. I can't wait to try it out :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment