private static async Task WriteDefinitelyEscapedJavaScriptStringWithoutDelimitersAsync(
            TextWriter writer, string s, int lastWritePosition, bool[] charEscapeFlags,
            StringEscapeHandling stringEscapeHandling, JsonTextWriter client, char[] writeBuffer,
            CancellationToken cancellationToken)
        {
            if (writeBuffer == null || writeBuffer.Length < lastWritePosition)
            {
                writeBuffer = client.EnsureWriteBuffer(lastWritePosition, UnicodeTextLength);
            }

            if (lastWritePosition != 0)
            {
                s.CopyTo(0, writeBuffer, 0, lastWritePosition);

                // write unchanged chars at start of text.
                await writer.WriteAsync(writeBuffer, 0, lastWritePosition, cancellationToken).ConfigureAwait(false);
            }

            int    length;
            bool   isEscapedUnicodeText = false;
            string?escapedValue         = null;

            for (int i = lastWritePosition; i < s.Length; i++)
            {
                char c = s[i];

                if (c < charEscapeFlags.Length && !charEscapeFlags[c])
                {
                    continue;
                }

                switch (c)
                {
                case '\t':
                    escapedValue = @"\t";
                    break;

                case '\n':
                    escapedValue = @"\n";
                    break;

                case '\r':
                    escapedValue = @"\r";
                    break;

                case '\f':
                    escapedValue = @"\f";
                    break;

                case '\b':
                    escapedValue = @"\b";
                    break;

                case '\\':
                    escapedValue = @"\\";
                    break;

                case '\u0085':     // Next Line
                    escapedValue = @"\u0085";
                    break;

                case '\u2028':     // Line Separator
                    escapedValue = @"\u2028";
                    break;

                case '\u2029':     // Paragraph Separator
                    escapedValue = @"\u2029";
                    break;

                default:
                    if (c < charEscapeFlags.Length || stringEscapeHandling == StringEscapeHandling.EscapeNonAscii)
                    {
                        if (c == '\'' && stringEscapeHandling != StringEscapeHandling.EscapeHtml)
                        {
                            escapedValue = @"\'";
                        }
                        else if (c == '"' && stringEscapeHandling != StringEscapeHandling.EscapeHtml)
                        {
                            escapedValue = @"\""";
                        }
                        else
                        {
                            if (writeBuffer.Length < UnicodeTextLength)
                            {
                                writeBuffer = client.EnsureWriteBuffer(UnicodeTextLength, 0);
                            }

                            StringUtils.ToCharAsUnicode(c, writeBuffer);

                            isEscapedUnicodeText = true;
                        }
                    }
                    else
                    {
                        continue;
                    }
                    break;
                }

                if (i > lastWritePosition)
                {
                    length = i - lastWritePosition + (isEscapedUnicodeText ? UnicodeTextLength : 0);
                    int start = isEscapedUnicodeText ? UnicodeTextLength : 0;

                    if (writeBuffer.Length < length)
                    {
                        writeBuffer = client.EnsureWriteBuffer(length, UnicodeTextLength);
                    }

                    s.CopyTo(lastWritePosition, writeBuffer, start, length - start);

                    // write unchanged chars before writing escaped text
                    await writer.WriteAsync(writeBuffer, start, length - start, cancellationToken).ConfigureAwait(false);
                }

                lastWritePosition = i + 1;
                if (!isEscapedUnicodeText)
                {
                    await writer.WriteAsync(escapedValue !, cancellationToken).ConfigureAwait(false);
                }
                else
                {
                    await writer.WriteAsync(writeBuffer, 0, UnicodeTextLength, cancellationToken).ConfigureAwait(false);

                    isEscapedUnicodeText = false;
                }
            }

            length = s.Length - lastWritePosition;

            if (length != 0)
            {
                if (writeBuffer.Length < length)
                {
                    writeBuffer = client.EnsureWriteBuffer(length, 0);
                }

                s.CopyTo(lastWritePosition, writeBuffer, 0, length);

                // write remaining text
                await writer.WriteAsync(writeBuffer, 0, length, cancellationToken).ConfigureAwait(false);
            }
        }
Beispiel #2
0
        private static async Task WriteDefinitelyEscapedJavaScriptStringWithoutDelimitersAsync(TextWriter writer, string s, int lastWritePosition, bool[] charEscapeFlags, StringEscapeHandling stringEscapeHandling, JsonTextWriter client, char[] writeBuffer, CancellationToken cancellationToken)
        {
            int length;
            ConfiguredTaskAwaitable configuredTaskAwaitable;
            char chr;

            if (writeBuffer == null || (int)writeBuffer.Length < lastWritePosition)
            {
                writeBuffer = client.EnsureWriteBuffer(lastWritePosition, 6);
            }
            if (lastWritePosition != 0)
            {
                s.CopyTo(0, writeBuffer, 0, lastWritePosition);
                configuredTaskAwaitable = writer.WriteAsync(writeBuffer, 0, lastWritePosition, cancellationToken).ConfigureAwait(false);
                await configuredTaskAwaitable;
            }
            bool   flag = false;
            string str  = null;

            for (int i = lastWritePosition; i < s.Length; i++)
            {
                chr = s[i];
                if (chr >= (char)((int)charEscapeFlags.Length) || charEscapeFlags[chr])
                {
                    if (chr <= '\\')
                    {
                        switch (chr)
                        {
                        case '\b':
                        {
                            str = "\\b";
                            break;
                        }

                        case '\t':
                        {
                            str = "\\t";
                            break;
                        }

                        case '\n':
                        {
                            str = "\\n";
                            break;
                        }

                        case '\v':
                        {
                            goto Label0;
                        }

                        case '\f':
                        {
                            str = "\\f";
                            break;
                        }

                        case '\r':
                        {
                            str = "\\r";
                            break;
                        }

                        default:
                        {
                            if (chr == '\\')
                            {
                                str = "\\\\";
                                break;
                            }
                            else
                            {
                                goto Label0;
                            }
                        }
                        }
                    }
                    else if (chr == '\u0085')
                    {
                        str = "\\u0085";
                    }
                    else if (chr == '\u2028')
                    {
                        str = "\\u2028";
                    }
                    else
                    {
                        if (chr != '\u2029')
                        {
                            goto Label0;
                        }
                        str = "\\u2029";
                    }
Label2:
                    if (i > lastWritePosition)
                    {
                        int num = i - lastWritePosition;
                        length = num + (flag ? 6 : 0);
                        int num1 = (flag ? 6 : 0);
                        if ((int)writeBuffer.Length < length)
                        {
                            writeBuffer = client.EnsureWriteBuffer(length, 6);
                        }
                        s.CopyTo(lastWritePosition, writeBuffer, num1, length - num1);
                        configuredTaskAwaitable = writer.WriteAsync(writeBuffer, num1, length - num1, cancellationToken).ConfigureAwait(false);
                        await configuredTaskAwaitable;
                    }
                    lastWritePosition = i + 1;
                    if (flag)
                    {
                        configuredTaskAwaitable = writer.WriteAsync(writeBuffer, 0, 6, cancellationToken).ConfigureAwait(false);
                        await configuredTaskAwaitable;
                        flag = false;
                    }
                    else
                    {
                        configuredTaskAwaitable = writer.WriteAsync(str, cancellationToken).ConfigureAwait(false);
                        await configuredTaskAwaitable;
                    }
                }
Label1:
            }
            length = s.Length - lastWritePosition;
            if (length != 0)
            {
                if ((int)writeBuffer.Length < length)
                {
                    writeBuffer = client.EnsureWriteBuffer(length, 0);
                }
                s.CopyTo(lastWritePosition, writeBuffer, 0, length);
                configuredTaskAwaitable = writer.WriteAsync(writeBuffer, 0, length, cancellationToken).ConfigureAwait(false);
                await configuredTaskAwaitable;
            }
            return;

Label0:
            if (chr >= (char)((int)charEscapeFlags.Length) && stringEscapeHandling != StringEscapeHandling.EscapeNonAscii)
            {
                goto Label1;
            }
            if (chr == '\'' && stringEscapeHandling != StringEscapeHandling.EscapeHtml)
            {
                str = "\\'";
                goto Label2;
            }
            else if (chr != '\"' || stringEscapeHandling == StringEscapeHandling.EscapeHtml)
            {
                if ((int)writeBuffer.Length < 6)
                {
                    writeBuffer = client.EnsureWriteBuffer(6, 0);
                }
                StringUtils.ToCharAsUnicode(chr, writeBuffer);
                flag = true;
                goto Label2;
            }
            else
            {
                str = "\\\"";
                goto Label2;
            }
        }