JsonReader.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ Dotnetfx_Vista_SP2 / Dotnetfx_Vista_SP2 / 8.0.50727.4016 / DEVDIV / depot / DevDiv / releases / Orcas / QFE / ndp / fx / src / DataWeb / Server / System / Data / Services / Serializers / JsonReader.cs / 2 / JsonReader.cs

                            //---------------------------------------------------------------------- 
// 
//      Copyright (c) Microsoft Corporation.  All rights reserved.
// 
//  
//      Provides a reader implementaion for Json format
//  
// 
// @owner  [....]
//--------------------------------------------------------------------- 

namespace System.Data.Services.Serializers
{
    using System; 
    using System.Collections;
    using System.Diagnostics; 
    using System.Globalization; 
    using System.IO;
    using System.Text; 
    using System.Text.RegularExpressions;

    /// Json text reader.
    internal sealed class JsonReader : IDisposable 
    {
        /// Compiled Regex for DateTime Format. 
        private static readonly Regex DateTimeFormat = new Regex(@"^/Date\((?-?[0-9]+)\)/", RegexOptions.Compiled); 

        /// Maximum recursion limit on reader. 
        private const int RecursionLimit = 200;

        ///  Reader to reader text into 
        private readonly TextReader reader; 

        /// Depth of recursion. 
        private int recursionDepth; 

        ///  
        /// Creates a new instance of Json reader which readers the json text
        /// from the given reader
        /// 
        /// text reader from which json payload needs to be readS 
        public JsonReader(TextReader reader)
        { 
            Debug.Assert(reader != null, "reader != null"); 
            this.reader = reader;
        } 

        /// Releases resources held onto by this object.
        public void Dispose()
        { 
            this.reader.Dispose();
        } 
 
        /// 
        /// Converts the given value into the right type 
        /// 
        /// returns the clr object instance which 
        public object ReadValue()
        { 
            this.RecurseEnter();
 
            object value = null; 
            bool allowNull = false;
 
            char ch = this.PeekNextSignificantCharacter();
            if (ch == '[')
            {
                value = this.ReadArray(); 
            }
            else if (ch == '{') 
            { 
                value = this.ReadObject();
            } 
            else if ((ch == '\'') || (ch == '"'))
            {
                bool hasLeadingSlash;
                string s = this.ReadString(out hasLeadingSlash); 
                value = s; // may be overwritten with a DateTime if ends up being a date/time
 
                // Atlas format for date/time 
                if (hasLeadingSlash)
                { 
                    Match match = DateTimeFormat.Match(s);
                    if (match.Success)
                    {
                        string ticksStr = match.Groups["ticks"].Value; 

                        long ticks; 
                        if (long.TryParse(ticksStr, NumberStyles.Integer, NumberFormatInfo.InvariantInfo, out ticks)) 
                        {
                            // The javascript ticks start from 1/1/1970 but FX DateTime ticks start from 1/1/0001 
                            DateTime dateTime = new DateTime(ticks * 10000 + JsonWriter.DatetimeMinTimeTicks, DateTimeKind.Utc);
                            value = dateTime;
                        }
                    } 
                }
            } 
            else if (Char.IsDigit(ch) || (ch == '-') || (ch == '.')) 
            {
                value = this.ReadNumber(); 
            }
            else if ((ch == 't') || (ch == 'f'))
            {
                value = this.ReadBoolean(); 
            }
            else if (ch == 'n') 
            { 
                this.ReadNull();
                allowNull = true; 
            }

            if ((value == null) && (allowNull == false))
            { 
                throw DataServiceException.CreateBadRequestError(Strings.BadRequestStream_InvalidContent);
            } 
 
            this.RecurseLeave();
            return value; 
        }

        /// 
        /// Gets the next character from the reader. This function moves the enumerator by 1 position 
        /// 
        /// the next charater from the current reader position 
        private char ReadNextCharacter() 
        {
            int result = this.reader.Read(); 
            if (result < 0)
            {
                throw DataServiceException.CreateBadRequestError(Strings.BadRequestStream_InvalidContent);
            } 

            Debug.Assert(result <= char.MaxValue, "result <= char.MaxValue"); 
            return (char)result; 
        }
 
        /// 
        /// peeks the next character from the reader. This does not move the current reader position.
        /// 
        /// the next character from the current reader position 
        private char PeekNextCharacter()
        { 
            int result = this.reader.Peek(); 
            if (result < 0)
            { 
                return '\0';
            }

            Debug.Assert(result <= char.MaxValue, "result <= char.MaxValue"); 
            return (char)result;
        } 
 
        /// 
        /// Returns the next count characters from the reader's current position 
        /// 
        /// number of characters to return
        /// string consisting of next count characters
        private string GetCharacters(int count) 
        {
            StringBuilder stringBuilder = new StringBuilder(); 
            for (int i = 0; i < count; i++) 
            {
                char ch = this.ReadNextCharacter(); 
                stringBuilder.Append(ch);
            }

            return stringBuilder.ToString(); 
        }
 
        ///  
        /// Sets the readers position to the next significant character position
        ///  
        /// returns the next significant character without changing the current position of the reader
        private char PeekNextSignificantCharacter()
        {
            char ch = this.PeekNextCharacter(); 
            while ((ch != '\0') && Char.IsWhiteSpace(ch))
            { 
                this.ReadNextCharacter(); 
                ch = this.PeekNextCharacter();
            } 

            return ch;
        }
 
        /// 
        /// Converts the given text into an arrayList 
        ///  
        /// returns the arraylist containing the list of objects
        private ArrayList ReadArray() 
        {
            ArrayList array = new ArrayList();

            // Consume the '[' 
            this.ReadNextCharacter();
 
            while (true) 
            {
                char ch = this.PeekNextSignificantCharacter(); 
                if (ch == '\0')
                {
                    throw DataServiceException.CreateBadRequestError(Strings.BadRequestStream_InvalidContent);
                } 

                if (ch == ']') 
                { 
                    this.ReadNextCharacter();
                    return array; 
                }

                if (array.Count != 0)
                { 
                    if (ch != ',')
                    { 
                        throw DataServiceException.CreateBadRequestError(Strings.BadRequestStream_MissingArrayMemberSeperator); 
                    }
                    else 
                    {
                        this.ReadNextCharacter();
                    }
                } 

                object item = this.ReadValue(); 
                array.Add(item); 
            }
        } 

        /// 
        /// Reads the boolean value
        ///  
        /// returns the boolean value as read from the reader
        private bool ReadBoolean() 
        { 
            string s = this.ReadName(/* allowQuotes */ false);
 
            if (s != null)
            {
                if (s.Equals(XmlConstants.XmlTrueLiteral, StringComparison.Ordinal))
                { 
                    return true;
                } 
                else if (s.Equals(XmlConstants.XmlFalseLiteral, StringComparison.Ordinal)) 
                {
                    return false; 
                }
            }

            throw DataServiceException.CreateBadRequestError(Strings.BadRequestStream_InvalidKeyword(s)); 
        }
 
        ///  
        /// Reads the name string from the reader
        ///  
        /// true, if you want to allow quotes, otherwise false
        /// string name value
        private string ReadName(bool allowQuotes)
        { 
            char ch = this.PeekNextSignificantCharacter();
 
            if ((ch == '"') || (ch == '\'')) 
            {
                if (allowQuotes) 
                {
                    return this.ReadString();
                }
            } 
            else
            { 
                StringBuilder sb = new StringBuilder(); 

                while (true) 
                {
                    ch = this.PeekNextCharacter();
                    if ((ch == '_') || Char.IsLetterOrDigit(ch) || ch == '$')
                    { 
                        this.ReadNextCharacter();
                        sb.Append(ch); 
                    } 
                    else
                    { 
                        return sb.ToString();
                    }
                }
            } 

            return null; 
        } 

        ///  
        /// Reads the null literal from the reader
        /// 
        private void ReadNull()
        { 
            string s = this.ReadName(/* allowQuotes */ false);
 
            if (s == null) 
            {
                throw DataServiceException.CreateBadRequestError(Strings.BadRequestStream_MissingMemberName); 
            }
            else if (!s.Equals("null", StringComparison.Ordinal))
            {
                throw DataServiceException.CreateBadRequestError(Strings.BadRequestStream_InvalidKeyword(s)); 
            }
        } 
 
        /// Reads the number from the reader.
        /// reads the clr number object 
        private object ReadNumber()
        {
            char ch = this.ReadNextCharacter();
 
            StringBuilder sb = new StringBuilder();
            sb.Append(ch); 
            while (true) 
            {
                ch = this.PeekNextSignificantCharacter(); 

                if (Char.IsDigit(ch) || (ch == '.') || (ch == 'E') || (ch == 'e') || (ch == '-') || (ch == '+'))
                {
                    this.ReadNextCharacter(); 
                    sb.Append(ch);
                } 
                else 
                {
                    break; 
                }
            }

            string s = sb.ToString(); 
            Double doubleValue;
            int intValue; 
 
            // We will first try and convert this int32. If this succeeds, great. Otherwise, we will try
            // and convert this into a double. 
            if (Int32.TryParse(s, NumberStyles.Integer, NumberFormatInfo.InvariantInfo, out intValue))
            {
                return intValue;
            } 
            else if (Double.TryParse(s, NumberStyles.Float, NumberFormatInfo.InvariantInfo, out doubleValue))
            { 
                return doubleValue; 
            }
 
            throw DataServiceException.CreateBadRequestError(Strings.BadRequestStream_InvalidContent);
        }

        ///  
        /// Reads the object from the reader
        ///  
        /// returns hashtable containing the list of property names and values 
        private Hashtable ReadObject()
        { 
            Hashtable record = new Hashtable();

            // Consume the '{'
            this.ReadNextCharacter(); 

            while (true) 
            { 
                char ch = this.PeekNextSignificantCharacter();
                if (ch == '\0') 
                {
                    // Unterminated Object literal
                    throw DataServiceException.CreateBadRequestError(Strings.BadRequestStream_InvalidContent);
                } 

                if (ch == '}') 
                { 
                    this.ReadNextCharacter();
                    return record; 
                }

                if (record.Count != 0)
                { 
                    if (ch != ',')
                    { 
                        throw DataServiceException.CreateBadRequestError(Strings.BadRequestStream_MissingMemberSeperator); 
                    }
                    else 
                    {
                        this.ReadNextCharacter();
                    }
                } 

                string name = this.ReadName(/* allowQuotes */ true); 
                if (String.IsNullOrEmpty(name)) 
                {
                    throw DataServiceException.CreateBadRequestError(Strings.BadRequestStream_InvalidJsonNameSpecifiedOrExtraComma); 
                }

                ch = this.PeekNextSignificantCharacter();
 
                // Unexpected name/value pair syntax in object literal
                if (ch != ':') 
                { 
                    throw DataServiceException.CreateBadRequestError(Strings.BadRequestStream_MissingNameValueSeperator(name));
                } 
                else
                {
                    this.ReadNextCharacter();
                } 

                object item = this.ReadValue(); 
                record[name] = item; 
            }
        } 

        /// 
        /// Read the string value from the reader
        ///  
        /// returns the string value read from the reader
        private string ReadString() 
        { 
            bool dummy;
            return this.ReadString(out dummy); 
        }

        /// 
        /// Read the string value from the reader 
        /// 
        /// out parameter indicating whether the string has a leading slash or not 
        /// returns the string value read from the reader 
        private string ReadString(out bool hasLeadingSlash)
        { 
            StringBuilder sb = new StringBuilder();

            char endQuoteCharacter = this.ReadNextCharacter();
            bool insideEscape = false; 
            bool firstCharacter = true;
            hasLeadingSlash = false; 
 
            while (true)
            { 
                char ch = this.ReadNextCharacter();
                if (firstCharacter)
                {
                    if (ch == '\\') 
                    {
                        hasLeadingSlash = true; 
                    } 

                    firstCharacter = false; 
                }

                if (insideEscape)
                { 
                    if (ch == 'u')
                    { 
                        string unicodeSequence = this.GetCharacters(4); 
                        Debug.Assert(unicodeSequence != null, "unicodeSequence != null");
                        ch = (char)Int32.Parse(unicodeSequence, NumberStyles.HexNumber, CultureInfo.InvariantCulture); 
                    }

                    // From 4627, section 2.5, here's the list of characters that we should be escaping
                    if (ch == 'b') 
                    {
                        sb.Append('\b'); 
                    } 
                    else if (ch == 'f')
                    { 
                        sb.Append('\f');
                    }
                    else if (ch == 'n')
                    { 
                        sb.Append('\n');
                    } 
                    else if (ch == 'r') 
                    {
                        sb.Append('\r'); 
                    }
                    else if (ch == 't')
                    {
                        sb.Append('\t'); 
                    }
                    else 
                    { 
                        sb.Append(ch);
                    } 

                    insideEscape = false;
                    continue;
                } 

                if (ch == '\\') 
                { 
                    insideEscape = true;
                    continue; 
                }

                if (ch == endQuoteCharacter)
                { 
                    return sb.ToString();
                } 
 
                sb.Append(ch);
            } 
        }

        /// Marks the fact that a recursive method was entered, and checks that the depth is allowed.
        private void RecurseEnter() 
        {
            this.recursionDepth++; 
            Debug.Assert(this.recursionDepth <= RecursionLimit, "this.recursionDepth <= RecursionLimit"); 
            if (this.recursionDepth == RecursionLimit)
            { 
                // 400 - Bad Request
                throw DataServiceException.CreateDeepRecursion(RecursionLimit);
            }
        } 

        /// Marks the fact that a recursive method is leaving.. 
        private void RecurseLeave() 
        {
            this.recursionDepth--; 
            Debug.Assert(0 <= this.recursionDepth, "0 <= this.recursionDepth");
            Debug.Assert(this.recursionDepth < RecursionLimit, "this.recursionDepth < RecursionLimit");
        }
    } 
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
//---------------------------------------------------------------------- 
// 
//      Copyright (c) Microsoft Corporation.  All rights reserved.
// 
//  
//      Provides a reader implementaion for Json format
//  
// 
// @owner  [....]
//--------------------------------------------------------------------- 

namespace System.Data.Services.Serializers
{
    using System; 
    using System.Collections;
    using System.Diagnostics; 
    using System.Globalization; 
    using System.IO;
    using System.Text; 
    using System.Text.RegularExpressions;

    /// Json text reader.
    internal sealed class JsonReader : IDisposable 
    {
        /// Compiled Regex for DateTime Format. 
        private static readonly Regex DateTimeFormat = new Regex(@"^/Date\((?-?[0-9]+)\)/", RegexOptions.Compiled); 

        /// Maximum recursion limit on reader. 
        private const int RecursionLimit = 200;

        ///  Reader to reader text into 
        private readonly TextReader reader; 

        /// Depth of recursion. 
        private int recursionDepth; 

        ///  
        /// Creates a new instance of Json reader which readers the json text
        /// from the given reader
        /// 
        /// text reader from which json payload needs to be readS 
        public JsonReader(TextReader reader)
        { 
            Debug.Assert(reader != null, "reader != null"); 
            this.reader = reader;
        } 

        /// Releases resources held onto by this object.
        public void Dispose()
        { 
            this.reader.Dispose();
        } 
 
        /// 
        /// Converts the given value into the right type 
        /// 
        /// returns the clr object instance which 
        public object ReadValue()
        { 
            this.RecurseEnter();
 
            object value = null; 
            bool allowNull = false;
 
            char ch = this.PeekNextSignificantCharacter();
            if (ch == '[')
            {
                value = this.ReadArray(); 
            }
            else if (ch == '{') 
            { 
                value = this.ReadObject();
            } 
            else if ((ch == '\'') || (ch == '"'))
            {
                bool hasLeadingSlash;
                string s = this.ReadString(out hasLeadingSlash); 
                value = s; // may be overwritten with a DateTime if ends up being a date/time
 
                // Atlas format for date/time 
                if (hasLeadingSlash)
                { 
                    Match match = DateTimeFormat.Match(s);
                    if (match.Success)
                    {
                        string ticksStr = match.Groups["ticks"].Value; 

                        long ticks; 
                        if (long.TryParse(ticksStr, NumberStyles.Integer, NumberFormatInfo.InvariantInfo, out ticks)) 
                        {
                            // The javascript ticks start from 1/1/1970 but FX DateTime ticks start from 1/1/0001 
                            DateTime dateTime = new DateTime(ticks * 10000 + JsonWriter.DatetimeMinTimeTicks, DateTimeKind.Utc);
                            value = dateTime;
                        }
                    } 
                }
            } 
            else if (Char.IsDigit(ch) || (ch == '-') || (ch == '.')) 
            {
                value = this.ReadNumber(); 
            }
            else if ((ch == 't') || (ch == 'f'))
            {
                value = this.ReadBoolean(); 
            }
            else if (ch == 'n') 
            { 
                this.ReadNull();
                allowNull = true; 
            }

            if ((value == null) && (allowNull == false))
            { 
                throw DataServiceException.CreateBadRequestError(Strings.BadRequestStream_InvalidContent);
            } 
 
            this.RecurseLeave();
            return value; 
        }

        /// 
        /// Gets the next character from the reader. This function moves the enumerator by 1 position 
        /// 
        /// the next charater from the current reader position 
        private char ReadNextCharacter() 
        {
            int result = this.reader.Read(); 
            if (result < 0)
            {
                throw DataServiceException.CreateBadRequestError(Strings.BadRequestStream_InvalidContent);
            } 

            Debug.Assert(result <= char.MaxValue, "result <= char.MaxValue"); 
            return (char)result; 
        }
 
        /// 
        /// peeks the next character from the reader. This does not move the current reader position.
        /// 
        /// the next character from the current reader position 
        private char PeekNextCharacter()
        { 
            int result = this.reader.Peek(); 
            if (result < 0)
            { 
                return '\0';
            }

            Debug.Assert(result <= char.MaxValue, "result <= char.MaxValue"); 
            return (char)result;
        } 
 
        /// 
        /// Returns the next count characters from the reader's current position 
        /// 
        /// number of characters to return
        /// string consisting of next count characters
        private string GetCharacters(int count) 
        {
            StringBuilder stringBuilder = new StringBuilder(); 
            for (int i = 0; i < count; i++) 
            {
                char ch = this.ReadNextCharacter(); 
                stringBuilder.Append(ch);
            }

            return stringBuilder.ToString(); 
        }
 
        ///  
        /// Sets the readers position to the next significant character position
        ///  
        /// returns the next significant character without changing the current position of the reader
        private char PeekNextSignificantCharacter()
        {
            char ch = this.PeekNextCharacter(); 
            while ((ch != '\0') && Char.IsWhiteSpace(ch))
            { 
                this.ReadNextCharacter(); 
                ch = this.PeekNextCharacter();
            } 

            return ch;
        }
 
        /// 
        /// Converts the given text into an arrayList 
        ///  
        /// returns the arraylist containing the list of objects
        private ArrayList ReadArray() 
        {
            ArrayList array = new ArrayList();

            // Consume the '[' 
            this.ReadNextCharacter();
 
            while (true) 
            {
                char ch = this.PeekNextSignificantCharacter(); 
                if (ch == '\0')
                {
                    throw DataServiceException.CreateBadRequestError(Strings.BadRequestStream_InvalidContent);
                } 

                if (ch == ']') 
                { 
                    this.ReadNextCharacter();
                    return array; 
                }

                if (array.Count != 0)
                { 
                    if (ch != ',')
                    { 
                        throw DataServiceException.CreateBadRequestError(Strings.BadRequestStream_MissingArrayMemberSeperator); 
                    }
                    else 
                    {
                        this.ReadNextCharacter();
                    }
                } 

                object item = this.ReadValue(); 
                array.Add(item); 
            }
        } 

        /// 
        /// Reads the boolean value
        ///  
        /// returns the boolean value as read from the reader
        private bool ReadBoolean() 
        { 
            string s = this.ReadName(/* allowQuotes */ false);
 
            if (s != null)
            {
                if (s.Equals(XmlConstants.XmlTrueLiteral, StringComparison.Ordinal))
                { 
                    return true;
                } 
                else if (s.Equals(XmlConstants.XmlFalseLiteral, StringComparison.Ordinal)) 
                {
                    return false; 
                }
            }

            throw DataServiceException.CreateBadRequestError(Strings.BadRequestStream_InvalidKeyword(s)); 
        }
 
        ///  
        /// Reads the name string from the reader
        ///  
        /// true, if you want to allow quotes, otherwise false
        /// string name value
        private string ReadName(bool allowQuotes)
        { 
            char ch = this.PeekNextSignificantCharacter();
 
            if ((ch == '"') || (ch == '\'')) 
            {
                if (allowQuotes) 
                {
                    return this.ReadString();
                }
            } 
            else
            { 
                StringBuilder sb = new StringBuilder(); 

                while (true) 
                {
                    ch = this.PeekNextCharacter();
                    if ((ch == '_') || Char.IsLetterOrDigit(ch) || ch == '$')
                    { 
                        this.ReadNextCharacter();
                        sb.Append(ch); 
                    } 
                    else
                    { 
                        return sb.ToString();
                    }
                }
            } 

            return null; 
        } 

        ///  
        /// Reads the null literal from the reader
        /// 
        private void ReadNull()
        { 
            string s = this.ReadName(/* allowQuotes */ false);
 
            if (s == null) 
            {
                throw DataServiceException.CreateBadRequestError(Strings.BadRequestStream_MissingMemberName); 
            }
            else if (!s.Equals("null", StringComparison.Ordinal))
            {
                throw DataServiceException.CreateBadRequestError(Strings.BadRequestStream_InvalidKeyword(s)); 
            }
        } 
 
        /// Reads the number from the reader.
        /// reads the clr number object 
        private object ReadNumber()
        {
            char ch = this.ReadNextCharacter();
 
            StringBuilder sb = new StringBuilder();
            sb.Append(ch); 
            while (true) 
            {
                ch = this.PeekNextSignificantCharacter(); 

                if (Char.IsDigit(ch) || (ch == '.') || (ch == 'E') || (ch == 'e') || (ch == '-') || (ch == '+'))
                {
                    this.ReadNextCharacter(); 
                    sb.Append(ch);
                } 
                else 
                {
                    break; 
                }
            }

            string s = sb.ToString(); 
            Double doubleValue;
            int intValue; 
 
            // We will first try and convert this int32. If this succeeds, great. Otherwise, we will try
            // and convert this into a double. 
            if (Int32.TryParse(s, NumberStyles.Integer, NumberFormatInfo.InvariantInfo, out intValue))
            {
                return intValue;
            } 
            else if (Double.TryParse(s, NumberStyles.Float, NumberFormatInfo.InvariantInfo, out doubleValue))
            { 
                return doubleValue; 
            }
 
            throw DataServiceException.CreateBadRequestError(Strings.BadRequestStream_InvalidContent);
        }

        ///  
        /// Reads the object from the reader
        ///  
        /// returns hashtable containing the list of property names and values 
        private Hashtable ReadObject()
        { 
            Hashtable record = new Hashtable();

            // Consume the '{'
            this.ReadNextCharacter(); 

            while (true) 
            { 
                char ch = this.PeekNextSignificantCharacter();
                if (ch == '\0') 
                {
                    // Unterminated Object literal
                    throw DataServiceException.CreateBadRequestError(Strings.BadRequestStream_InvalidContent);
                } 

                if (ch == '}') 
                { 
                    this.ReadNextCharacter();
                    return record; 
                }

                if (record.Count != 0)
                { 
                    if (ch != ',')
                    { 
                        throw DataServiceException.CreateBadRequestError(Strings.BadRequestStream_MissingMemberSeperator); 
                    }
                    else 
                    {
                        this.ReadNextCharacter();
                    }
                } 

                string name = this.ReadName(/* allowQuotes */ true); 
                if (String.IsNullOrEmpty(name)) 
                {
                    throw DataServiceException.CreateBadRequestError(Strings.BadRequestStream_InvalidJsonNameSpecifiedOrExtraComma); 
                }

                ch = this.PeekNextSignificantCharacter();
 
                // Unexpected name/value pair syntax in object literal
                if (ch != ':') 
                { 
                    throw DataServiceException.CreateBadRequestError(Strings.BadRequestStream_MissingNameValueSeperator(name));
                } 
                else
                {
                    this.ReadNextCharacter();
                } 

                object item = this.ReadValue(); 
                record[name] = item; 
            }
        } 

        /// 
        /// Read the string value from the reader
        ///  
        /// returns the string value read from the reader
        private string ReadString() 
        { 
            bool dummy;
            return this.ReadString(out dummy); 
        }

        /// 
        /// Read the string value from the reader 
        /// 
        /// out parameter indicating whether the string has a leading slash or not 
        /// returns the string value read from the reader 
        private string ReadString(out bool hasLeadingSlash)
        { 
            StringBuilder sb = new StringBuilder();

            char endQuoteCharacter = this.ReadNextCharacter();
            bool insideEscape = false; 
            bool firstCharacter = true;
            hasLeadingSlash = false; 
 
            while (true)
            { 
                char ch = this.ReadNextCharacter();
                if (firstCharacter)
                {
                    if (ch == '\\') 
                    {
                        hasLeadingSlash = true; 
                    } 

                    firstCharacter = false; 
                }

                if (insideEscape)
                { 
                    if (ch == 'u')
                    { 
                        string unicodeSequence = this.GetCharacters(4); 
                        Debug.Assert(unicodeSequence != null, "unicodeSequence != null");
                        ch = (char)Int32.Parse(unicodeSequence, NumberStyles.HexNumber, CultureInfo.InvariantCulture); 
                    }

                    // From 4627, section 2.5, here's the list of characters that we should be escaping
                    if (ch == 'b') 
                    {
                        sb.Append('\b'); 
                    } 
                    else if (ch == 'f')
                    { 
                        sb.Append('\f');
                    }
                    else if (ch == 'n')
                    { 
                        sb.Append('\n');
                    } 
                    else if (ch == 'r') 
                    {
                        sb.Append('\r'); 
                    }
                    else if (ch == 't')
                    {
                        sb.Append('\t'); 
                    }
                    else 
                    { 
                        sb.Append(ch);
                    } 

                    insideEscape = false;
                    continue;
                } 

                if (ch == '\\') 
                { 
                    insideEscape = true;
                    continue; 
                }

                if (ch == endQuoteCharacter)
                { 
                    return sb.ToString();
                } 
 
                sb.Append(ch);
            } 
        }

        /// Marks the fact that a recursive method was entered, and checks that the depth is allowed.
        private void RecurseEnter() 
        {
            this.recursionDepth++; 
            Debug.Assert(this.recursionDepth <= RecursionLimit, "this.recursionDepth <= RecursionLimit"); 
            if (this.recursionDepth == RecursionLimit)
            { 
                // 400 - Bad Request
                throw DataServiceException.CreateDeepRecursion(RecursionLimit);
            }
        } 

        /// Marks the fact that a recursive method is leaving.. 
        private void RecurseLeave() 
        {
            this.recursionDepth--; 
            Debug.Assert(0 <= this.recursionDepth, "0 <= this.recursionDepth");
            Debug.Assert(this.recursionDepth < RecursionLimit, "this.recursionDepth < RecursionLimit");
        }
    } 
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.

                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK