public static string CollapseWhitespace(this string str) { if (str == null) { return(null); } var sb = StringBuilderThreadStatic.Allocate(); var lastChar = (char)0; for (var i = 0; i < str.Length; i++) { var c = str[i]; if (c < 32) { continue; // Skip all these } if (c == 32) { if (lastChar == 32) { continue; // Only write one space character } } sb.Append(c); lastChar = c; } return(StringBuilderThreadStatic.ReturnAndFree(sb)); }
public static string HexEscape(this string text, params char[] anyCharOf) { if (string.IsNullOrEmpty(text)) { return(text); } if (anyCharOf == null || anyCharOf.Length == 0) { return(text); } var encodeCharMap = new HashSet <char>(anyCharOf); var sb = StringBuilderThreadStatic.Allocate(); var textLength = text.Length; for (var i = 0; i < textLength; i++) { var c = text[i]; if (encodeCharMap.Contains(c)) { sb.Append('%' + ((int)c).ToString("x")); } else { sb.Append(c); } } return(StringBuilderThreadStatic.ReturnAndFree(sb)); }
public static string HexUnescape(this string text, params char[] anyCharOf) { if (String.IsNullOrEmpty(text)) { return(null); } if (anyCharOf == null || anyCharOf.Length == 0) { return(text); } var sb = StringBuilderThreadStatic.Allocate(); var textLength = text.Length; for (var i = 0; i < textLength; i++) { var c = text.Substring(i, 1); if (c == "%") { var hexNo = Convert.ToInt32(text.Substring(i + 1, 2), 16); sb.Append((char)hexNo); i += 2; } else { sb.Append(c); } } return(StringBuilderThreadStatic.ReturnAndFree(sb)); }
public static string CombinePaths(params string[] paths) { var sb = StringBuilderThreadStatic.Allocate(); AppendPaths(sb, paths); return(StringBuilderThreadStatic.ReturnAndFree(sb)); }
public static string UrlEncode(this string text, bool upperCase = false) { if (String.IsNullOrEmpty(text)) { return(text); } var sb = StringBuilderThreadStatic.Allocate(); var fmt = upperCase ? "X2" : "x2"; foreach (var charCode in Encoding.UTF8.GetBytes(text)) { if ( charCode >= 65 && charCode <= 90 || // A-Z charCode >= 97 && charCode <= 122 || // a-z charCode >= 48 && charCode <= 57 || // 0-9 charCode >= 44 && charCode <= 46 // ,-. ) { sb.Append((char)charCode); } else if (charCode == 32) { sb.Append('+'); } else { sb.Append('%' + charCode.ToString(fmt)); } } return(StringBuilderThreadStatic.ReturnAndFree(sb)); }
public static string ToPascalCase(this string value) { if (string.IsNullOrEmpty(value)) { return(value); } if (value.IndexOf('_') >= 0) { var parts = value.Split('_'); var sb = StringBuilderThreadStatic.Allocate(); foreach (var part in parts) { if (string.IsNullOrEmpty(part)) { continue; } var str = part.ToCamelCase(); sb.Append(char.ToUpper(str[0]) + str.SafeSubstring(1, str.Length)); } return(StringBuilderThreadStatic.ReturnAndFree(sb)); } var camelCase = value.ToCamelCase(); return(char.ToUpper(camelCase[0]) + camelCase.SafeSubstring(1, camelCase.Length)); }
public static Type GetCachedGenericType(this Type type, params Type[] argTypes) { if (!type.IsGenericTypeDefinition()) { throw new ArgumentException(type.FullName + " is not a Generic Type Definition"); } if (argTypes == null) { argTypes = TypeConstants.EmptyTypeArray; } StringBuilder sb = StringBuilderThreadStatic.Allocate().Append(type.FullName); foreach (Type argType in argTypes) { sb.Append('|').Append(argType.FullName); } string key = StringBuilderThreadStatic.ReturnAndFree(sb); Type type1; if (PlatformExtensions.GenericTypeCache.TryGetValue(key, out type1)) { return(type1); } Type type2 = type.MakeGenericType(argTypes); Dictionary <string, Type> genericTypeCache; Dictionary <string, Type> dictionary; do { genericTypeCache = PlatformExtensions.GenericTypeCache; dictionary = new Dictionary <string, Type>((IDictionary <string, Type>)PlatformExtensions.GenericTypeCache); dictionary[key] = type2; }while (Interlocked.CompareExchange <Dictionary <string, Type> >(ref PlatformExtensions.GenericTypeCache, dictionary, genericTypeCache) != genericTypeCache); return(type2); }
public static string ToLowercaseUnderscore(this string value) { if (string.IsNullOrEmpty(value)) { return(value); } value = value.ToCamelCase(); var sb = StringBuilderThreadStatic.Allocate(); foreach (var t in value) { if (char.IsDigit(t) || char.IsLetter(t) && char.IsLower(t) || t == '_') { sb.Append(t); } else { sb.Append("_"); sb.Append(char.ToLowerInvariant(t)); } } return(StringBuilderThreadStatic.ReturnAndFree(sb)); }
public static string ToWcfJsonDateTimeOffset(DateTimeOffset dateTimeOffset) { var sb = StringBuilderThreadStatic.Allocate(); using (var writer = new StringWriter(sb)) { WriteWcfJsonDateTimeOffset(writer, dateTimeOffset); return(StringBuilderThreadStatic.ReturnAndFree(sb)); } }
public static string CombineWith(this string path, params object[] thesePaths) { if (thesePaths.Length == 1 && thesePaths[0] == null) { return(path); } var sb = StringBuilderThreadStatic.Allocate(); sb.Append(path.TrimEnd('/', '\\')); AppendPaths(sb, ToStrings(thesePaths)); return(StringBuilderThreadStatic.ReturnAndFree(sb)); }
public static string Join <T>(this IEnumerable <T> values, string seperator) { var sb = StringBuilderThreadStatic.Allocate(); foreach (var value in values) { if (sb.Length > 0) { sb.Append(seperator); } sb.Append(value); } return(StringBuilderThreadStatic.ReturnAndFree(sb)); }
public static string ToXsdDuration(TimeSpan timeSpan) { var sb = StringBuilderThreadStatic.Allocate(); sb.Append(timeSpan.Ticks < 0 ? "-P" : "P"); double ticks = Math.Abs(timeSpan.Ticks); var totalSeconds = ticks / TimeSpan.TicksPerSecond; var wholeSeconds = (int)totalSeconds; var seconds = wholeSeconds; var sec = seconds >= 60 ? seconds % 60 : seconds; var min = (seconds = seconds / 60) >= 60 ? seconds % 60 : seconds; var hours = (seconds = seconds / 60) >= 24 ? seconds % 24 : seconds; var days = seconds / 24; var remainingSecs = sec + (totalSeconds - wholeSeconds); if (days > 0) { sb.Append(days + "D"); } if (days == 0 || hours + min + sec + remainingSecs > 0) { sb.Append("T"); if (hours > 0) { sb.Append(hours + "H"); } if (min > 0) { sb.Append(min + "M"); } if (remainingSecs > 0) { var secFmt = $"{remainingSecs:0.0000000}"; secFmt = secFmt.TrimEnd('0').TrimEnd('.'); sb.Append(secFmt + "S"); } else if (sb.Length == 2) { // PT sb.Append("0S"); } } return(StringBuilderThreadStatic.ReturnAndFree(sb)); }
private static string GetTypesKey(params Type[] types) { var sb = StringBuilderThreadStatic.Allocate(); foreach (var type in types) { if (sb.Length > 0) { sb.Append(">"); } sb.Append(type.FullName); } return(StringBuilderThreadStatic.ReturnAndFree(sb)); }
public static string Join <K, V>(this Dictionary <K, V> values, string itemSeperator, string keySeperator) { var sb = StringBuilderThreadStatic.Allocate(); foreach (var entry in values) { if (sb.Length > 0) { sb.Append(itemSeperator); } sb.Append(entry.Key).Append(keySeperator).Append(entry.Value); } return(StringBuilderThreadStatic.ReturnAndFree(sb)); }
public static string ToXsdDuration(TimeSpan timeSpan) { var sb = StringBuilderThreadStatic.Allocate(); sb.Append(timeSpan.Ticks < 0 ? "-P" : "P"); double ticks = Math.Abs(timeSpan.Ticks); double totalSeconds = ticks / TimeSpan.TicksPerSecond; int wholeSeconds = (int)totalSeconds; int seconds = wholeSeconds; int sec = (seconds >= 60 ? seconds % 60 : seconds); int min = (seconds = (seconds / 60)) >= 60 ? seconds % 60 : seconds; int hours = (seconds = (seconds / 60)) >= 24 ? seconds % 24 : seconds; int days = seconds / 24; double remainingSecs = sec + (totalSeconds - wholeSeconds); if (days > 0) { sb.Append(days + "D"); } if (days == 0 || hours + min + sec + remainingSecs > 0) { sb.Append("T"); if (hours > 0) { sb.Append(hours + "H"); } if (min > 0) { sb.Append(min + "M"); } if (remainingSecs > 0) { var secFmt = string.Format(CultureInfo.InvariantCulture, "{0:0.0000000}", remainingSecs); secFmt = secFmt.TrimEnd('0').TrimEnd('.'); sb.Append(secFmt + "S"); } else if (sb.Length == 2) //PT { sb.Append("0S"); } } return(StringBuilderThreadStatic.ReturnAndFree(sb)); }
internal static string Underscored(IEnumerable <char> pascalCase) { var sb = StringBuilderThreadStatic.Allocate(); var i = 0; foreach (var c in pascalCase) { if (char.IsUpper(c) && i > 0) { sb.Append("_"); } sb.Append(c); i++; } return(StringBuilderThreadStatic.ReturnAndFree(sb).ToLowerInvariant()); }
public static string AppendUrlPathsRaw(this string uri, params string[] uriComponents) { var sb = StringBuilderThreadStatic.Allocate(); sb.Append(uri.WithTrailingSlash()); var i = 0; foreach (var uriComponent in uriComponents) { if (i++ > 0) { sb.Append('/'); } sb.Append(uriComponent); } return(StringBuilderThreadStatic.ReturnAndFree(sb)); }
public static Type GetCachedGenericType(this Type type, params Type[] argTypes) { if (!type.IsGenericTypeDefinition) { throw new ArgumentException(type.FullName + " is not a Generic Type Definition"); } if (argTypes == null) { argTypes = TypeConstants.EmptyTypeArray; } var sb = StringBuilderThreadStatic.Allocate() .Append(type.FullName); foreach (var argType in argTypes) { sb.Append('|') .Append(argType.FullName); } var key = StringBuilderThreadStatic.ReturnAndFree(sb); if (GenericTypeCache.TryGetValue(key, out var genericType)) { return(genericType); } genericType = type.MakeGenericType(argTypes); Dictionary <string, Type> snapshot, newCache; do { snapshot = GenericTypeCache; newCache = new Dictionary <string, Type>(GenericTypeCache) { [key] = genericType }; } while (!ReferenceEquals( Interlocked.CompareExchange(ref GenericTypeCache, newCache, snapshot), snapshot)); return(genericType); }
public static string CombineWith(this string path, params string[] thesePaths) { if (path == null) { path = ""; } if (thesePaths.Length == 1 && thesePaths[0] == null) { return(path); } var startPath = path.Length > 1 ? path.TrimEnd('/', '\\') : path; var sb = StringBuilderThreadStatic.Allocate(); sb.Append(startPath); AppendPaths(sb, thesePaths); return(StringBuilderThreadStatic.ReturnAndFree(sb)); }
public static string Dump(this Delegate fn) { var method = fn.GetType().GetMethod("Invoke"); var sb = StringBuilderThreadStatic.Allocate(); foreach (var param in method.GetParameters()) { if (sb.Length > 0) { sb.Append(", "); } sb.AppendFormat("{0} {1}", param.ParameterType.Name, param.Name); } var methodName = fn.Method.Name; var info = $"{method.ReturnType.Name} {methodName}({StringBuilderThreadStatic.ReturnAndFree(sb)})"; return(info); }
/// <summary> /// Converts to xsdduration. /// </summary> /// <param name="timeSpan">The time span.</param> /// <returns>System.String.</returns> public static string ToXsdDuration(TimeSpan timeSpan) { if (timeSpan == TimeSpan.MinValue) { return(MinSerializedValue); } if (timeSpan == TimeSpan.MaxValue) { return(MaxSerializedValue); } var sb = StringBuilderThreadStatic.Allocate(); sb.Append(timeSpan.Ticks < 0 ? "-P" : "P"); double ticks = timeSpan.Ticks; if (ticks < 0) { ticks = -ticks; } double totalSeconds = ticks / TimeSpan.TicksPerSecond; long wholeSeconds = (long)totalSeconds; long seconds = wholeSeconds; long sec = seconds >= 60 ? seconds % 60 : seconds; long min = (seconds = seconds / 60) >= 60 ? seconds % 60 : seconds; long hours = (seconds = seconds / 60) >= 24 ? seconds % 24 : seconds; long days = seconds / 24; double remainingSecs = sec + (totalSeconds - wholeSeconds); if (days > 0) { sb.Append(days + "D"); } if (days == 0 || hours + min + sec + remainingSecs > 0) { sb.Append("T"); if (hours > 0) { sb.Append(hours + "H"); } if (min > 0) { sb.Append(min + "M"); } if (remainingSecs > 0) { var secFmt = string.Format(CultureInfo.InvariantCulture, "{0:0.0000000}", remainingSecs); secFmt = secFmt.TrimEnd('0').TrimEnd('.'); sb.Append(secFmt + "S"); } else if (sb.Length == 2) //PT { sb.Append("0S"); } } return(StringBuilderThreadStatic.ReturnAndFree(sb)); }
public static string IndentJson(this string json) { var indent = 0; var quoted = false; var sb = StringBuilderThreadStatic.Allocate(); for (var i = 0; i < json.Length; i++) { var ch = json[i]; switch (ch) { case '{': case '[': sb.Append(ch); if (!quoted) { sb.AppendLine(); times(++indent, () => sb.Append(Indent)); } break; case '}': case ']': if (!quoted) { sb.AppendLine(); times(--indent, () => sb.Append(Indent)); } sb.Append(ch); break; case '"': sb.Append(ch); var escaped = false; var index = i; while (index > 0 && json[--index] == '\\') { escaped = !escaped; } if (!escaped) { quoted = !quoted; } break; case ',': sb.Append(ch); if (!quoted) { sb.AppendLine(); times(indent, () => sb.Append(Indent)); } break; case ':': sb.Append(ch); if (!quoted) { sb.Append(" "); } break; default: sb.Append(ch); break; } } return(StringBuilderThreadStatic.ReturnAndFree(sb)); }
public static StringSegment Unescape(StringSegment input, bool removeQuotes) { var length = input.Length; int start = 0; int count = 0; var output = StringBuilderThreadStatic.Allocate(); for (; count < length;) { if (removeQuotes) { if (input.GetChar(count) == JsonUtils.QuoteChar) { if (start != count) { output.Append(input.Buffer, input.Offset + start, count - start); } count++; start = count; continue; } } if (input.GetChar(count) == JsonUtils.EscapeChar) { if (start != count) { output.Append(input.Buffer, input.Offset + start, count - start); } start = count; count++; if (count >= length) { continue; } //we will always be parsing an escaped char here var c = input.GetChar(count); switch (c) { case 'a': output.Append('\a'); count++; break; case 'b': output.Append('\b'); count++; break; case 'f': output.Append('\f'); count++; break; case 'n': output.Append('\n'); count++; break; case 'r': output.Append('\r'); count++; break; case 'v': output.Append('\v'); count++; break; case 't': output.Append('\t'); count++; break; case 'u': if (count + 4 < length) { var unicodeString = input.Substring(count + 1, 4); var unicodeIntVal = UInt32.Parse(unicodeString, NumberStyles.HexNumber); output.Append(ConvertFromUtf32((int)unicodeIntVal)); count += 5; } else { output.Append(c); } break; case 'x': if (count + 4 < length) { var unicodeString = input.Substring(count + 1, 4); var unicodeIntVal = uint.Parse(unicodeString, NumberStyles.HexNumber); output.Append(ConvertFromUtf32((int)unicodeIntVal)); count += 5; } else if (count + 2 < length) { var unicodeString = input.Substring(count + 1, 2); var unicodeIntVal = uint.Parse(unicodeString, NumberStyles.HexNumber); output.Append(ConvertFromUtf32((int)unicodeIntVal)); count += 3; } else { output.Append(input.Buffer, input.Offset + start, count - start); } break; default: output.Append(c); count++; break; } start = count; } else { count++; } } output.Append(input.Buffer, input.Offset + start, length - start); return(new StringSegment(StringBuilderThreadStatic.ReturnAndFree(output))); }
/// <summary> /// Formats the specified serialized text. /// </summary> /// <param name="serializedText">The serialized text.</param> /// <returns>System.String.</returns> public static string Format(string serializedText) { if (string.IsNullOrEmpty(serializedText)) { return(null); } var tabCount = 0; var sb = StringBuilderThreadStatic.Allocate(); var firstKeySeparator = true; var inString = false; for (var i = 0; i < serializedText.Length; i++) { var current = serializedText[i]; var previous = i - 1 >= 0 ? serializedText[i - 1] : 0; var next = i < serializedText.Length - 1 ? serializedText[i + 1] : 0; switch (current) { case JsWriter.MapStartChar: case JsWriter.ListStartChar: { if (previous == JsWriter.MapKeySeperator) { if (next == JsWriter.MapEndChar || next == JsWriter.ListEndChar) { sb.Append(current); sb.Append(serializedText[++i]); //eat next continue; } AppendTabLine(sb, tabCount); } sb.Append(current); AppendTabLine(sb, ++tabCount); firstKeySeparator = true; continue; } case JsWriter.MapEndChar: case JsWriter.ListEndChar: AppendTabLine(sb, --tabCount); sb.Append(current); firstKeySeparator = true; continue; case JsWriter.QuoteChar: sb.Append(current); inString = !inString; continue; case JsWriter.ItemSeperator when !inString: sb.Append(current); AppendTabLine(sb, tabCount); firstKeySeparator = true; continue; } sb.Append(current); if (current == JsWriter.MapKeySeperator && firstKeySeparator) { sb.Append(" "); firstKeySeparator = false; } } return(StringBuilderThreadStatic.ReturnAndFree(sb)); }
public static ReadOnlySpan <char> Unescape(ReadOnlySpan <char> input, bool removeQuotes, char quoteChar) { var length = input.Length; int start = 0; int count = 0; var output = StringBuilderThreadStatic.Allocate(); for (; count < length;) { var c = input[count]; if (removeQuotes) { if (c == quoteChar) { if (start != count) { output.Append(input.Slice(start, count - start)); } count++; start = count; continue; } } if (c == JsonUtils.EscapeChar) { if (start != count) { output.Append(input.Slice(start, count - start)); } start = count; count++; if (count >= length) { continue; } //we will always be parsing an escaped char here c = input[count]; switch (c) { case 'a': output.Append('\a'); count++; break; case 'b': output.Append('\b'); count++; break; case 'f': output.Append('\f'); count++; break; case 'n': output.Append('\n'); count++; break; case 'r': output.Append('\r'); count++; break; case 'v': output.Append('\v'); count++; break; case 't': output.Append('\t'); count++; break; case 'u': if (count + 4 < length) { var unicodeString = input.Slice(count + 1, 4); var unicodeIntVal = MemoryProvider.Instance.ParseUInt32(unicodeString, NumberStyles.HexNumber); output.Append(ConvertFromUtf32((int)unicodeIntVal)); count += 5; } else { output.Append(c); } break; case 'x': if (count + 4 < length) { var unicodeString = input.Slice(count + 1, 4); var unicodeIntVal = MemoryProvider.Instance.ParseUInt32(unicodeString, NumberStyles.HexNumber); output.Append(ConvertFromUtf32((int)unicodeIntVal)); count += 5; } else if (count + 2 < length) { var unicodeString = input.Slice(count + 1, 2); var unicodeIntVal = MemoryProvider.Instance.ParseUInt32(unicodeString, NumberStyles.HexNumber); output.Append(ConvertFromUtf32((int)unicodeIntVal)); count += 3; } else { output.Append(input.Slice(start, count - start)); } break; default: output.Append(c); count++; break; } start = count; } else { count++; } } output.Append(input.Slice(start, length - start)); return(StringBuilderThreadStatic.ReturnAndFree(output).AsSpan()); }