public static void WriteEscapedJavaScriptString(TextWriter writer, string s, char delimiter, bool appendDelimiters,
                                                        bool[] charEscapeFlags, StringEscapeHandling stringEscapeHandling, IArrayPool <char> bufferPool, ref char[] writeBuffer)
        {
            // leading delimiter
            if (appendDelimiters)
            {
                writer.Write(delimiter);
            }

            if (s != null)
            {
                int lastWritePosition = 0;

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

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

                    string escapedValue;

                    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 == null || writeBuffer.Length < UnicodeTextLength)
                                {
                                    writeBuffer = BufferUtils.EnsureBufferSize(bufferPool, UnicodeTextLength, writeBuffer);
                                }

                                StringUtils.ToCharAsUnicode(c, writeBuffer);

                                // slightly hacky but it saves multiple conditions in if test
                                escapedValue = EscapedUnicodeText;
                            }
                        }
                        else
                        {
                            escapedValue = null;
                        }
                        break;
                    }

                    if (escapedValue == null)
                    {
                        continue;
                    }

                    bool isEscapedUnicodeText = string.Equals(escapedValue, EscapedUnicodeText);

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

                        if (writeBuffer == null || writeBuffer.Length < length)
                        {
                            char[] newBuffer = BufferUtils.RentBuffer(bufferPool, length);

                            // the unicode text is already in the buffer
                            // copy it over when creating new buffer
                            if (isEscapedUnicodeText)
                            {
                                Array.Copy(writeBuffer, newBuffer, UnicodeTextLength);
                            }

                            BufferUtils.ReturnBuffer(bufferPool, writeBuffer);

                            writeBuffer = newBuffer;
                        }

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

                        // write unchanged chars before writing escaped text
                        writer.Write(writeBuffer, start, length - start);
                    }

                    lastWritePosition = i + 1;
                    if (!isEscapedUnicodeText)
                    {
                        writer.Write(escapedValue);
                    }
                    else
                    {
                        writer.Write(writeBuffer, 0, UnicodeTextLength);
                    }
                }

                if (lastWritePosition == 0)
                {
                    // no escaped text, write entire string
                    writer.Write(s);
                }
                else
                {
                    int length = s.Length - lastWritePosition;

                    if (writeBuffer == null || writeBuffer.Length < length)
                    {
                        writeBuffer = BufferUtils.EnsureBufferSize(bufferPool, length, writeBuffer);
                    }

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

                    // write remaining text
                    writer.Write(writeBuffer, 0, length);
                }
            }

            // trailing delimiter
            if (appendDelimiters)
            {
                writer.Write(delimiter);
            }
        }
 public StringBuffer(IArrayPool <char> bufferPool, int initalSize) : this(BufferUtils.RentBuffer(bufferPool, initalSize))
 {
 }