internal override int EncodeUtf8(Rune value, Span <byte> destination) { if (value.Value == '<') { if (!SpanUtility.TryWriteBytes(destination, (byte)'&', (byte)'l', (byte)'t', (byte)';')) { goto OutOfSpace; } return(4); } else if (value.Value == '>') { if (!SpanUtility.TryWriteBytes(destination, (byte)'&', (byte)'g', (byte)'t', (byte)';')) { goto OutOfSpace; } return(4); } else if (value.Value == '&') { if (!SpanUtility.TryWriteBytes(destination, (byte)'&', (byte)'a', (byte)'m', (byte)'p', (byte)';')) { goto OutOfSpace; } return(5); } else if (value.Value == '\"') { if (!SpanUtility.TryWriteBytes(destination, (byte)'&', (byte)'q', (byte)'u', (byte)'o', (byte)'t', (byte)';')) { goto OutOfSpace; } return(6); } else { return(TryEncodeScalarAsHex(this, (uint)value.Value, destination)); } OutOfSpace: return(-1);
#pragma warning disable IDE0060 // 'this' taken explicitly to avoid argument shuffling by caller static int TryEncodeScalarAsHex(object @this, uint scalarValue, Span <byte> destination) #pragma warning restore IDE0060 { UnicodeDebug.AssertIsValidScalar(scalarValue); // See comments in the UTF-16 equivalent method later in this file. int idxOfSemicolon = (int)((uint)BitOperations.Log2(scalarValue) / 4) + 4; Debug.Assert(4 <= idxOfSemicolon && idxOfSemicolon <= 9, "Expected '�'..''."); if (!SpanUtility.IsValidIndex(destination, idxOfSemicolon)) { goto OutOfSpaceInner; } destination[idxOfSemicolon] = (byte)';'; if (!SpanUtility.TryWriteBytes(destination, (byte)'&', (byte)'#', (byte)'x', (byte)'0')) { Debug.Fail("We should've had enough room to write 4 bytes."); } destination = destination.Slice(3, idxOfSemicolon - 3); for (int i = destination.Length - 1; SpanUtility.IsValidIndex(destination, i); i--) { char asUpperHex = HexConverter.ToCharUpper((int)scalarValue); destination[i] = (byte)asUpperHex; scalarValue >>= 4; // write a nibble - not a byte - at a time } return(destination.Length + 4); OutOfSpaceInner: return(-1); }
public void TryWriteFiveBytes() { Span <byte> span = stackalloc byte[0]; Assert.False(SpanUtility.TryWriteBytes(span, 10, 20, 30, 40, 50)); span = stackalloc byte[4] { 100, 101, 102, 103 }; Assert.False(SpanUtility.TryWriteBytes(span, 10, 20, 30, 40, 50)); Assert.Equal(new byte[] { 100, 101, 102, 103 }, span.ToArray()); span = stackalloc byte[5] { 100, 101, 102, 103, 104 }; Assert.True(SpanUtility.TryWriteBytes(span, 10, 20, 30, 40, 50)); Assert.Equal(new byte[] { 10, 20, 30, 40, 50 }, span.ToArray()); span = stackalloc byte[6] { 100, 101, 102, 103, 104, 105 }; Assert.True(SpanUtility.TryWriteBytes(span, 10, 20, 30, 40, 50)); Assert.Equal(new byte[] { 10, 20, 30, 40, 50, 105 }, span.ToArray()); }