public static Writer Make(int index, NameWriter name) { return((reader, buffer) => { if (reader.IsDBNull(index)) { return buffer; } Comma.Write(ref buffer); name.Write(ref buffer); buffer[0] = QuotationMark; buffer = buffer.Slice(1); Utf8Formatter.TryFormat(reader.GetDateTime(index), buffer, out var n, new StandardFormat('O')); buffer[n] = QuotationMark; return buffer.Slice(n + 1); }); }
public static void WriteHeader(ref Sequence <byte> buffer, ReadOnlySpan <byte> headerName, long headerValue) { var segment = buffer.GetMemory().Span; int written = 0; headerName.CopyTo(segment); written += headerName.Length; segment.Slice(written)[0] = s_headerSeparator; written += 1; if (!Utf8Formatter.TryFormat(headerValue, segment.Slice(written), out int formatted)) { throw new NotImplementedException("resise buffer"); } written += formatted; s_crlf.CopyTo(segment.Slice(written)); written += s_crlf.Length; }
public static Writer Make(int index, NameWriter name) { return((reader, buffer, pos) => { if (reader.IsDBNull(index)) { return pos; } Comma.Write(buffer, ref pos); name.Write(buffer, ref pos); buffer[pos++] = QuotationMark; var value = reader.GetFieldValue <DateTimeOffset>(index); Utf8Formatter.TryFormat(value, buffer.Slice(pos, 64), out var n, new StandardFormat('O')); pos = pos + n; buffer[pos] = QuotationMark; return pos + 1; }); }
private Result GetSubFileCount(out int fileCount, U8Span dirPath) { fileCount = default; FsPath buffer; unsafe { _ = &buffer; } // workaround for CS0165 int pathLen = StringUtils.Copy(buffer.Str, dirPath); // Make sure we have at least 3 bytes for the sub file name if (pathLen + 3 > PathTools.MaxPathLength) { return(ResultFs.TooLongPath.Log()); } buffer.Str[pathLen] = StringTraits.DirectorySeparator; Span <byte> subFileName = buffer.Str.Slice(pathLen + 1); Result rc; int count; for (count = 0; ; count++) { Utf8Formatter.TryFormat(count, subFileName, out _, new StandardFormat('D', 2)); rc = BaseFileSystem.GetEntryType(out _, buffer); if (rc.IsFailure()) { break; } } if (!ResultFs.PathNotFound.Includes(rc)) { return(rc); } fileCount = count; return(Result.Success); }
// ToDo benchmark - split writes into chunks? public async Task WriteAsync(Memory <byte> bytes) { if (_stream is null) { Write(bytes.Span); return; } int required = BEncodingHelpers.DigitCount(bytes.Length); if (_memory.Length - BytesPending < required) { Grow(required); } bool success = Utf8Formatter.TryFormat(bytes.Length, _memory.Span.Slice(BytesPending), out int written); Debug.Assert(success); Debug.Assert(written == required); BytesPending += written; _arrayBufferWriter.Advance(BytesPending); Debug.Assert(BytesPending == _arrayBufferWriter.WrittenCount); await _stream.WriteAsync(_arrayBufferWriter.WrittenMemory).ConfigureAwait(false); _arrayBufferWriter.Clear(); _memory = _arrayBufferWriter.GetMemory(DefaultGrowthSize); BytesCommitted += BytesPending + bytes.Length; BytesPending = 0; while (bytes.Length > 0) { int chunkSize = Math.Min(bytes.Length, 4096); await _stream.WriteAsync(bytes.Slice(0, chunkSize)).ConfigureAwait(false); bytes = bytes.Slice(chunkSize); } await _stream.FlushAsync().ConfigureAwait(false); }
public static IEnumerable <object[]> GetPropertiesToWrite() { yield return(new object[] { new JwtMember(JsonEncodedText.Encode("object"), new object()), "{\"object\":{}}" }); yield return(new object[] { new JwtMember(JsonEncodedText.Encode("array"), new List <object>()), "{\"array\":[]}" }); yield return(new object[] { new JwtMember(JsonEncodedText.Encode("int64"), 1L), "{\"int64\":1}" }); yield return(new object[] { new JwtMember(JsonEncodedText.Encode("int32"), 1), "{\"int32\":1}" }); yield return(new object[] { new JwtMember(JsonEncodedText.Encode("int16"), (short)1), "{\"int16\":1}" }); yield return(new object[] { new JwtMember(JsonEncodedText.Encode("int8"), (byte)1), "{\"int8\":1}" }); #if NETCOREAPP2_1 || NETFRAMEWORK || NETSTANDARD yield return(new object[] { new JwtMember(JsonEncodedText.Encode("float"), 1.0f), "{\"float\":1}" }); yield return(new object[] { new JwtMember(JsonEncodedText.Encode("float"), 1.1f), "{\"float\":" + ((double)1.1f).ToString("G9", CultureInfo.InvariantCulture) + "}" }); yield return(new object[] { new JwtMember(JsonEncodedText.Encode("double"), 1.0d), "{\"double\":1}" }); yield return(new object[] { new JwtMember(JsonEncodedText.Encode("double"), 1.1d), "{\"double\":" + (1.1d).ToString("G17", CultureInfo.InvariantCulture) + "}" }); #else byte[] destination = new byte[256]; Utf8Formatter.TryFormat(1.0f, destination, out int bytesWritten); yield return(new object[] { new JwtMember(JsonEncodedText.Encode("float"), 1.0f), "{\"float\":" + Encoding.UTF8.GetString(destination.AsSpan().Slice(0, bytesWritten)) + "}" }); Utf8Formatter.TryFormat(1.1f, destination, out bytesWritten); yield return(new object[] { new JwtMember(JsonEncodedText.Encode("float"), 1.1f), "{\"float\":" + Encoding.UTF8.GetString(destination.AsSpan().Slice(0, bytesWritten)) + "}" }); Utf8Formatter.TryFormat(1.0d, destination, out bytesWritten); yield return(new object[] { new JwtMember(JsonEncodedText.Encode("double"), 1.0d), "{\"double\":" + Encoding.UTF8.GetString(destination.AsSpan().Slice(0, bytesWritten)) + "}" }); Utf8Formatter.TryFormat(1.1d, destination, out bytesWritten); yield return(new object[] { new JwtMember(JsonEncodedText.Encode("double"), 1.1d), "{\"double\":" + Encoding.UTF8.GetString(destination.AsSpan().Slice(0, bytesWritten)) + "}" }); #endif yield return(new object[] { new JwtMember(JsonEncodedText.Encode("string"), "hello"), "{\"string\":\"hello\"}" }); //yield return new object[] { new JwtMember("utf8String", new[] { (byte)'h', (byte)'e', (byte)'l', (byte)'l', (byte)'o' }), "{\"utf8String\":\"hello\"}" }; yield return(new object[] { new JwtMember(JsonEncodedText.Encode("boolean"), true), "{\"boolean\":true}" }); }
private void WriteStringValueIndented(DateTime value) { int indent = Indentation; Debug.Assert(indent <= 2 * JsonConstants.MaxWriterDepth); // 2 quotes, and optionally, 1 list separator and 1-2 bytes for new line int maxRequired = indent + JsonConstants.MaximumFormatDateTimeOffsetLength + 3 + s_newLineLength; if (_memory.Length - BytesPending < maxRequired) { Grow(maxRequired); } Span <byte> output = _memory.Span; if (_currentDepth < 0) { output[BytesPending++] = JsonConstants.ListSeparator; } if (_tokenType != JsonTokenType.None) { WriteNewLine(output); } JsonWriterHelper.WriteIndentation(output.Slice(BytesPending), indent); BytesPending += indent; output[BytesPending++] = JsonConstants.Quote; Span <byte> tempSpan = stackalloc byte[JsonConstants.MaximumFormatDateTimeOffsetLength]; bool result = Utf8Formatter.TryFormat(value, tempSpan, out int bytesWritten, s_dateTimeStandardFormat); Debug.Assert(result); JsonWriterHelper.TrimDateTimeOffset(tempSpan.Slice(0, bytesWritten), out bytesWritten); tempSpan.Slice(0, bytesWritten).CopyTo(output.Slice(BytesPending)); BytesPending += bytesWritten; output[BytesPending++] = JsonConstants.Quote; }
public void Write(ulong number) { // Try to format directly if (Utf8Formatter.TryFormat(number, Span, out int bytesWritten)) { Advance(bytesWritten); } else { // Ask for at least 20 bytes Ensure(20); Debug.Assert(Span.Length >= 20, "Buffer is < 20 bytes"); // Try again if (Utf8Formatter.TryFormat(number, Span, out bytesWritten)) { Advance(bytesWritten); } } }
public void Write(ulong value) { // 22 is the worst-case required size ('i', 'e' and 20 digits) const int required = 22; if (_memory.Length - BytesPending < required) { Grow(required); } var span = _memory.Span; span[BytesPending++] = BEncodingConstants.OpenInteger; bool success = Utf8Formatter.TryFormat(value, span.Slice(BytesPending), out int written); Debug.Assert(success); BytesPending += written; span[BytesPending++] = BEncodingConstants.End; }
/// <summary> /// Creates an <see cref="IdSpan"/> representing a <see cref="long"/> key. /// </summary> public static IdSpan CreateIntegerKey(long key, string keyExtension) { if (string.IsNullOrWhiteSpace(keyExtension)) { return(CreateIntegerKey(key)); } Span <byte> tmp = stackalloc byte[sizeof(long) * 2]; Utf8Formatter.TryFormat(key, tmp, out var len, 'X'); Debug.Assert(len > 0); var extLen = Encoding.UTF8.GetByteCount(keyExtension); var buf = new byte[len + 1 + extLen]; tmp.Slice(0, len).CopyTo(buf); buf[len] = (byte)'+'; Encoding.UTF8.GetBytes(keyExtension, 0, keyExtension.Length, buf, len + 1); return(new IdSpan(buf)); }
private void WriteValueFormatted(Guid value) { int indent = Indentation; // This is guaranteed not to overflow. Debug.Assert(int.MaxValue - JsonConstants.MaximumGuidLength - 3 - JsonWriterHelper.NewLineUtf8.Length - indent >= 0); // Calculated based on the following: ',\r\n "value"' int bytesNeeded = 3 + JsonWriterHelper.NewLineUtf8.Length + indent + JsonConstants.MaximumGuidLength; Span <byte> byteBuffer = WriteValueFormatted(bytesNeeded, indent, out int idx); byteBuffer[idx++] = JsonConstants.Quote; bool result = Utf8Formatter.TryFormat(value, byteBuffer.Slice(idx), out int bytesWritten); Debug.Assert(result); idx += bytesWritten; byteBuffer[idx++] = JsonConstants.Quote; Advance(idx); }
private void WriteNumberValueMinimized(long value) { int maxRequired = JsonConstants.MaximumFormatInt64Length + 1; // Optionally, 1 list separator if (_memory.Length - BytesPending < maxRequired) { Grow(maxRequired); } Span <byte> output = _memory.Span; if (_currentDepth < 0) { output[BytesPending++] = JsonConstants.ListSeparator; } bool result = Utf8Formatter.TryFormat(value, output.Slice(BytesPending), out int bytesWritten); Debug.Assert(result); BytesPending += bytesWritten; }
internal Result GetConcatenationFileSize(out long size, ReadOnlySpan <byte> path) { UnsafeHelpers.SkipParamInit(out size); Unsafe.SkipInit(out FsPath buffer); int pathLen = StringUtils.Copy(buffer.Str, path); // Make sure we have at least 3 bytes for the sub file name if (pathLen + 3 > PathTools.MaxPathLength) { return(ResultFs.TooLongPath.Log()); } buffer.Str[pathLen] = StringTraits.DirectorySeparator; Span <byte> subFileName = buffer.Str.Slice(pathLen + 1); Result rc; long totalSize = 0; for (int i = 0; ; i++) { Utf8Formatter.TryFormat(i, subFileName, out _, new StandardFormat('D', 2)); rc = BaseFileSystem.GetFileSize(out long fileSize, buffer); if (rc.IsFailure()) { break; } totalSize += fileSize; } if (!ResultFs.PathNotFound.Includes(rc)) { return(rc); } size = totalSize; return(Result.Success); }
private void WriteStringValueIndented(Guid value) { int indent = Indentation; Debug.Assert(indent <= 2 * JsonConstants.MaxWriterDepth); // 2 quotes, and optionally, 1 list separator and 1-2 bytes for new line int maxRequired = indent + JsonConstants.MaximumFormatGuidLength + 3 + s_newLineLength; if (_memory.Length - BytesPending < maxRequired) { Grow(maxRequired); } Span <byte> output = _memory.Span; if (_currentDepth < 0) { output[BytesPending++] = JsonConstants.ListSeparator; } if (_tokenType != JsonTokenType.PropertyName) { if (_tokenType != JsonTokenType.None) { WriteNewLine(output); } JsonWriterHelper.WriteIndentation(output.Slice(BytesPending), indent); BytesPending += indent; } output[BytesPending++] = JsonConstants.Quote; bool result = Utf8Formatter.TryFormat(value, output.Slice(BytesPending), out int bytesWritten); Debug.Assert(result); BytesPending += bytesWritten; output[BytesPending++] = JsonConstants.Quote; }
private static void WriteWideRgb <TPixel>(Configuration configuration, Stream stream, ImageFrame <TPixel> image) where TPixel : unmanaged, IPixel <TPixel> { int width = image.Width; int height = image.Height; Buffer2D <TPixel> pixelBuffer = image.PixelBuffer; MemoryAllocator allocator = configuration.MemoryAllocator; using IMemoryOwner <Rgb48> row = allocator.Allocate <Rgb48>(width); Span <Rgb48> rowSpan = row.GetSpan(); using IMemoryOwner <byte> plainMemory = allocator.Allocate <byte>(width * MaxCharsPerPixelRgbWide); Span <byte> plainSpan = plainMemory.GetSpan(); for (int y = 0; y < height; y++) { Span <TPixel> pixelSpan = pixelBuffer.DangerousGetRowSpan(y); PixelOperations <TPixel> .Instance.ToRgb48( configuration, pixelSpan, rowSpan); int written = 0; for (int x = 0; x < width; x++) { Utf8Formatter.TryFormat(rowSpan[x].R, plainSpan.Slice(written), out int bytesWritten, DecimalFormat); written += bytesWritten; plainSpan[written++] = Space; Utf8Formatter.TryFormat(rowSpan[x].G, plainSpan.Slice(written), out bytesWritten, DecimalFormat); written += bytesWritten; plainSpan[written++] = Space; Utf8Formatter.TryFormat(rowSpan[x].B, plainSpan.Slice(written), out bytesWritten, DecimalFormat); written += bytesWritten; plainSpan[written++] = Space; } plainSpan[written - 1] = NewLine; stream.Write(plainSpan, 0, written); } }
private static void Utf8Parser_TryParseDouble(ReadOnlySpan <byte> data) { Span <byte> to = stackalloc byte[1024]; if (Utf8Parser.TryParse(data, out double d1, out _)) { if (double.IsNaN(d1)) { return; } if (!Utf8Formatter.TryFormat(d1, to, out int written)) { throw new Exception(); } if (!Utf8Parser.TryParse(to.Slice(0, written), out double d2, out _)) { throw new Exception(); } } }
private void WriteArrayFast(ref ReadOnlySpan <byte> propertyName, ref ReadOnlySpan <float> values) { if (values.Length > 0 && values.Length < (int.MaxValue - 5 - propertyName.Length) / (JsonConstants.MaximumSingleLength + 1)) { // Calculated based on the following: '"propertyName":[number0,number1,...,numberN]' int bytesNeeded = propertyName.Length + 5 + (values.Length * (1 + JsonConstants.MaximumSingleLength) - 1); if (_currentDepth >= 0) { bytesNeeded--; } Ensure(bytesNeeded); WritePropertyName(ref propertyName, bytesNeeded, out int idx); _buffer[idx++] = JsonConstants.OpenBracket; bool result = Utf8Formatter.TryFormat(values[0], _buffer.Slice(idx), out int bytesWritten); Debug.Assert(result); idx += bytesWritten; for (int i = 1; i < values.Length; i++) { _buffer[idx++] = JsonConstants.ListSeperator; result = Utf8Formatter.TryFormat(values[i], _buffer.Slice(idx), out bytesWritten); Debug.Assert(result); idx += bytesWritten; } _buffer[idx++] = JsonConstants.CloseBracket; Advance(idx); } else { WriteArrayFastIterate(ref propertyName, ref values); } }
private void WriteStringMinimized(ReadOnlySpan <byte> escapedPropertyName, DateTimeOffset value) { Debug.Assert(escapedPropertyName.Length < int.MaxValue - JsonConstants.MaximumFormatDateTimeOffsetLength - 6); int minRequired = escapedPropertyName.Length + JsonConstants.MaximumFormatDateTimeOffsetLength + 5; // 2 quotes for property name, 2 quotes for date, and 1 colon int maxRequired = minRequired + 1; // Optionally, 1 list separator if (_memory.Length - BytesPending < maxRequired) { Grow(maxRequired); } Span <byte> output = _memory.Span; if (_currentDepth < 0) { output[BytesPending++] = JsonConstants.ListSeparator; } output[BytesPending++] = JsonConstants.Quote; escapedPropertyName.CopyTo(output.Slice(BytesPending)); BytesPending += escapedPropertyName.Length; output[BytesPending++] = JsonConstants.Quote; output[BytesPending++] = JsonConstants.KeyValueSeperator; output[BytesPending++] = JsonConstants.Quote; Span <byte> tempSpan = stackalloc byte[JsonConstants.MaximumFormatDateTimeOffsetLength]; bool result = Utf8Formatter.TryFormat(value, tempSpan, out int bytesWritten, s_dateTimeStandardFormat); Debug.Assert(result); JsonWriterHelper.TrimDateTimeOffset(tempSpan.Slice(0, bytesWritten), out bytesWritten); tempSpan.Slice(0, bytesWritten).CopyTo(output.Slice(BytesPending)); BytesPending += bytesWritten; output[BytesPending++] = JsonConstants.Quote; }
private void WriteStringMinimized(ReadOnlySpan <char> escapedPropertyName, DateTimeOffset value) { Debug.Assert(escapedPropertyName.Length < (int.MaxValue / JsonConstants.MaxExpansionFactorWhileTranscoding) - JsonConstants.MaximumFormatDateTimeOffsetLength - 6); // All ASCII, 2 quotes for property name, 2 quotes for date, and 1 colon => escapedPropertyName.Length + JsonConstants.MaximumFormatDateTimeOffsetLength + 5 // Optionally, 1 list separator, and up to 3x growth when transcoding int maxRequired = (escapedPropertyName.Length * JsonConstants.MaxExpansionFactorWhileTranscoding) + JsonConstants.MaximumFormatDateTimeOffsetLength + 6; if (_memory.Length - BytesPending < maxRequired) { Grow(maxRequired); } Span <byte> output = _memory.Span; if (_currentDepth < 0) { output[BytesPending++] = JsonConstants.ListSeparator; } output[BytesPending++] = JsonConstants.Quote; TranscodeAndWrite(escapedPropertyName, output); output[BytesPending++] = JsonConstants.Quote; output[BytesPending++] = JsonConstants.KeyValueSeperator; output[BytesPending++] = JsonConstants.Quote; Span <byte> tempSpan = stackalloc byte[JsonConstants.MaximumFormatDateTimeOffsetLength]; bool result = Utf8Formatter.TryFormat(value, tempSpan, out int bytesWritten, s_dateTimeStandardFormat); Debug.Assert(result); JsonWriterHelper.TrimDateTimeOffset(tempSpan.Slice(0, bytesWritten), out bytesWritten); tempSpan.Slice(0, bytesWritten).CopyTo(output.Slice(BytesPending)); BytesPending += bytesWritten; output[BytesPending++] = JsonConstants.Quote; }
private static void Utf8Parser_TryParseTimeSpan(ReadOnlySpan <byte> data) { Span <byte> to = stackalloc byte[1024]; if (Utf8Parser.TryParse(data, out TimeSpan t1, out _)) { var format = 'c'; if (!Utf8Formatter.TryFormat(t1, to, out int written, format)) { throw new Exception(); } if (!Utf8Parser.TryParse(to.Slice(0, written), out TimeSpan t2, out _, format)) { throw new Exception(); } if (t1 != t2) { throw new Exception(); } } }
public static void WriteDateTime(Utf8JsonWriter writer, DateTime value) { long unixTime = Convert.ToInt64((value.ToUniversalTime() - s_Epoch).TotalMilliseconds); int stackSize = 64; while (true) { Span <byte> span = stackSize <= 1024 ? stackalloc byte[stackSize] : new byte[stackSize]; if (!Utf8Formatter.TryFormat(unixTime, span.Slice(7), out int bytesWritten, new StandardFormat('D'))) { stackSize *= 2; continue; } Start.CopyTo(span); End.CopyTo(span.Slice(7 + bytesWritten)); writer.WriteStringValue( CreateJsonEncodedTextFunc(span.Slice(0, 10 + bytesWritten).ToArray())); break; } }
private static object?To(Type type) { if (type == typeof(string)) { return(_fromString ?? (_fromString = new[] { ValueBinder.Converter.Utf16Text((string value) => value.AsSpan()) })); } if (type == typeof(ReadOnlyMemory <char>)) { return(_fromStringROMemory ?? (_fromStringROMemory = new[] { ValueBinder.Converter.Utf16Text((ReadOnlyMemory <char> value) => value.Span) })); } if (type == typeof(Memory <char>)) { return(_fromStringMemory ?? (_fromStringMemory = new[] { ValueBinder.Converter.Utf16Text((Memory <char> value) => value.Span) })); } if (type == typeof(Guid)) { return(_fromGuid ?? (_fromGuid = new[] { ValueBinder.Converter.Utf8Text( (Guid value, Span <byte> dest) => { if (!Utf8Formatter.TryFormat(value, dest, out _)) { throw new FormatException(); } }, _ => 36), })); } if (type == typeof(Guid?)) { return(_fromGuidNull ?? (_fromGuidNull = new[]
public void WriteValue(Decimal value) { WriteStarted(InternalState.Value); var span = m_output.GetSpan(Constants.MaxDecimalSize); if (!Utf8Formatter.TryFormat(value, span, out var bytesWritten)) { ThrowFormatException(value); } // Do not serialize trailing zeroes. The current version of the Utf8Formatter we use // do not allow us to specify that we don't want any. if (span[bytesWritten - 1] == (Byte)'0') { // Find out if the decimal has a decimal point var pointIndex = span.Slice(0, bytesWritten).LastIndexOf((Byte)'.'); if (pointIndex != -1) { --bytesWritten; while (span[bytesWritten - 1] == (Byte)'0') { --bytesWritten; } if (bytesWritten - 1 == pointIndex) { --bytesWritten; } } } m_output.Advance(bytesWritten); }
private static bool TryFormatUtf8(object value, Span <byte> buffer, out int bytesWritten, StandardFormat format = default) { Type t = value.GetType(); if (t == typeof(bool)) { return(Utf8Formatter.TryFormat((bool)value, buffer, out bytesWritten, format)); } if (t == typeof(byte)) { return(Utf8Formatter.TryFormat((byte)value, buffer, out bytesWritten, format)); } if (t == typeof(sbyte)) { return(Utf8Formatter.TryFormat((sbyte)value, buffer, out bytesWritten, format)); } if (t == typeof(short)) { return(Utf8Formatter.TryFormat((short)value, buffer, out bytesWritten, format)); } if (t == typeof(ushort)) { return(Utf8Formatter.TryFormat((ushort)value, buffer, out bytesWritten, format)); } if (t == typeof(int)) { return(Utf8Formatter.TryFormat((int)value, buffer, out bytesWritten, format)); } if (t == typeof(uint)) { return(Utf8Formatter.TryFormat((uint)value, buffer, out bytesWritten, format)); } if (t == typeof(long)) { return(Utf8Formatter.TryFormat((long)value, buffer, out bytesWritten, format)); } if (t == typeof(ulong)) { return(Utf8Formatter.TryFormat((ulong)value, buffer, out bytesWritten, format)); } if (t == typeof(decimal)) { return(Utf8Formatter.TryFormat((decimal)value, buffer, out bytesWritten, format)); } if (t == typeof(double)) { return(Utf8Formatter.TryFormat((double)value, buffer, out bytesWritten, format)); } if (t == typeof(float)) { return(Utf8Formatter.TryFormat((float)value, buffer, out bytesWritten, format)); } if (t == typeof(Guid)) { return(Utf8Formatter.TryFormat((Guid)value, buffer, out bytesWritten, format)); } if (t == typeof(DateTime)) { return(Utf8Formatter.TryFormat((DateTime)value, buffer, out bytesWritten, format)); } if (t == typeof(DateTimeOffset)) { return(Utf8Formatter.TryFormat((DateTimeOffset)value, buffer, out bytesWritten, format)); } if (t == typeof(TimeSpan)) { return(Utf8Formatter.TryFormat((TimeSpan)value, buffer, out bytesWritten, format)); } throw new Exception("No formatter for type " + t); }
// T-REC-X.680-201508 sec 46 // T-REC-X.690-201508 sec 11.7 private void WriteGeneralizedTimeCore(Asn1Tag tag, DateTimeOffset value, bool omitFractionalSeconds) { // GeneralizedTime under BER allows many different options: // * (HHmmss), (HHmm), (HH) // * "(value).frac", "(value),frac" // * frac == 0 may be omitted or emitted // non-UTC offset in various formats // // We're not allowing any of them. // Just encode as the CER/DER common restrictions. // // This results in the following formats: // yyyyMMddHHmmssZ // yyyyMMddHHmmss.f?Z // // where "f?" is anything from "f" to "fffffff" (tenth of a second down to 100ns/1-tick) // with no trailing zeros. DateTimeOffset normalized = value.ToUniversalTime(); if (normalized.Year > 9999) { // This is unreachable since DateTimeOffset guards against this internally. throw new ArgumentOutOfRangeException(nameof(value)); } // We're only loading in sub-second ticks. // Ticks are defined as 1e-7 seconds, so their printed form // is at the longest "0.1234567", or 9 bytes. Span <byte> fraction = stackalloc byte[0]; if (!omitFractionalSeconds) { long floatingTicks = normalized.Ticks % TimeSpan.TicksPerSecond; if (floatingTicks != 0) { // We're only loading in sub-second ticks. // Ticks are defined as 1e-7 seconds, so their printed form // is at the longest "0.1234567", or 9 bytes. fraction = stackalloc byte[9]; decimal decimalTicks = floatingTicks; decimalTicks /= TimeSpan.TicksPerSecond; if (!Utf8Formatter.TryFormat(decimalTicks, fraction, out int bytesWritten, new StandardFormat('G'))) { Debug.Fail($"Utf8Formatter.TryFormat could not format {floatingTicks} / TicksPerSecond"); throw new CryptographicException(); } Debug.Assert(bytesWritten > 2, $"{bytesWritten} should be > 2"); Debug.Assert(fraction[0] == (byte)'0'); Debug.Assert(fraction[1] == (byte)'.'); fraction = fraction.Slice(1, bytesWritten - 1); } } // yyyy, MM, dd, hh, mm, ss const int IntegerPortionLength = 4 + 2 + 2 + 2 + 2 + 2; // Z, and the optional fraction. int totalLength = IntegerPortionLength + 1 + fraction.Length; // Because GeneralizedTime is IMPLICIT VisibleString it technically can have // a constructed form. // DER says character strings must be primitive. // CER says character strings <= 1000 encoded bytes must be primitive. // So we'll just make BER be primitive, too. Debug.Assert(!tag.IsConstructed); this.WriteTag(tag); this.WriteLength(totalLength); int year = normalized.Year; int month = normalized.Month; int day = normalized.Day; int hour = normalized.Hour; int minute = normalized.Minute; int second = normalized.Second; Span <byte> baseSpan = this._buffer.AsSpan(this._offset); StandardFormat d4 = new StandardFormat('D', 4); StandardFormat d2 = new StandardFormat('D', 2); if (!Utf8Formatter.TryFormat(year, baseSpan.Slice(0, 4), out _, d4) || !Utf8Formatter.TryFormat(month, baseSpan.Slice(4, 2), out _, d2) || !Utf8Formatter.TryFormat(day, baseSpan.Slice(6, 2), out _, d2) || !Utf8Formatter.TryFormat(hour, baseSpan.Slice(8, 2), out _, d2) || !Utf8Formatter.TryFormat(minute, baseSpan.Slice(10, 2), out _, d2) || !Utf8Formatter.TryFormat(second, baseSpan.Slice(12, 2), out _, d2)) { Debug.Fail($"Utf8Formatter.TryFormat failed to build components of {normalized:O}"); throw new CryptographicException(); } this._offset += IntegerPortionLength; fraction.CopyTo(baseSpan.Slice(IntegerPortionLength)); this._offset += fraction.Length; this._buffer[this._offset] = (byte)'Z'; this._offset++; }
public static bool TryWritePrimitives(Span <byte> output, Sha256 hash, string keyType, string verb, string resourceId, string resourceType, string tokenVersion, DateTime utc, out int bytesWritten) { int totalWritten = 0; bytesWritten = 0; Span <byte> buffer = stackalloc byte[AuthenticationHeaderBufferSize]; s_type.CopyTo(buffer); totalWritten += s_type.Length; if (Encodings.Utf16.ToUtf8(keyType.AsReadOnlySpan().AsBytes(), buffer.Slice(totalWritten), out int consumed, out int written) != OperationStatus.Done) { throw new NotImplementedException("need to resize buffer"); } totalWritten += written; s_ver.CopyTo(buffer.Slice(totalWritten)); totalWritten += s_ver.Length; if (Encodings.Utf16.ToUtf8(tokenVersion.AsReadOnlySpan().AsBytes(), buffer.Slice(totalWritten), out consumed, out written) != OperationStatus.Done) { throw new NotImplementedException("need to resize buffer"); } totalWritten += written; s_sig.CopyTo(buffer.Slice(totalWritten)); totalWritten += s_sig.Length; var front = buffer.Slice(0, totalWritten); var payload = buffer.Slice(totalWritten); totalWritten = 0; if (verb.Equals("GET", StringComparison.Ordinal) || verb.Equals("get", StringComparison.Ordinal)) { s_get.CopyTo(payload); totalWritten += s_get.Length; } else if (verb.Equals("POST", StringComparison.Ordinal) || verb.Equals("post", StringComparison.Ordinal)) { s_post.CopyTo(payload); totalWritten += s_post.Length; } else if (verb.Equals("DELETE", StringComparison.Ordinal) || verb.Equals("delete", StringComparison.Ordinal)) { s_delete.CopyTo(payload); totalWritten += s_delete.Length; } else { if (Encodings.Utf16.ToUtf8(verb.AsReadOnlySpan().AsBytes(), payload, out consumed, out written) != OperationStatus.Done) { throw new NotImplementedException("need to resize buffer"); } if (Encodings.Ascii.ToLowerInPlace(payload.Slice(0, written), out written) != OperationStatus.Done) { throw new NotImplementedException("need to resize buffer"); } payload[written] = (byte)'\n'; totalWritten += written + 1; } var bufferSlice = payload.Slice(totalWritten); if (Encodings.Utf16.ToUtf8(resourceType.AsReadOnlySpan().AsBytes(), bufferSlice, out consumed, out written) != OperationStatus.Done) { throw new NotImplementedException("need to resize buffer"); } if (Encodings.Ascii.ToLowerInPlace(bufferSlice.Slice(0, written), out written) != OperationStatus.Done) { throw new NotImplementedException("need to resize buffer"); } bufferSlice[written] = (byte)'\n'; totalWritten += written + 1; bufferSlice = payload.Slice(totalWritten); if (Encodings.Utf16.ToUtf8(resourceId.AsReadOnlySpan().AsBytes(), bufferSlice, out consumed, out written) != OperationStatus.Done) { throw new NotImplementedException("need to resize buffer"); } bufferSlice[written] = (byte)'\n'; totalWritten += written + 1; bufferSlice = payload.Slice(totalWritten); if (!Utf8Formatter.TryFormat(utc, bufferSlice, out written, 'l')) { throw new NotImplementedException("need to resize buffer"); } bufferSlice[written] = (byte)'\n'; totalWritten += written + 1; bufferSlice = payload.Slice(totalWritten); bufferSlice[0] = (byte)'\n'; totalWritten += 1; hash.Append(buffer.Slice(front.Length, totalWritten)); if (!hash.TryWrite(buffer.Slice(front.Length), out written)) { throw new NotImplementedException("need to resize buffer"); } if (Base64.EncodeToUtf8InPlace(buffer.Slice(front.Length), written, out written) != OperationStatus.Done) { throw new NotImplementedException("need to resize buffer"); } var len = front.Length + written; if (UrlEncoder.Utf8.Encode(buffer.Slice(0, len), output, out consumed, out bytesWritten) != OperationStatus.Done) { bytesWritten = 0; return(false); } return(true); }
static object CreateFormatter(Type type) { if (type == typeof(System.Byte)) { return(new TryFormat <System.Byte>((System.Byte x, Span <byte> dest, out int written, StandardFormat format) => Utf8Formatter.TryFormat(x, dest, out written, format))); } if (type == typeof(System.DateTime)) { return(new TryFormat <System.DateTime>((System.DateTime x, Span <byte> dest, out int written, StandardFormat format) => Utf8Formatter.TryFormat(x, dest, out written, format))); } if (type == typeof(System.DateTimeOffset)) { return(new TryFormat <System.DateTimeOffset>((System.DateTimeOffset x, Span <byte> dest, out int written, StandardFormat format) => Utf8Formatter.TryFormat(x, dest, out written, format))); } if (type == typeof(System.Decimal)) { return(new TryFormat <System.Decimal>((System.Decimal x, Span <byte> dest, out int written, StandardFormat format) => Utf8Formatter.TryFormat(x, dest, out written, format))); } if (type == typeof(System.Double)) { return(new TryFormat <System.Double>((System.Double x, Span <byte> dest, out int written, StandardFormat format) => Utf8Formatter.TryFormat(x, dest, out written, format))); } if (type == typeof(System.Int16)) { return(new TryFormat <System.Int16>((System.Int16 x, Span <byte> dest, out int written, StandardFormat format) => Utf8Formatter.TryFormat(x, dest, out written, format))); } if (type == typeof(System.Int32)) { return(new TryFormat <System.Int32>((System.Int32 x, Span <byte> dest, out int written, StandardFormat format) => Utf8Formatter.TryFormat(x, dest, out written, format))); } if (type == typeof(System.Int64)) { return(new TryFormat <System.Int64>((System.Int64 x, Span <byte> dest, out int written, StandardFormat format) => Utf8Formatter.TryFormat(x, dest, out written, format))); } if (type == typeof(System.SByte)) { return(new TryFormat <System.SByte>((System.SByte x, Span <byte> dest, out int written, StandardFormat format) => Utf8Formatter.TryFormat(x, dest, out written, format))); } if (type == typeof(System.Single)) { return(new TryFormat <System.Single>((System.Single x, Span <byte> dest, out int written, StandardFormat format) => Utf8Formatter.TryFormat(x, dest, out written, format))); } if (type == typeof(System.TimeSpan)) { return(new TryFormat <System.TimeSpan>((System.TimeSpan x, Span <byte> dest, out int written, StandardFormat format) => Utf8Formatter.TryFormat(x, dest, out written, format))); } if (type == typeof(System.UInt16)) { return(new TryFormat <System.UInt16>((System.UInt16 x, Span <byte> dest, out int written, StandardFormat format) => Utf8Formatter.TryFormat(x, dest, out written, format))); } if (type == typeof(System.UInt32)) { return(new TryFormat <System.UInt32>((System.UInt32 x, Span <byte> dest, out int written, StandardFormat format) => Utf8Formatter.TryFormat(x, dest, out written, format))); } if (type == typeof(System.UInt64)) { return(new TryFormat <System.UInt64>((System.UInt64 x, Span <byte> dest, out int written, StandardFormat format) => Utf8Formatter.TryFormat(x, dest, out written, format))); } if (type == typeof(System.Guid)) { return(new TryFormat <System.Guid>((System.Guid x, Span <byte> dest, out int written, StandardFormat format) => Utf8Formatter.TryFormat(x, dest, out written, format))); } if (type == typeof(System.Boolean)) { return(new TryFormat <System.Boolean>((System.Boolean x, Span <byte> dest, out int written, StandardFormat format) => Utf8Formatter.TryFormat(x, dest, out written, format))); } if (type == typeof(System.Byte?)) { return(CreateNullableFormatter <System.Byte>()); } if (type == typeof(System.DateTime?)) { return(CreateNullableFormatter <System.DateTime>()); } if (type == typeof(System.DateTimeOffset?)) { return(CreateNullableFormatter <System.DateTimeOffset>()); } if (type == typeof(System.Decimal?)) { return(CreateNullableFormatter <System.Decimal>()); } if (type == typeof(System.Double?)) { return(CreateNullableFormatter <System.Double>()); } if (type == typeof(System.Int16?)) { return(CreateNullableFormatter <System.Int16>()); } if (type == typeof(System.Int32?)) { return(CreateNullableFormatter <System.Int32>()); } if (type == typeof(System.Int64?)) { return(CreateNullableFormatter <System.Int64>()); } if (type == typeof(System.SByte?)) { return(CreateNullableFormatter <System.SByte>()); } if (type == typeof(System.Single?)) { return(CreateNullableFormatter <System.Single>()); } if (type == typeof(System.TimeSpan?)) { return(CreateNullableFormatter <System.TimeSpan>()); } if (type == typeof(System.UInt16?)) { return(CreateNullableFormatter <System.UInt16>()); } if (type == typeof(System.UInt32?)) { return(CreateNullableFormatter <System.UInt32>()); } if (type == typeof(System.UInt64?)) { return(CreateNullableFormatter <System.UInt64>()); } if (type == typeof(System.Guid?)) { return(CreateNullableFormatter <System.Guid>()); } if (type == typeof(System.Boolean?)) { return(CreateNullableFormatter <System.Boolean>()); } if (type == typeof(System.IntPtr)) { // ignore format return(new TryFormat <System.IntPtr>((System.IntPtr x, Span <byte> dest, out int written, StandardFormat _) => System.IntPtr.Size == 4 ? Utf8Formatter.TryFormat(x.ToInt32(), dest, out written, default) : Utf8Formatter.TryFormat(x.ToInt64(), dest, out written, default))); } if (type == typeof(System.UIntPtr)) { // ignore format return(new TryFormat <System.UIntPtr>((System.UIntPtr x, Span <byte> dest, out int written, StandardFormat _) => System.UIntPtr.Size == 4 ? Utf8Formatter.TryFormat(x.ToUInt32(), dest, out written, default) : Utf8Formatter.TryFormat(x.ToUInt64(), dest, out written, default))); } return(null); }
static async Task Main() { using var server = new EchoServer(Port); await Task.Yield(); SocketConnection.AssertDependencies(); Log("Connecting..."); using var connection = await SocketConnection.ConnectAsync(new IPEndPoint (IPAddress.Loopback, Port)); Log("Connected"); Guid guid = Guid.NewGuid(); Log($"Writing '{guid}'..."); var output = connection.Output; var memory = output.GetMemory(30); if (!Utf8Formatter.TryFormat(guid, memory.Span, out var bytes)) { throw new FormatException(); } output.Advance(bytes); //Log($"Flushing..."); //var flushResult = await output.FlushAsync(); //Log($"IsCompleted:{flushResult.IsCompleted}, IsCanceled:{flushResult.IsCanceled}"); //Log($"Reading..."); //var input = connection.Input; //while (true) //{ // Log($"Reading..."); // var readResult = await input.ReadAsync(); // Log($"IsCompleted:{readResult.IsCompleted}, IsCanceled:{readResult.IsCanceled}, Length:{readResult.Buffer.Length}"); // if (readResult.IsCompleted || readResult.IsCanceled) break; // if (readResult.Buffer.Length >= 36) // { // var buffer = readResult.Buffer; // var len = checked((int)buffer.Length); // var arr = ArrayPool<byte>.Shared.Rent(len); // try // { // buffer.CopyTo(arr); // var s = Encoding.UTF8.GetString(arr, 0, len); // Log($"Received: '{s}'"); // } // finally // { // ArrayPool<byte>.Shared.Return(arr); // } // input.AdvanceTo(readResult.Buffer.End); // break; // } // else // { // input.AdvanceTo(readResult.Buffer.Start, readResult.Buffer.End); // } //} //Log($"Closing output..."); //output.Complete(); }
public static IMemoryOwner <byte> RentedSerialize(NatsMemoryPool pool, string subscriptionId, int?maxMessages) { var hint = _command.Length; hint += subscriptionId.Length; if (maxMessages != null) { if (maxMessages < 10) { hint += 1; } else if (maxMessages < 100) { hint += 2; } else if (maxMessages < 1_000) { hint += 3; } else if (maxMessages < 10_000) { hint += 4; } else if (maxMessages < 100_000) { hint += 5; } else if (maxMessages < 1_000_000) { hint += 6; } else if (maxMessages < 10_000_000) { hint += 7; } else { throw new ArgumentOutOfRangeException(nameof(maxMessages)); } hint += _del.Length; } hint += _end.Length; var rented = pool.Rent(hint); var buffer = rented.Memory; _command.CopyTo(buffer); var consumed = _command.Length; consumed += Encoding.UTF8.GetBytes(subscriptionId, buffer.Slice(consumed).Span); if (maxMessages != null) { _del.CopyTo(buffer.Slice(consumed)); consumed += _del.Length; Utf8Formatter.TryFormat(maxMessages.Value, buffer.Slice(consumed).Span, out var written); consumed += written; } _end.CopyTo(buffer.Slice(consumed)); return(rented); }
static bool TryWritePrimitive(Span <byte> output, Sha256 hash, string verb, string canonicalizedResource, DateTime utc, out int bytesWritten) { int written, consumed; bytesWritten = 0; if (verb.Equals("GET", StringComparison.Ordinal)) { if (output.Length < 3) { bytesWritten = 0; return(false); } s_GET.CopyTo(output); bytesWritten += s_GET.Length; } else { if (Encodings.Utf16.ToUtf8(MemoryMarshal.AsBytes(verb.AsSpan()), output, out consumed, out written) != OperationStatus.Done) { bytesWritten = 0; return(false); } output[written] = (byte)'\n'; bytesWritten += written + 1; } var free = output.Slice(bytesWritten); s_emptyHeaders.CopyTo(free); bytesWritten += s_emptyHeaders.Length; free = output.Slice(bytesWritten); if (!Utf8Formatter.TryFormat(utc, free, out written, 'R')) { bytesWritten = 0; return(false); } free[written] = (byte)'\n'; bytesWritten += written + 1; free = output.Slice(bytesWritten); if (Encodings.Utf16.ToUtf8(MemoryMarshal.AsBytes(canonicalizedResource.AsSpan()), free, out consumed, out written) != OperationStatus.Done) { bytesWritten = 0; return(false); } bytesWritten += written; var formatted = output.Slice(0, bytesWritten); hash.Append(formatted); if (!hash.TryWrite(output, out written)) { throw new NotImplementedException("need to resize buffer"); } if (Base64.EncodeToUtf8InPlace(output, written, out written) != OperationStatus.Done) { bytesWritten = 0; return(false); } bytesWritten = written; return(true); }