private static StringSegment TrimStartPatternCore(StringSegment source, ReadOnlySpan <char> pattern, StringComparison comparisonType, int max) { var pLen = pattern.Length; if (max == -1) { while (source.AsSpan().IndexOf(pattern, comparisonType) == 0) { source = source.Subsegment(pLen); if (pattern.Length > source.Length) { break; } } } else { while (0 != max-- && source.AsSpan().IndexOf(pattern, comparisonType) == 0) { source = source.Subsegment(pLen); if (pattern.Length > source.Length) { break; } } } return(source); }
private static StringSegment TrimEndPatternCore(StringSegment source, ReadOnlySpan <char> pattern, StringComparison comparisonType, int max) { var pLen = pattern.Length; var expectedIndex = source.Length - pLen; if (max == -1) { while (source.AsSpan().LastIndexOf(pattern, comparisonType) == expectedIndex) { source = source.Subsegment(0, expectedIndex); expectedIndex = source.Length - pattern.Length; if (expectedIndex < 0) { break; } } } else { while (0 != max-- && source.AsSpan().LastIndexOf(pattern, comparisonType) == expectedIndex) { source = source.Subsegment(0, expectedIndex); expectedIndex = source.Length - pattern.Length; if (expectedIndex < 0) { break; } } } return(source); }
public override string ToString() { var sb = new StringBuilder(); sb.Append(_unit.AsSpan()); sb.Append('='); var first = true; foreach (var range in Ranges) { if (first) { first = false; } else { sb.Append(", "); } sb.Append(range.From); sb.Append('-'); sb.Append(range.To); } return(sb.ToString()); }
public void RunSegments() { // <Segment> var segment = new StringSegment( "This a string, within a single segment representation.", 14, 25); Console.WriteLine($"Buffer: \"{segment.Buffer}\""); Console.WriteLine($"Offset: {segment.Offset}"); Console.WriteLine($"Length: {segment.Length}"); Console.WriteLine($"Value: \"{segment.Value}\""); Console.Write("Span: \""); foreach (char @char in segment.AsSpan()) { Console.Write(@char); } Console.Write("\"\n"); // Outputs: // Buffer: "This a string, within a single segment representation." // Offset: 14 // Length: 25 // Value: " within a single segment " // " within a single segment " // </Segment> }
public override string ToString() { var sb = new StringBuilder(); sb.Append(_unit.AsSpan()); sb.Append(' '); if (HasRange) { sb.Append(_from.GetValueOrDefault().ToString(NumberFormatInfo.InvariantInfo)); sb.Append('-'); sb.Append(_to.GetValueOrDefault().ToString(NumberFormatInfo.InvariantInfo)); } else { sb.Append('*'); } sb.Append('/'); if (HasLength) { sb.Append(_length.GetValueOrDefault().ToString(NumberFormatInfo.InvariantInfo)); } else { sb.Append('*'); } return(sb.ToString()); }
public SipBuilderStep SetResponseHeader(StringSegment statusCode, StringSegment reasonPhrase) { if (!IsStatusCodeValid(statusCode)) { throw new ArgumentException("Is not valid", nameof(statusCode)); } if (!IsReasonPhraseValid(reasonPhrase)) { throw new ArgumentException("Is not valid", nameof(reasonPhrase)); } var headerWithoutFirstLine = header.Slice(firstLineLength); var newFirstLineLength = statusCode.Length + reasonPhrase.Length + FirstLineAdditionalLength; var newHeader = new char[headerWithoutFirstLine.Length + newFirstLineLength]; var remainsOfNewHeader = newHeader.AsSpan(); remainsOfNewHeader = WriteAndSlice(remainsOfNewHeader, Version.AsSpan()); remainsOfNewHeader = WriteAndSlice(remainsOfNewHeader, WordDelimiter); remainsOfNewHeader = WriteAndSlice(remainsOfNewHeader, statusCode.AsSpan()); remainsOfNewHeader = WriteAndSlice(remainsOfNewHeader, WordDelimiter); remainsOfNewHeader = WriteAndSlice(remainsOfNewHeader, reasonPhrase.AsSpan()); remainsOfNewHeader = WriteAndSlice(remainsOfNewHeader, CRLF.AsSpan()); remainsOfNewHeader = WriteAndSlice(remainsOfNewHeader, headerWithoutFirstLine.Span); return(new SipBuilderStep(newHeader, body, newFirstLineLength)); }
public SipBuilderStep SetRequestHeader(StringSegment method, StringSegment uri) { if (!IsMethodValid(method)) { throw new ArgumentException("Is not valid", nameof(method)); } if (!IsUriValid(uri)) { throw new ArgumentException("Is not valid", nameof(uri)); } var headerWithoutFirstLine = header.Slice(firstLineLength); var newFirstLineLength = method.Length + uri.Length + FirstLineAdditionalLength; var newHeader = new char[headerWithoutFirstLine.Length + newFirstLineLength]; var remainsOfNewHeader = newHeader.AsSpan(); remainsOfNewHeader = WriteAndSlice(remainsOfNewHeader, method.AsSpan()); remainsOfNewHeader = WriteAndSlice(remainsOfNewHeader, WordDelimiter); remainsOfNewHeader = WriteAndSlice(remainsOfNewHeader, uri.AsSpan()); remainsOfNewHeader = WriteAndSlice(remainsOfNewHeader, WordDelimiter); remainsOfNewHeader = WriteAndSlice(remainsOfNewHeader, Version.AsSpan()); remainsOfNewHeader = WriteAndSlice(remainsOfNewHeader, CRLF.AsSpan()); remainsOfNewHeader = WriteAndSlice(remainsOfNewHeader, headerWithoutFirstLine.Span); return(new SipBuilderStep(newHeader, body, newFirstLineLength)); }
public object GetValue(BlittableJsonReaderObject queryParameters) { switch (Value) { case ValueTokenType.Parameter: queryParameters.TryGetMember(Token, out var r); return(r); case ValueTokenType.Long: return(QueryBuilder.ParseInt64WithSeparators(Token.Value)); case ValueTokenType.Double: return(double.Parse(Token.AsSpan(), NumberStyles.AllowThousands | NumberStyles.Float, CultureInfo.InvariantCulture)); case ValueTokenType.String: return(Token); case ValueTokenType.True: return(QueryExpressionExtensions.True); case ValueTokenType.False: return(QueryExpressionExtensions.False); case ValueTokenType.Null: return(null); default: throw new InvalidOperationException("Unknown ValueExpression value: " + Value); } }
public override string ToString() { var builder = new StringBuilder(); builder.Append(_mediaType.AsSpan()); NameValueHeaderValue.ToString(_parameters, separator: ';', leadingSeparator: true, destination: builder); return(builder.ToString()); }
private Span <char> WriteAndSliceHeader(Span <char> destination, StringSegment headerName, StringSegment headerValue) { var remainsOfDestination = destination; remainsOfDestination = WriteAndSlice(remainsOfDestination, headerName.AsSpan()); remainsOfDestination = WriteAndSlice(remainsOfDestination, HeaderNameValueDelimiter); remainsOfDestination = WriteAndSlice(remainsOfDestination, headerValue.AsSpan()); return(WriteAndSlice(remainsOfDestination, CRLF.AsSpan())); }
/// <summary> /// Try to convert a <see cref="StringSegment"/> representation of a positive number to its 64-bit signed /// integer equivalent. A return value indicates whether the conversion succeeded or failed. /// </summary> /// <param name="value"> /// A <see cref="StringSegment"/> containing a number to convert. /// </param> /// <param name="result"> /// When this method returns, contains the 64-bit signed integer value equivalent of the number contained /// in the string, if the conversion succeeded, or zero if the conversion failed. The conversion fails if /// the <see cref="StringSegment"/> is null or String.Empty, is not of the correct format, is negative, or /// represents a number greater than Int64.MaxValue. This parameter is passed uninitialized; any value /// originally supplied in result will be overwritten. /// </param> /// <returns><see langword="true" /> if parsing succeeded; otherwise, <see langword="false" />.</returns> public static bool TryParseNonNegativeInt64(StringSegment value, out long result) { if (string.IsNullOrEmpty(value.Buffer) || value.Length == 0) { result = 0; return(false); } return(long.TryParse(value.AsSpan(), NumberStyles.None, NumberFormatInfo.InvariantInfo, out result)); }
private static void AppendSegment(ref Span <char> span, StringSegment name, StringSegment value) { Append(ref span, SeparatorToken); Append(ref span, name.AsSpan()); if (value != null) { Append(ref span, EqualsToken); Append(ref span, value.AsSpan()); } }
// Encode using MIME encoding // And adds surrounding quotes, Encoded data must always be quoted, the equals signs are invalid in tokens private string EncodeMimeWithQuotes(StringSegment input) { var requiredLength = MimePrefix.Length + GetBase64Length(Encoding.UTF8.GetByteCount(input.AsSpan())) + MimeSuffix.Length; Span <byte> buffer = requiredLength <= 256 ? (stackalloc byte[256]).Slice(0, requiredLength) : new byte[requiredLength]; MimePrefix.CopyTo(buffer); var bufferContent = buffer.Slice(MimePrefix.Length); var contentLength = Encoding.UTF8.GetBytes(input.AsSpan(), bufferContent); Base64.EncodeToUtf8InPlace(bufferContent, contentLength, out var base64ContentLength); MimeSuffix.CopyTo(bufferContent.Slice(base64ContentLength)); return(Encoding.UTF8.GetString(buffer.Slice(0, MimePrefix.Length + base64ContentLength + MimeSuffix.Length))); }
/// <inheritdoc /> // name="val ue"; public override string ToString() { var header = new StringBuilder(); header.Append(_name.AsSpan()); header.Append("="); header.Append(_value.AsSpan()); return(header.ToString()); }
private static void AppendSegment(StringBuilder builder, StringSegment name, StringSegment value) { builder.Append("; "); builder.Append(name.AsSpan()); if (value != null) { builder.Append("="); builder.Append(value.AsSpan()); } }
/// <summary> /// Append string representation of this <see cref="SetCookieHeaderValue"/> to given /// <paramref name="builder"/>. /// </summary> /// <param name="builder"> /// The <see cref="StringBuilder"/> to receive the string representation of this /// <see cref="SetCookieHeaderValue"/>. /// </param> public void AppendToStringBuilder(StringBuilder builder) { builder.Append(_name.AsSpan()); builder.Append("="); builder.Append(_value.AsSpan()); if (Expires.HasValue) { AppendSegment(builder, ExpiresToken, HeaderUtilities.FormatDate(Expires.GetValueOrDefault())); } if (MaxAge.HasValue) { AppendSegment(builder, MaxAgeToken, HeaderUtilities.FormatNonNegativeInt64((long)MaxAge.GetValueOrDefault().TotalSeconds)); } if (Domain != null) { AppendSegment(builder, DomainToken, Domain); } if (Path != null) { AppendSegment(builder, PathToken, Path); } if (Secure) { AppendSegment(builder, SecureToken, null); } // Allow for Unspecified (-1) to skip SameSite if (SameSite == SameSiteMode.None) { AppendSegment(builder, SameSiteToken, SameSiteNoneToken); } else if (SameSite == SameSiteMode.Lax) { AppendSegment(builder, SameSiteToken, SameSiteLaxToken); } else if (SameSite == SameSiteMode.Strict) { AppendSegment(builder, SameSiteToken, SameSiteStrictToken); } if (HttpOnly) { AppendSegment(builder, HttpOnlyToken, null); } foreach (var extension in Extensions) { AppendSegment(builder, extension, null); } }
private static bool TrySliceVersion(StringSegment chars, out StringSegment remainingChars) { remainingChars = StringSegment.Empty; if (!chars.AsSpan().StartsWith(VersionString.AsSpan())) { return(false); } remainingChars = chars.Subsegment(VersionString.Length); return(true); }
public Dictionary <StringSegment, object> Unflatten(Dictionary <string, string> data, char separator = '_') { var result = new Dictionary <StringSegment, object>(); (Dictionary <StringSegment, object> @object, List <object> list)cur = default; var idx = 0; StringSegment prop = StringSegment.Empty; foreach (var p in data.Keys) { cur.@object = result; prop = string.Empty; var last = 0; do { idx = p.IndexOf(separator, last); var temp = idx != -1 ? new StringSegment(p, last, idx - last) : new StringSegment(p, last, p.Length - last); if (cur.@object != null) { var leftSideOfProp = new StringSegment(prop.Buffer, 0, prop.Offset + prop.Length); if ([email protected](prop)) { var tempAsBytes = MemoryMarshal.AsBytes(temp.AsSpan()); if (Utf8Parser.TryParse(tempAsBytes, out int listIndex, out var _)) { [email protected](prop, new List <object>()); } else { [email protected](prop, new Dictionary <StringSegment, object>()); } } if (cur.@object[prop] is Dictionary <StringSegment, object> ) { cur.@object = cur.@object[prop] as Dictionary <StringSegment, object>; cur.list = null; } else { cur.@object = null; cur.list = cur.@object[prop] as List <object>; } } else { var propAsBytes = MemoryMarshal.AsBytes(prop.AsSpan()); var tempAsBytes = MemoryMarshal.AsBytes(temp.AsSpan()); Utf8Parser.TryParse(propAsBytes, out int index, out var _); if (Utf8Parser.TryParse(tempAsBytes, out int listIndex, out var _)) { cur.list.Add(new List <Dictionary <StringSegment, object> >()); }
/// <inheritdoc cref="TrimStartPattern(ReadOnlySpan{char}, ReadOnlySpan{char}, StringComparison, int)"/> public static ReadOnlySpan <char> TrimStartPattern(this ReadOnlySpan <char> source, StringSegment pattern, StringComparison comparisonType = StringComparison.Ordinal, int max = -1) { if (max < -1) { throw new ArgumentOutOfRangeException(nameof(max), max, MustBeAtleastNegativeOne); } Contract.EndContractBlock(); return(max == 0 || source.IsEmpty || pattern.Length == 0 || pattern.Length > source.Length ? source : TrimStartPatternCore(source, pattern.AsSpan(), comparisonType, max)); }
private static SipRequest CreateRequest(StringSegment headers, ReadOnlyMemory <byte> body) { var lineBreakIndex = headers.AsSpan().IndexOf(CRLFString.AsSpan()); var firstLine = headers.Subsegment(0, lineBreakIndex); var words = firstLine.Split(WordDelimiters).GetEnumerator(); words.MoveNext(); var method = words.Current; words.MoveNext(); var uri = words.Current; words.MoveNext(); var version = words.Current; return(new SipRequest(headers, method, uri, version, body)); }
/// <summary> /// Append string representation of this <see cref="SetCookieHeaderValue"/> to given /// <paramref name="builder"/>. /// </summary> /// <param name="builder"> /// The <see cref="StringBuilder"/> to receive the string representation of this /// <see cref="SetCookieHeaderValue"/>. /// </param> public void AppendToStringBuilder(StringBuilder builder) { builder.Append(_name.AsSpan()); builder.Append("="); builder.Append(_value.AsSpan()); if (Expires.HasValue) { AppendSegment(builder, ExpiresToken, HeaderUtilities.FormatDate(Expires.GetValueOrDefault())); } if (MaxAge.HasValue) { AppendSegment(builder, MaxAgeToken, HeaderUtilities.FormatNonNegativeInt64((long)MaxAge.GetValueOrDefault().TotalSeconds)); } if (Domain != null) { AppendSegment(builder, DomainToken, Domain); } if (Path != null) { AppendSegment(builder, PathToken, Path); } if (Secure) { AppendSegment(builder, SecureToken, null); } if (SameSite != SameSiteMode.None) { AppendSegment(builder, SameSiteToken, SameSite == SameSiteMode.Lax ? SameSiteLaxToken : SameSiteStrictToken); } if (HttpOnly) { AppendSegment(builder, HttpOnlyToken, null); } }
private string EncodeMimeWithQuotes(StringSegment input) { var requiredLength = MimePrefix.Length + Base64.GetMaxEncodedToUtf8Length(Encoding.UTF8.GetByteCount(input.AsSpan())) + MimeSuffix.Length; byte[]? bufferFromPool = null; Span <byte> buffer = requiredLength <= MaxStackAllocSizeBytes ? stackalloc byte[MaxStackAllocSizeBytes] : bufferFromPool = ArrayPool <byte> .Shared.Rent(requiredLength); buffer = buffer[..requiredLength];
/// <inheritdoc cref="TrimStartPattern(ReadOnlySpan{char}, ReadOnlySpan{char}, StringComparison, int)"/> public static StringSegment TrimStartPattern(this StringSegment source, StringSegment pattern, StringComparison comparisonType = StringComparison.Ordinal, int max = -1) => TrimStartPattern(source, pattern.AsSpan(), comparisonType, max);
/// <inheritdoc cref="Equals(string?)"/> public bool Equals(StringSegment other) => Equals(other.AsSpan());