Make3.Renderer/Make3.RenderServer/Grpc/GrpcConverters.cs
2025-06-28 03:00:25 +03:00

117 lines
3.6 KiB
C#

using Google.Protobuf;
using LayerClients;
namespace Make3.RenderServer.Grpc;
public static class GrpcConverters
{
private const int StreamChunkSize = 4096; // Размер чанка (4 КБ)
public static double[,] DecodeMatrix(List<LayerClients.MatrixRow> grpcMatrix)
{
if (grpcMatrix == null || grpcMatrix.Count == 0)
{
throw new ArgumentException("The input grpcMatrix is null or empty.");
}
// Определяем размерность массива
int rows = grpcMatrix.Count;
int cols = grpcMatrix[0].Values.Count;
// Создаём двумерный массив
double[,] matrix = new double[rows, cols];
// Заполняем массив данными из grpcMatrix
for (int i = 0; i < rows; i++)
{
if (grpcMatrix[i].Values.Count != cols)
{
throw new InvalidOperationException("All rows in grpcMatrix must have the same number of columns.");
}
for (int j = 0; j < cols; j++)
{
matrix[i, j] = grpcMatrix[i].Values[j];
}
}
return matrix;
}
public static Stream AppendToStream(Stream stream, IEnumerable<MatrixRow> matrix)
{
using var writer = new BinaryWriter(stream, System.Text.Encoding.Default, true);
foreach (var row in matrix)
{
foreach (var value in row.Values)
{
writer.Write(value);
}
}
stream.Position = 0;
return stream;
}
public static double[,] ConvertStreamToMatrix(Stream stream, uint rows, uint columns)
{
var matrix = new double[rows, columns];
using var reader = new BinaryReader(stream);
for (uint y = 0; y < rows; y++)
{
for (uint x = 0; x < columns; x++)
{
if (reader.BaseStream.Position < reader.BaseStream.Length)
{
matrix[y, x] = reader.ReadDouble(); // Читаем `double` из потока
}
else
{
throw new EndOfStreamException("Not enough data to read from stream.");
// matrix[y, x] = 0; // Заполняем нулями, если данных недостаточно
}
}
}
return matrix;
}
public static async Task SendStream(Stream stream, Func<ByteString, Task> sendChunk)
{
var buffer = new byte[StreamChunkSize];
int bytesRead;
while ((bytesRead = stream.Read(buffer, 0, buffer.Length)) > 0)
{
await sendChunk(ByteString.CopyFrom(buffer, 0, bytesRead));
}
}
public static void ReceiveStream(string outputPath, Func<ByteString?> getChunk)
{
using var fileStream = new FileStream(outputPath, FileMode.Create, FileAccess.Write);
ByteString chunk;
while ((chunk = getChunk()) != null)
{
fileStream.Write(chunk.ToByteArray());
}
}
public static DecimalValue ConvertDecimalValue(decimal value)
{
var nanoFactor = 1_000_000_000;
var units = decimal.ToInt64(value);
var nanos = decimal.ToInt32((value - units) * nanoFactor);
return new DecimalValue
{
Units = units,
Nanos = nanos,
};
}
public static decimal ConvertDecimalValue(DecimalValue value)
{
var nanoFactor = 1_000_000_000;
return value.Units + value.Nanos / nanoFactor;
}
}