Skip to content

Commit bee8654

Browse files
committed
add some comments
1 parent 6964727 commit bee8654

File tree

1 file changed

+48
-13
lines changed

1 file changed

+48
-13
lines changed

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

Lines changed: 48 additions & 13 deletions
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

@@ -51,20 +52,52 @@ public int TransformBlock(
5152
{
5253
int bytesToProcess = Math.Min(InputBlockSize, inputCount - inputProcessed);
5354

55+
/*
56+
Input Buffer ("hi mom"):
57+
+-----+-----+-----+-----+-----+-----+
58+
| 'h' | 'i' | ' ' | 'm' | 'o' | 'm' |
59+
+-----+-----+-----+-----+-----+-----+
60+
|104 |105 | 32 |109 |111 |109 |
61+
+-----+-----+-----+-----+-----+-----+
62+
63+
Base64 Encoding Process:
64+
- 'hi ' -> 'aGkg'
65+
- 'mom' -> 'bW9t'
66+
67+
Base64 Encoded Output:
68+
| |base64Written | | base64Written |
69+
+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+
70+
| \0 | \0 | \0 | \0 |'a' |'G' |'k' |'g' | \0 | \0 | \0 | \0 |'b' |'W' |'9' |'t' |
71+
+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+
72+
| 0 | 0 | 0 | 0 | 97 | 71 |107 |103 | 0 | 0 | 0 | 0 | 98 | 87 | 57 |116 |
73+
+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+
74+
75+
Expanded Output Buffer (UTF-16 Encoding):
76+
| outputChars | outputChars |
77+
+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+
78+
| \0 |'a' | \0 |'G' | \0 |'k' | \0 |'g' | \0 |'b' | \0 |'W' | \0 |'9' | \0 |'t' |
79+
+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+
80+
| 0 | 97 | 0 | 71 | 0 |107 | 0 |103 | 0 | 98 | 0 | 87 | 0 | 57 | 0 |116 |
81+
+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+
82+
83+
*/
84+
5485
// Calculate positions in the output buffer
55-
int base64OutputStart = outputOffset + totalBytesWritten + OutputBlockSize / 2;
56-
int base64OutputLength = _base64Transform.OutputBlockSize;
86+
int outputStart = outputOffset + totalBytesWritten;
87+
int base64OutputStart = outputStart + OutputBlockSize / 2;
5788

58-
// Apply Base64 transformation directly to the second half of the output buffer
89+
// write Base64 transformation directly to the second half of the output buffer
5990
int base64BytesWritten = _base64Transform.TransformBlock(
6091
inputBuffer, inputOffset + inputProcessed, bytesToProcess,
6192
outputBuffer, base64OutputStart);
6293

63-
var outputSpan = MemoryMarshal.Cast<byte, char>(outputBuffer.AsSpan(outputOffset + totalBytesWritten, OutputBlockSize));
94+
var base64Written = outputBuffer.AsSpan(base64OutputStart, base64BytesWritten);
95+
var outputChars = outputBuffer.AsSpan(outputStart, OutputBlockSize);
6496
for (int i = 0; i < base64BytesWritten; i++)
6597
{
66-
char base64Char = (char)outputBuffer[base64OutputStart + i];
67-
outputSpan[i] = base64Char;
98+
// Expand each ascii byte to a char write it in the same logical position
99+
// as a char in outputChars eventually filling the output buffer
100+
BitConverter.TryWriteBytes(outputChars.Slice(i * 2), (char)base64Written[i]);
68101
}
69102

70103
inputProcessed += bytesToProcess;
@@ -81,12 +114,10 @@ public byte[] TransformFinalBlock(byte[] inputBuffer, int inputOffset, int input
81114

82115
// Expand each Base64 byte to two bytes in the output buffer
83116
byte[] outputBuffer = new byte[base64Buffer.Length * 2];
84-
Span<char> outputSpan = MemoryMarshal.Cast<byte, char>(outputBuffer.AsSpan());
85117
for (int i = 0; i < base64Buffer.Length; i++)
86118
{
87-
// Convert each byte to a char
88-
char base64Char = (char)base64Buffer[i];
89-
outputSpan[i] = base64Char;
119+
// Convert each ascii byte to a char
120+
BitConverter.TryWriteBytes(outputBuffer.AsSpan(i * 2), (char)base64Buffer[i]);
90121
}
91122

92123
return outputBuffer;
@@ -108,8 +139,12 @@ public static void WriteOnSingleLine(XElement assembliesElement)
108139
xmlWriter.Flush();
109140
cryptoStream.FlushFinalBlock();
110141

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

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

0 commit comments

Comments
 (0)