public unsafe static void WriteNumeric(ref WritableBufferWriter buffer, ulong number) { const byte AsciiDigitStart = (byte)'0'; var span = buffer.Span; var bytesLeftInBlock = span.Length; // Fast path, try copying to the available memory directly var simpleWrite = true; fixed(byte *output = &span.DangerousGetPinnableReference()) { var start = output; if (number < 10 && bytesLeftInBlock >= 1) { *(start) = (byte)(((uint)number) + AsciiDigitStart); buffer.Advance(1); } else if (number < 100 && bytesLeftInBlock >= 2) { var val = (uint)number; var tens = (byte)((val * 205u) >> 11); // div10, valid to 1028 *(start) = (byte)(tens + AsciiDigitStart); *(start + 1) = (byte)(val - (tens * 10) + AsciiDigitStart); buffer.Advance(2); } else if (number < 1000 && bytesLeftInBlock >= 3) { var val = (uint)number; var digit0 = (byte)((val * 41u) >> 12); // div100, valid to 1098 var digits01 = (byte)((val * 205u) >> 11); // div10, valid to 1028 *(start) = (byte)(digit0 + AsciiDigitStart); *(start + 1) = (byte)(digits01 - (digit0 * 10) + AsciiDigitStart); *(start + 2) = (byte)(val - (digits01 * 10) + AsciiDigitStart); buffer.Advance(3); } else { simpleWrite = false; } } if (!simpleWrite) { WriteNumericMultiWrite(ref buffer, number); } }
public unsafe static void WriteAsciiNoValidation(ref WritableBufferWriter buffer, string data) { if (string.IsNullOrEmpty(data)) { return; } var dest = buffer.Span; var destLength = dest.Length; var sourceLength = data.Length; // Fast path, try copying to the available memory directly if (sourceLength <= destLength) { fixed(char *input = data) fixed(byte *output = &dest.DangerousGetPinnableReference()) { EncodeAsciiCharsToBytes(input, output, sourceLength); } buffer.Advance(sourceLength); } else { WriteAsciiMultiWrite(ref buffer, data); } }
private unsafe static void WriteAsciiMultiWrite(ref WritableBufferWriter buffer, string data) { var remaining = data.Length; fixed(char *input = data) { var inputSlice = input; while (remaining > 0) { var writable = Math.Min(remaining, buffer.Span.Length); if (writable == 0) { buffer.Ensure(); continue; } fixed(byte *output = &buffer.Span.DangerousGetPinnableReference()) { EncodeAsciiCharsToBytes(inputSlice, output, writable); } inputSlice += writable; remaining -= writable; buffer.Advance(writable); } } }