Exemplo n.º 1
0
        public static string CombinePaths(params string[] paths)
        {
            var sb = StringBuilderThreadStatic.Allocate();

            AppendPaths(sb, paths);
            return(StringBuilderThreadStatic.ReturnAndFree(sb));
        }
Exemplo n.º 2
0
        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));
        }
Exemplo n.º 3
0
        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));
        }
Exemplo n.º 4
0
        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));
        }
Exemplo n.º 5
0
        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));
        }
Exemplo n.º 6
0
        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);
        }
Exemplo n.º 7
0
        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));
        }
Exemplo n.º 8
0
        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));
        }
Exemplo n.º 9
0
        public static string ToWcfJsonDateTimeOffset(DateTimeOffset dateTimeOffset)
        {
            var sb = StringBuilderThreadStatic.Allocate();

            using (var writer = new StringWriter(sb))
            {
                WriteWcfJsonDateTimeOffset(writer, dateTimeOffset);
                return(StringBuilderThreadStatic.ReturnAndFree(sb));
            }
        }
Exemplo n.º 10
0
        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));
        }
Exemplo n.º 11
0
        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));
        }
Exemplo n.º 12
0
        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));
        }
        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));
        }
Exemplo n.º 14
0
        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));
        }
Exemplo n.º 15
0
        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));
        }
Exemplo n.º 16
0
        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());
        }
Exemplo n.º 17
0
        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));
        }
Exemplo n.º 18
0
        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);
        }
Exemplo n.º 19
0
        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));
        }
Exemplo n.º 20
0
        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);
        }
Exemplo n.º 21
0
    /// <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));
    }
Exemplo n.º 22
0
        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());
        }
Exemplo n.º 23
0
        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));
        }
Exemplo n.º 24
0
        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)));
        }
Exemplo n.º 25
0
    /// <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));
    }