using Google.Protobuf; using LayerClients; namespace Make3.RenderServer.Grpc; public static class GrpcConverters { private const int StreamChunkSize = 4096; // Размер чанка (4 КБ) public static double[,] DecodeMatrix(List 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 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 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 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; } }