Beispiel #1
0
 /// <summary>
 /// Returns a character array to the pool.
 /// </summary>
 /// <param name="bufferPool">The character pool.</param>
 /// <param name="buffer">The character array should be returned.</param>
 public static void ReturnToBuffer(ICharArrayPool bufferPool, char[] buffer)
 {
     if (bufferPool != null)
     {
         bufferPool.Return(buffer);
     }
 }
Beispiel #2
0
        /// <summary>
        /// Writes the string value with special characters escaped.
        /// </summary>
        /// <param name="writer">The text writer to write the output to.</param>
        /// <param name="inputString">Input string value.</param>
        /// <param name="stringEscapeOption">The string escape option.</param>
        /// <param name="buffer">Char buffer to use for streaming data.</param>
        /// <param name="bufferPool">Array pool for renting a buffer.</param>
        internal static void WriteEscapedJsonStringValue(
            TextWriter writer,
            string inputString,
            ODataStringEscapeOption stringEscapeOption,
            Ref <char[]> buffer,
            ICharArrayPool bufferPool)
        {
            Debug.Assert(writer != null, "writer != null");
            Debug.Assert(inputString != null, "The string value must not be null.");

            int firstIndex;

            if (!JsonValueUtils.CheckIfStringHasSpecialChars(inputString, stringEscapeOption, out firstIndex))
            {
                writer.Write(inputString);
            }
            else
            {
                int inputStringLength = inputString.Length;

                Debug.Assert(firstIndex < inputStringLength, "First index of the special character should be within the string");
                buffer.Value = BufferUtils.InitializeBufferIfRequired(bufferPool, buffer.Value);
                int bufferLength = buffer.Value.Length;
                int bufferIndex  = 0;
                int currentIndex = 0;

                // Let's copy and flush strings up to the first index of the special char
                while (currentIndex < firstIndex)
                {
                    int subStrLength = firstIndex - currentIndex;

                    Debug.Assert(subStrLength > 0, "SubStrLength should be greater than 0 always");

                    // If the first index of the special character is larger than the buffer length,
                    // flush everything to the buffer first and reset the buffer to the next chunk.
                    // Otherwise copy to the buffer and go on from there.
                    if (subStrLength >= bufferLength)
                    {
                        inputString.CopyTo(currentIndex, buffer.Value, 0, bufferLength);
                        writer.Write(buffer.Value, 0, bufferLength);
                        currentIndex += bufferLength;
                    }
                    else
                    {
                        WriteSubstringToBuffer(inputString, ref currentIndex, buffer.Value, ref bufferIndex, subStrLength);
                    }
                }

                // start writing escaped strings
                WriteEscapedStringToBuffer(writer, inputString, ref currentIndex, buffer.Value, ref bufferIndex, stringEscapeOption);

                // write any remaining chars to the writer
                if (bufferIndex > 0)
                {
                    writer.Write(buffer.Value, 0, bufferIndex);
                }
            }
        }
Beispiel #3
0
        /// <summary>
        /// Checks if the buffer is not initialized and if initialized returns the same buffer or creates a new one.
        /// </summary>
        /// <param name="bufferPool">The character pool.</param>
        /// <param name="buffer">The buffer to verify</param>
        /// <returns>The initialized buffer.</returns>
        public static char[] InitializeBufferIfRequired(ICharArrayPool bufferPool, char[] buffer)
        {
            if (buffer != null)
            {
                return(buffer);
            }

            return(RentFromBuffer(bufferPool, BufferLength));
        }
Beispiel #4
0
        /// <summary>
        /// A TextWriter for writing properly escaped JSON text.
        /// </summary>
        /// <param name="textWriter">The underlying TextWriter used when writing JSON</param>
        /// <param name="buffer">Buffer used when converting binary values.</param>
        /// <param name="bufferPool">Buffer pool used for renting a buffer.</param>
        internal ODataJsonTextWriter(TextWriter textWriter, Ref <char[]> wrappedBuffer, ICharArrayPool bufferPool)
            : base(System.Globalization.CultureInfo.InvariantCulture)
        {
            ExceptionUtils.CheckArgumentNotNull(textWriter, "textWriter");

            this.textWriter    = textWriter;
            this.wrappedBuffer = wrappedBuffer;
            this.bufferPool    = bufferPool;
        }
Beispiel #5
0
 /// <summary>
 /// Dispose the writer
 /// </summary>
 public void Dispose()
 {
     if (this.ArrayPool != null && this.buffer != null)
     {
         BufferUtils.ReturnToBuffer(this.ArrayPool, this.buffer);
         this.ArrayPool = null;
         this.buffer    = null;
     }
 }
Beispiel #6
0
        /// <summary>
        /// Rents a character array from the pool.
        /// </summary>
        /// <param name="bufferPool">The character pool.</param>
        /// <param name="minSize">The min required size of the character array.</param>
        /// <returns>The character array from the pool.</returns>
        public static char[] RentFromBuffer(ICharArrayPool bufferPool, int minSize)
        {
            if (bufferPool == null)
            {
                return(new char[minSize]);
            }

            char[] buffer = bufferPool.Rent(minSize);
            return(buffer);
        }
Beispiel #7
0
        /// <summary>
        /// Returns the string value with special characters escaped.
        /// </summary>
        /// <param name="writer">The text writer to write the output to.</param>
        /// <param name="inputString">Input string value.</param>
        /// <param name="stringEscapeOption">The string escape option.</param>
        /// <param name="buffer">Char buffer to use for streaming data</param>
        /// <param name="bufferPool">Array pool for renting a buffer.</param>
        internal static void WriteEscapedJsonString(
            TextWriter writer,
            string inputString,
            ODataStringEscapeOption stringEscapeOption,
            Ref <char[]> buffer,
            ICharArrayPool bufferPool = null)
        {
            Debug.Assert(writer != null, "writer != null");
            Debug.Assert(inputString != null, "The string value must not be null.");

            writer.Write(JsonConstants.QuoteCharacter);
            WriteEscapedJsonStringValue(writer, inputString, stringEscapeOption, buffer, bufferPool);
            writer.Write(JsonConstants.QuoteCharacter);
        }
Beispiel #8
0
        /// <summary>
        /// Rents a character array from the pool.
        /// </summary>
        /// <param name="bufferPool">The character pool.</param>
        /// <param name="minSize">The min required size of the character array.</param>
        /// <returns>The character array from the pool.</returns>
        public static char[] RentFromBuffer(ICharArrayPool bufferPool, int minSize)
        {
            if (bufferPool == null)
            {
                return(new char[minSize]);
            }

            char[] buffer = bufferPool.Rent(minSize);
            if (buffer == null || buffer.Length < minSize)
            {
                throw new ODataException(Strings.BufferUtils_InvalidBufferOrSize(minSize));
            }

            return(buffer);
        }
Beispiel #9
0
        /// <summary>
        /// Returns the string value with special characters escaped.
        /// </summary>
        /// <param name="writer">The text writer to write the output to.</param>
        /// <param name="inputString">Input string value.</param>
        /// <param name="stringEscapeOption">The string escape option.</param>
        /// <param name="buffer">Char buffer to use for streaming data.</param>
        /// <param name="bufferPool">Array pool for renting a buffer.</param>
        internal static async Task WriteEscapedJsonStringAsync(
            this TextWriter writer,
            string inputString,
            ODataStringEscapeOption stringEscapeOption,
            Ref <char[]> buffer,
            ICharArrayPool bufferPool = null)
        {
            Debug.Assert(writer != null, "writer != null");
            Debug.Assert(inputString != null, "The string value must not be null.");

            await writer.WriteAsync(JsonConstants.QuoteCharacter).ConfigureAwait(false);

            await writer.WriteEscapedJsonStringValueAsync(inputString, stringEscapeOption, buffer, bufferPool).ConfigureAwait(false);

            await writer.WriteAsync(JsonConstants.QuoteCharacter).ConfigureAwait(false);
        }
Beispiel #10
0
        /// <summary>
        /// Write a string value.
        /// </summary>
        /// <param name="writer">The text writer to write the output to.</param>
        /// <param name="value">String value to be written.</param>
        /// <param name="stringEscapeOption">The string escape option.</param>
        /// <param name="buffer">Char buffer to use for streaming data.</param>
        /// <param name="arrayPool">Array pool for renting a buffer.</param>
        internal static Task WriteValueAsync(
            this TextWriter writer,
            string value,
            ODataStringEscapeOption stringEscapeOption,
            Ref <char[]> buffer,
            ICharArrayPool arrayPool = null)
        {
            Debug.Assert(writer != null, "writer != null");

            if (value == null)
            {
                return(writer.WriteAsync(JsonConstants.JsonNullLiteral));
            }
            else
            {
                return(writer.WriteEscapedJsonStringAsync(value, stringEscapeOption, buffer, arrayPool));
            }
        }
Beispiel #11
0
        /// <summary>
        /// Write a string value.
        /// </summary>
        /// <param name="writer">The text writer to write the output to.</param>
        /// <param name="value">String value to be written.</param>
        /// <param name="stringEscapeOption">The string escape option.</param>
        /// <param name="buffer">Char buffer to use for streaming data.</param>
        /// <param name="arrayPool">Array pool for renting a buffer.</param>
        internal static void WriteValue(
            TextWriter writer,
            string value,
            ODataStringEscapeOption stringEscapeOption,
            Ref <char[]> buffer,
            ICharArrayPool arrayPool = null)
        {
            Debug.Assert(writer != null, "writer != null");

            if (value == null)
            {
                writer.Write(JsonConstants.JsonNullLiteral);
            }
            else
            {
                JsonValueUtils.WriteEscapedJsonString(writer, value, stringEscapeOption, buffer, arrayPool);
            }
        }
Beispiel #12
0
        /// <summary>
        /// Escapes and writes a character array to a writer.
        /// </summary>
        /// <param name="writer">The text writer to write the output to.</param>
        /// <param name="inputArray">Character array to write.</param>
        /// <param name="inputArrayOffset">How many characters to skip in the input array.</param>
        /// <param name="inputArrayCount">How many characters to write from the input array.</param>
        /// <param name="stringEscapeOption">The string escape option.</param>
        /// <param name="buffer">Char buffer to use for streaming data.</param>
        /// <param name="bufferPool">Character buffer pool.</param>
        internal static void WriteEscapedCharArray(
            TextWriter writer,
            char[] inputArray,
            int inputArrayOffset,
            int inputArrayCount,
            ODataStringEscapeOption stringEscapeOption,
            Ref <char[]> buffer, ICharArrayPool bufferPool)
        {
            int bufferIndex = 0;

            buffer.Value = BufferUtils.InitializeBufferIfRequired(bufferPool, buffer.Value);

            WriteEscapedCharArrayToBuffer(writer, inputArray, ref inputArrayOffset, inputArrayCount, buffer.Value, ref bufferIndex, stringEscapeOption);

            // write remaining bytes in buffer
            if (bufferIndex > 0)
            {
                writer.Write(buffer.Value, 0, bufferIndex);
            }
        }
Beispiel #13
0
        /// <summary>
        /// Escapes and writes a character array to a writer.
        /// </summary>
        /// <param name="writer">The text writer to write the output to.</param>
        /// <param name="inputArray">Character array to write.</param>
        /// <param name="inputArrayOffset">How many characters to skip in the input array.</param>
        /// <param name="inputArrayCount">How many characters to write from the input array.</param>
        /// <param name="stringEscapeOption">The string escape option.</param>
        /// <param name="buffer">Char buffer to use for streaming data.</param>
        /// <param name="bufferPool">Character buffer pool.</param>
        internal static async Task WriteEscapedCharArrayAsync(
            this TextWriter writer,
            char[] inputArray,
            int inputArrayOffset,
            int inputArrayCount,
            ODataStringEscapeOption stringEscapeOption,
            Ref <char[]> buffer,
            ICharArrayPool bufferPool)
        {
            int bufferIndex = 0;

            buffer.Value = BufferUtils.InitializeBufferIfRequired(bufferPool, buffer.Value);

            WriteEscapedCharArrayToBuffer(writer, inputArray, ref inputArrayOffset, inputArrayCount, buffer.Value, ref bufferIndex, stringEscapeOption);

            // write remaining bytes in buffer
            if (bufferIndex > 0)
            {
                await writer.WriteAsync(buffer.Value, 0, bufferIndex).ConfigureAwait(false);
            }
        }
 /// <summary>
 /// Constructor.
 /// </summary>
 /// <param name="writer">A Textwriter for writing to the stream.</param>
 /// <param name="streamingBuffer">A temporary buffer to use when converting binary values.</param>
 /// <param name="bufferPool">Array pool for renting a buffer.</param>
 public ODataBinaryStreamWriter(TextWriter writer, Ref <char[]> wrappedBuffer, ICharArrayPool bufferPool)
 {
     this.Writer        = writer;
     this.wrappedBuffer = wrappedBuffer;
     this.bufferPool    = bufferPool;
 }
Beispiel #15
0
        /// <summary>
        /// Write a byte array.
        /// </summary>
        /// <param name="writer">The text writer to write the output to.</param>
        /// <param name="value">Byte array to be written.</param>
        /// <param name="buffer">Char buffer to use for streaming data.</param>
        /// <param name="arrayPool">Array pool for renting a buffer.</param>
        internal static async Task WriteBinaryStringAsync(this TextWriter writer, byte[] value, Ref <char[]> buffer, ICharArrayPool arrayPool)
        {
            Debug.Assert(writer != null, "writer != null");
            Debug.Assert(value != null, "The value must not be null.");

            buffer.Value = BufferUtils.InitializeBufferIfRequired(arrayPool, buffer.Value);
            Debug.Assert(buffer.Value != null);

            int bufferLength = buffer.Value.Length;

            // Try to hold base64 string as much as possible in one converting.
            int bufferByteSize = bufferLength * 3 / 4;

            for (int offsetIn = 0; offsetIn < value.Length; offsetIn += bufferByteSize)
            {
                int count = WriteByteArrayToBuffer(value, offsetIn, buffer.Value, bufferByteSize);
                await writer.WriteAsync(buffer.Value, 0, count).ConfigureAwait(false);
            }
        }
Beispiel #16
0
        /// <summary>
        /// Escapes and writes a character array to a writer.
        /// </summary>
        /// <param name="writer">The text writer to write the output to.</param>
        /// <param name="inputArray">Character array to write.</param>
        /// <param name="inputArrayOffset">How many characters to skip in the input array.</param>
        /// <param name="inputArrayCount">How many characters to write from the input array.</param>
        /// <param name="stringEscapeOption">The string escape option.</param>
        /// <param name="buffer">Char buffer to use for streaming data.</param>
        /// <param name="bufferPool">Character buffer pool.</param>
        internal static void WriteEscapedCharArray(TextWriter writer, char[] inputArray, int inputArrayOffset, int inputArrayCount, ODataStringEscapeOption stringEscapeOption, ref char[] buffer, ICharArrayPool bufferPool)
        {
            int bufferIndex = 0;

            buffer = BufferUtils.InitializeBufferIfRequired(bufferPool, buffer);

            for (; inputArrayOffset < inputArrayCount; inputArrayOffset++)
            {
                bufferIndex = EscapeAndWriteCharToBuffer(writer, inputArray[inputArrayOffset], buffer, bufferIndex, stringEscapeOption);
            }

            // write remaining bytes in buffer
            if (bufferIndex > 0)
            {
                writer.Write(buffer, 0, bufferIndex);
            }
        }
Beispiel #17
0
        /// <summary>
        /// Write a byte array.
        /// </summary>
        /// <param name="writer">The text writer to write the output to.</param>
        /// <param name="value">Byte array to be written.</param>
        /// <param name="buffer">Char buffer to use for streaming data.</param>
        /// <param name="arrayPool">Array pool for renting a buffer.</param>
        internal static async Task WriteValueAsync(this TextWriter writer, byte[] value, Ref <char[]> buffer, ICharArrayPool arrayPool = null)
        {
            Debug.Assert(writer != null, "writer != null");

            if (value == null)
            {
                await writer.WriteAsync(JsonConstants.JsonNullLiteral).ConfigureAwait(false);
            }
            else
            {
                await writer.WriteAsync(JsonConstants.QuoteCharacter).ConfigureAwait(false);

                await writer.WriteBinaryStringAsync(value, buffer, arrayPool).ConfigureAwait(false);

                await writer.WriteAsync(JsonConstants.QuoteCharacter).ConfigureAwait(false);
            }
        }
Beispiel #18
0
        /// <summary>
        /// Write a byte array.
        /// </summary>
        /// <param name="writer">The text writer to write the output to.</param>
        /// <param name="value">Byte array to be written.</param>
        /// <param name="buffer">Char buffer to use for streaming data.</param>
        internal static void WriteValue(TextWriter writer, byte[] value, ref char[] buffer, ICharArrayPool arrayPool = null)
        {
            Debug.Assert(writer != null, "writer != null");

            if (value == null)
            {
                writer.Write(JsonConstants.JsonNullLiteral);
            }
            else
            {
                writer.Write(JsonConstants.QuoteCharacter);
                WriteBinaryString(writer, value, ref buffer, arrayPool);
                writer.Write(JsonConstants.QuoteCharacter);
            }
        }
Beispiel #19
0
 /// <summary>
 /// Constructor.
 /// </summary>
 /// <param name="writer">A Textwriter for writing to the stream.</param>
 /// <param name="streamingBuffer">A temporary buffer to use when converting binary values.</param>
 /// <param name="bufferPool">Array pool for renting a buffer.</param>
 public ODataBinaryStreamWriter(TextWriter writer, ref char[] streamingBuffer, ICharArrayPool bufferPool)
 {
     this.Writer          = writer;
     this.streamingBuffer = streamingBuffer;
     this.bufferPool      = bufferPool;
 }
Beispiel #20
0
        /// <summary>
        /// Write a byte array.
        /// </summary>
        /// <param name="writer">The text writer to write the output to.</param>
        /// <param name="value">Byte array to be written.</param>
        /// <param name="buffer">Char buffer to use for streaming data.</param>
        internal static void WriteBinaryString(TextWriter writer, byte[] value, ref char[] buffer, ICharArrayPool arrayPool)
        {
            Debug.Assert(writer != null, "writer != null");
            Debug.Assert(value != null, "The value must not be null.");

            buffer = BufferUtils.InitializeBufferIfRequired(arrayPool, buffer);
            Debug.Assert(buffer != null);

            int bufferLength = buffer.Length;

            // Try to hold base64 string as much as possible in one converting.
            int bufferByteSize = bufferLength * 3 / 4;

            for (int offsetIn = 0; offsetIn < value.Length; offsetIn += bufferByteSize)
            {
                int length = bufferByteSize;
                if (offsetIn + length > value.Length)
                {
                    length = value.Length - offsetIn;
                }

                int output = Convert.ToBase64CharArray(value, offsetIn, length, buffer, 0);
                writer.Write(buffer, 0, output);
            }
        }
Beispiel #21
0
        /// <summary>
        /// Returns the string value with special characters escaped.
        /// </summary>
        /// <param name="writer">The text writer to write the output to.</param>
        /// <param name="inputString">Input string value.</param>
        /// <param name="stringEscapeOption">The string escape option.</param>
        /// <param name="buffer">Char buffer to use for streaming data</param>
        internal static void WriteEscapedJsonString(TextWriter writer, string inputString,
                                                    ODataStringEscapeOption stringEscapeOption, ref char[] buffer, ICharArrayPool bufferPool = null)
        {
            Debug.Assert(writer != null, "writer != null");
            Debug.Assert(inputString != null, "The string value must not be null.");

            writer.Write(JsonConstants.QuoteCharacter);

            int firstIndex;

            if (!JsonValueUtils.CheckIfStringHasSpecialChars(inputString, stringEscapeOption, out firstIndex))
            {
                writer.Write(inputString);
            }
            else
            {
                int inputStringLength = inputString.Length;

                Debug.Assert(firstIndex < inputStringLength, "First index of the special character should be within the string");
                buffer = BufferUtils.InitializeBufferIfRequired(bufferPool, buffer);
                int bufferLength = buffer.Length;
                int bufferIndex  = 0;
                int currentIndex = 0;

                // Let's copy and flush strings up to the first index of the special char
                while (currentIndex < firstIndex)
                {
                    int subStrLength = firstIndex - currentIndex;

                    Debug.Assert(subStrLength > 0, "SubStrLength should be greater than 0 always");

                    // If the first index of the special character is larger than the buffer length,
                    // flush everything to the buffer first and reset the buffer to the next chunk.
                    // Otherwise copy to the buffer and go on from there.
                    if (subStrLength >= bufferLength)
                    {
                        inputString.CopyTo(currentIndex, buffer, 0, bufferLength);
                        writer.Write(buffer, 0, bufferLength);
                        currentIndex += bufferLength;
                    }
                    else
                    {
                        inputString.CopyTo(currentIndex, buffer, 0, subStrLength);
                        bufferIndex   = subStrLength;
                        currentIndex += subStrLength;
                    }
                }

                for (; currentIndex < inputStringLength; currentIndex++)
                {
                    char   c             = inputString[currentIndex];
                    string escapedString = null;

                    if (stringEscapeOption == ODataStringEscapeOption.EscapeNonAscii || c <= 0x7F)
                    {
                        escapedString = JsonValueUtils.SpecialCharToEscapedStringMap[c];
                    }

                    // Append the unhandled characters (that do not require special treament)
                    // to the buffer.
                    if (escapedString == null)
                    {
                        buffer[bufferIndex] = c;
                        bufferIndex++;
                    }
                    else
                    {
                        // Okay, an unhandled character was deteced.
                        // First lets check if we can fit it in the existing buffer, if not,
                        // flush the current buffer and reset. Add the escaped string to the buffer
                        // and continue.
                        int escapedStringLength = escapedString.Length;
                        Debug.Assert(escapedStringLength <= bufferLength, "Buffer should be larger than the escaped string");

                        if ((bufferIndex + escapedStringLength) > bufferLength)
                        {
                            writer.Write(buffer, 0, bufferIndex);
                            bufferIndex = 0;
                        }

                        escapedString.CopyTo(0, buffer, bufferIndex, escapedStringLength);
                        bufferIndex += escapedStringLength;
                    }

                    if (bufferIndex >= bufferLength)
                    {
                        Debug.Assert(bufferIndex == bufferLength,
                                     "We should never encounter a situation where the buffer index is greater than the buffer length");
                        writer.Write(buffer, 0, bufferIndex);
                        bufferIndex = 0;
                    }
                }

                if (bufferIndex > 0)
                {
                    writer.Write(buffer, 0, bufferIndex);
                }
            }

            writer.Write(JsonConstants.QuoteCharacter);
        }