Skip to content

Commit 0f872f4

Browse files
committed
add some comments
1 parent 6964727 commit 0f872f4

File tree

1 file changed

+47
-10
lines changed

1 file changed

+47
-10
lines changed

src/Microsoft.DotNet.XHarness.TestRunners.Xunit/WasmXmlResultWriter.cs

+47-10
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,9 @@ private class ToBase64CharTransform : ICryptoTransform
3030
{
3131
private readonly ToBase64Transform _base64Transform = new ToBase64Transform();
3232

33-
public int InputBlockSize => _base64Transform.InputBlockSize;
34-
public int OutputBlockSize => _base64Transform.OutputBlockSize * 2;
33+
public int InputBlockSize => _base64Transform.InputBlockSize; // 3 bytes of input
34+
public int OutputBlockSize => _base64Transform.OutputBlockSize * 2; // 4 bytes of base64 output * 2 for UTF-16 encoding
35+
3536
public bool CanTransformMultipleBlocks => _base64Transform.CanTransformMultipleBlocks;
3637
public bool CanReuseTransform => _base64Transform.CanReuseTransform;
3738

@@ -47,6 +48,7 @@ public int TransformBlock(
4748
int totalBytesWritten = 0;
4849
int inputProcessed = 0;
4950

51+
Debug.Assert(outputOffset % 2 == 0, $"{nameof(outputOffset)} must be a multiple 2");
5052
while (inputProcessed < inputCount)
5153
{
5254
int bytesToProcess = Math.Min(InputBlockSize, inputCount - inputProcessed);
@@ -55,16 +57,48 @@ public int TransformBlock(
5557
int base64OutputStart = outputOffset + totalBytesWritten + OutputBlockSize / 2;
5658
int base64OutputLength = _base64Transform.OutputBlockSize;
5759

58-
// Apply Base64 transformation directly to the second half of the output buffer
60+
// write Base64 transformation directly to the second half of the output buffer
5961
int base64BytesWritten = _base64Transform.TransformBlock(
6062
inputBuffer, inputOffset + inputProcessed, bytesToProcess,
6163
outputBuffer, base64OutputStart);
6264

63-
var outputSpan = MemoryMarshal.Cast<byte, char>(outputBuffer.AsSpan(outputOffset + totalBytesWritten, OutputBlockSize));
65+
/*
66+
Input Buffer ("hi mom"):
67+
+-----+-----+-----+-----+-----+-----+
68+
| 'h' | 'i' | ' ' | 'm' | 'o' | 'm' |
69+
+-----+-----+-----+-----+-----+-----+
70+
|104 |105 | 32 |109 |111 |109 |
71+
+-----+-----+-----+-----+-----+-----+
72+
73+
Base64 Encoding Process:
74+
- 'hi ' -> 'aGkg'
75+
- 'mom' -> 'bW9t'
76+
77+
Base64 Encoded Output:
78+
| |base64Written | | base64Written |
79+
+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+
80+
| \0 | \0 | \0 | \0 |'a' |'G' |'k' |'g' | \0 | \0 | \0 | \0 |'b' |'W' |'9' |'t' |
81+
+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+
82+
| 0 | 0 | 0 | 0 | 97 | 71 |107 |103 | 0 | 0 | 0 | 0 | 98 | 87 | 57 |116 |
83+
+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+
84+
85+
Expanded Output Buffer (UTF-16 Encoding):
86+
| outputChars | outputChars |
87+
+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+
88+
| \0 |'a' | \0 |'G' | \0 |'k' | \0 |'g' | \0 |'b' | \0 |'W' | \0 |'9' | \0 |'t' |
89+
+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+
90+
| 0 | 97 | 0 | 71 | 0 |107 | 0 |103 | 0 | 98 | 0 | 87 | 0 | 57 | 0 |116 |
91+
+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+
92+
93+
*/
94+
95+
var base64Written = outputBuffer.AsSpan(base64OutputStart, base64BytesWritten);
96+
var outputChars = MemoryMarshal.Cast<byte, char>(outputBuffer.AsSpan(outputOffset + totalBytesWritten, OutputBlockSize));
6497
for (int i = 0; i < base64BytesWritten; i++)
6598
{
66-
char base64Char = (char)outputBuffer[base64OutputStart + i];
67-
outputSpan[i] = base64Char;
99+
// Expand each acsii byte to a char write it in the same logical position
100+
// as a char in outputChars eventually filling the output buffer
101+
outputChars[i] = (char)base64Written[i];
68102
}
69103

70104
inputProcessed += bytesToProcess;
@@ -84,9 +118,8 @@ public byte[] TransformFinalBlock(byte[] inputBuffer, int inputOffset, int input
84118
Span<char> outputSpan = MemoryMarshal.Cast<byte, char>(outputBuffer.AsSpan());
85119
for (int i = 0; i < base64Buffer.Length; i++)
86120
{
87-
// Convert each byte to a char
88-
char base64Char = (char)base64Buffer[i];
89-
outputSpan[i] = base64Char;
121+
// Convert each ascii byte to a char
122+
outputSpan[i] = (char)base64Buffer[i]
90123
}
91124

92125
return outputBuffer;
@@ -108,8 +141,12 @@ public static void WriteOnSingleLine(XElement assembliesElement)
108141
xmlWriter.Flush();
109142
cryptoStream.FlushFinalBlock();
110143

144+
// guranteed to succeed with the MemoryStream() constructor
111145
ms.TryGetBuffer(out var bytes);
112-
var charData = MemoryMarshal.Cast<byte,char>(bytes);
146+
// we went to a lot of trouble to put characters in the final buffer
147+
// so that we can avoid a copy here and pass the span directly to the
148+
// string interpolation logic.
149+
Span<char> charData = MemoryMarshal.Cast<byte,char>(bytes);
113150

114151
// Output the result
115152
Console.WriteLine($"STARTRESULTXML {charData.Length} {charData} ENDRESULTXML");

0 commit comments

Comments
 (0)