XmlJsonReader.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ WCF / WCF / 3.5.30729.1 / untmp / Orcas / SP / ndp / cdf / src / NetFx35 / System.ServiceModel.Web / System / Runtime / Serialization / Json / XmlJsonReader.cs / 1 / XmlJsonReader.cs

                            //------------------------------------------------------------ 
// Copyright (c) Microsoft Corporation.  All rights reserved.
//-----------------------------------------------------------

namespace System.Runtime.Serialization.Json 
{
    using System.Globalization; 
    using System.IO; 
    using System.ServiceModel;
    using System.Text; 
    using System.Runtime.Serialization;
    using System.Collections.Generic;
    using System.Xml;
    using System.ServiceModel.Web; 

    class XmlJsonReader : XmlBaseReader, IXmlJsonReaderInitializer 
    { 
        const int MaxTextChunk = 2048;
 
        static byte[] charType = new byte[256]
            {
                CharType.None, //   0 (.)
                CharType.None, //   1 (.) 
                CharType.None, //   2 (.)
                CharType.None, //   3 (.) 
                CharType.None, //   4 (.) 
                CharType.None, //   5 (.)
                CharType.None, //   6 (.) 
                CharType.None, //   7 (.)
                CharType.None, //   8 (.)
                CharType.None, //   9 (.)
                CharType.None, //   A (.) 
                CharType.None, //   B (.)
                CharType.None, //   C (.) 
                CharType.None, //   D (.) 
                CharType.None, //   E (.)
                CharType.None, //   F (.) 
                CharType.None, //  10 (.)
                CharType.None, //  11 (.)
                CharType.None, //  12 (.)
                CharType.None, //  13 (.) 
                CharType.None, //  14 (.)
                CharType.None, //  15 (.) 
                CharType.None, //  16 (.) 
                CharType.None, //  17 (.)
                CharType.None, //  18 (.) 
                CharType.None, //  19 (.)
                CharType.None, //  1A (.)
                CharType.None, //  1B (.)
                CharType.None, //  1C (.) 
                CharType.None, //  1D (.)
                CharType.None, //  1E (.) 
                CharType.None, //  1F (.) 
                CharType.None, //  20 ( )
                CharType.None, //  21 (!) 
                CharType.None, //  22 (")
                CharType.None, //  23 (#)
                CharType.None, //  24 ($)
                CharType.None, //  25 (%) 
                CharType.None, //  26 (&)
                CharType.None, //  27 (') 
                CharType.None, //  28 (() 
                CharType.None, //  29 ())
                CharType.None, //  2A (*) 
                CharType.None, //  2B (+)
                CharType.None, //  2C (,)
                CharType.None | CharType.Name, //  2D (-)
                CharType.None | CharType.Name, //  2E (.) 
                CharType.None, //  2F (/)
                CharType.None | CharType.Name, //  30 (0) 
                CharType.None | CharType.Name, //  31 (1) 
                CharType.None | CharType.Name, //  32 (2)
                CharType.None | CharType.Name, //  33 (3) 
                CharType.None | CharType.Name, //  34 (4)
                CharType.None | CharType.Name, //  35 (5)
                CharType.None | CharType.Name, //  36 (6)
                CharType.None | CharType.Name, //  37 (7) 
                CharType.None | CharType.Name, //  38 (8)
                CharType.None | CharType.Name, //  39 (9) 
                CharType.None, //  3A (:) 
                CharType.None, //  3B (;)
                CharType.None, //  3C (<) 
                CharType.None, //  3D (=)
                CharType.None, //  3E (>)
                CharType.None, //  3F (?)
                CharType.None, //  40 (@) 
                CharType.None | CharType.FirstName | CharType.Name, //  41 (A)
                CharType.None | CharType.FirstName | CharType.Name, //  42 (B) 
                CharType.None | CharType.FirstName | CharType.Name, //  43 (C) 
                CharType.None | CharType.FirstName | CharType.Name, //  44 (D)
                CharType.None | CharType.FirstName | CharType.Name, //  45 (E) 
                CharType.None | CharType.FirstName | CharType.Name, //  46 (F)
                CharType.None | CharType.FirstName | CharType.Name, //  47 (G)
                CharType.None | CharType.FirstName | CharType.Name, //  48 (H)
                CharType.None | CharType.FirstName | CharType.Name, //  49 (I) 
                CharType.None | CharType.FirstName | CharType.Name, //  4A (J)
                CharType.None | CharType.FirstName | CharType.Name, //  4B (K) 
                CharType.None | CharType.FirstName | CharType.Name, //  4C (L) 
                CharType.None | CharType.FirstName | CharType.Name, //  4D (M)
                CharType.None | CharType.FirstName | CharType.Name, //  4E (N) 
                CharType.None | CharType.FirstName | CharType.Name, //  4F (O)
                CharType.None | CharType.FirstName | CharType.Name, //  50 (P)
                CharType.None | CharType.FirstName | CharType.Name, //  51 (Q)
                CharType.None | CharType.FirstName | CharType.Name, //  52 (R) 
                CharType.None | CharType.FirstName | CharType.Name, //  53 (S)
                CharType.None | CharType.FirstName | CharType.Name, //  54 (T) 
                CharType.None | CharType.FirstName | CharType.Name, //  55 (U) 
                CharType.None | CharType.FirstName | CharType.Name, //  56 (V)
                CharType.None | CharType.FirstName | CharType.Name, //  57 (W) 
                CharType.None | CharType.FirstName | CharType.Name, //  58 (X)
                CharType.None | CharType.FirstName | CharType.Name, //  59 (Y)
                CharType.None | CharType.FirstName | CharType.Name, //  5A (Z)
                CharType.None, //  5B ([) 
                CharType.None, //  5C (\)
                CharType.None, //  5D (]) 
                CharType.None, //  5E (^) 
                CharType.None | CharType.FirstName | CharType.Name, //  5F (_)
                CharType.None, //  60 (`) 
                CharType.None | CharType.FirstName | CharType.Name, //  61 (a)
                CharType.None | CharType.FirstName | CharType.Name, //  62 (b)
                CharType.None | CharType.FirstName | CharType.Name, //  63 (c)
                CharType.None | CharType.FirstName | CharType.Name, //  64 (d) 
                CharType.None | CharType.FirstName | CharType.Name, //  65 (e)
                CharType.None | CharType.FirstName | CharType.Name, //  66 (f) 
                CharType.None | CharType.FirstName | CharType.Name, //  67 (g) 
                CharType.None | CharType.FirstName | CharType.Name, //  68 (h)
                CharType.None | CharType.FirstName | CharType.Name, //  69 (i) 
                CharType.None | CharType.FirstName | CharType.Name, //  6A (j)
                CharType.None | CharType.FirstName | CharType.Name, //  6B (k)
                CharType.None | CharType.FirstName | CharType.Name, //  6C (l)
                CharType.None | CharType.FirstName | CharType.Name, //  6D (m) 
                CharType.None | CharType.FirstName | CharType.Name, //  6E (n)
                CharType.None | CharType.FirstName | CharType.Name, //  6F (o) 
                CharType.None | CharType.FirstName | CharType.Name, //  70 (p) 
                CharType.None | CharType.FirstName | CharType.Name, //  71 (q)
                CharType.None | CharType.FirstName | CharType.Name, //  72 (r) 
                CharType.None | CharType.FirstName | CharType.Name, //  73 (s)
                CharType.None | CharType.FirstName | CharType.Name, //  74 (t)
                CharType.None | CharType.FirstName | CharType.Name, //  75 (u)
                CharType.None | CharType.FirstName | CharType.Name, //  76 (v) 
                CharType.None | CharType.FirstName | CharType.Name, //  77 (w)
                CharType.None | CharType.FirstName | CharType.Name, //  78 (x) 
                CharType.None | CharType.FirstName | CharType.Name, //  79 (y) 
                CharType.None | CharType.FirstName | CharType.Name, //  7A (z)
                CharType.None, //  7B ({) 
                CharType.None, //  7C (|)
                CharType.None, //  7D (})
                CharType.None, //  7E (~)
                CharType.None, //  7F (.) 
                CharType.None | CharType.FirstName | CharType.Name, //  80 (.)
                CharType.None | CharType.FirstName | CharType.Name, //  81 (.) 
                CharType.None | CharType.FirstName | CharType.Name, //  82 (.) 
                CharType.None | CharType.FirstName | CharType.Name, //  83 (.)
                CharType.None | CharType.FirstName | CharType.Name, //  84 (.) 
                CharType.None | CharType.FirstName | CharType.Name, //  85 (.)
                CharType.None | CharType.FirstName | CharType.Name, //  86 (.)
                CharType.None | CharType.FirstName | CharType.Name, //  87 (.)
                CharType.None | CharType.FirstName | CharType.Name, //  88 (.) 
                CharType.None | CharType.FirstName | CharType.Name, //  89 (.)
                CharType.None | CharType.FirstName | CharType.Name, //  8A (.) 
                CharType.None | CharType.FirstName | CharType.Name, //  8B (.) 
                CharType.None | CharType.FirstName | CharType.Name, //  8C (.)
                CharType.None | CharType.FirstName | CharType.Name, //  8D (.) 
                CharType.None | CharType.FirstName | CharType.Name, //  8E (.)
                CharType.None | CharType.FirstName | CharType.Name, //  8F (.)
                CharType.None | CharType.FirstName | CharType.Name, //  90 (.)
                CharType.None | CharType.FirstName | CharType.Name, //  91 (.) 
                CharType.None | CharType.FirstName | CharType.Name, //  92 (.)
                CharType.None | CharType.FirstName | CharType.Name, //  93 (.) 
                CharType.None | CharType.FirstName | CharType.Name, //  94 (.) 
                CharType.None | CharType.FirstName | CharType.Name, //  95 (.)
                CharType.None | CharType.FirstName | CharType.Name, //  96 (.) 
                CharType.None | CharType.FirstName | CharType.Name, //  97 (.)
                CharType.None | CharType.FirstName | CharType.Name, //  98 (.)
                CharType.None | CharType.FirstName | CharType.Name, //  99 (.)
                CharType.None | CharType.FirstName | CharType.Name, //  9A (.) 
                CharType.None | CharType.FirstName | CharType.Name, //  9B (.)
                CharType.None | CharType.FirstName | CharType.Name, //  9C (.) 
                CharType.None | CharType.FirstName | CharType.Name, //  9D (.) 
                CharType.None | CharType.FirstName | CharType.Name, //  9E (.)
                CharType.None | CharType.FirstName | CharType.Name, //  9F (.) 
                CharType.None | CharType.FirstName | CharType.Name, //  A0 (�)
                CharType.None | CharType.FirstName | CharType.Name, //  A1 (�)
                CharType.None | CharType.FirstName | CharType.Name, //  A2 (�)
                CharType.None | CharType.FirstName | CharType.Name, //  A3 (�) 
                CharType.None | CharType.FirstName | CharType.Name, //  A4 ()
                CharType.None | CharType.FirstName | CharType.Name, //  A5 (�) 
                CharType.None | CharType.FirstName | CharType.Name, //  A6 (�) 
                CharType.None | CharType.FirstName | CharType.Name, //  A7 ()
                CharType.None | CharType.FirstName | CharType.Name, //  A8 (") 
                CharType.None | CharType.FirstName | CharType.Name, //  A9 (c)
                CharType.None | CharType.FirstName | CharType.Name, //  AA (�)
                CharType.None | CharType.FirstName | CharType.Name, //  AB (�)
                CharType.None | CharType.FirstName | CharType.Name, //  AC (�) 
                CharType.None | CharType.FirstName | CharType.Name, //  AD (-)
                CharType.None | CharType.FirstName | CharType.Name, //  AE (r) 
                CharType.None | CharType.FirstName | CharType.Name, //  AF (_) 
                CharType.None | CharType.FirstName | CharType.Name, //  B0 (�)
                CharType.None | CharType.FirstName | CharType.Name, //  B1 (�) 
                CharType.None | CharType.FirstName | CharType.Name, //  B2 (�)
                CharType.None | CharType.FirstName | CharType.Name, //  B3 (3)
                CharType.None | CharType.FirstName | CharType.Name, //  B4 (')
                CharType.None | CharType.FirstName | CharType.Name, //  B5 (�) 
                CharType.None | CharType.FirstName | CharType.Name, //  B6 ()
                CharType.None | CharType.FirstName | CharType.Name, //  B7 (�) 
                CharType.None | CharType.FirstName | CharType.Name, //  B8 (,) 
                CharType.None | CharType.FirstName | CharType.Name, //  B9 (1)
                CharType.None | CharType.FirstName | CharType.Name, //  BA (�) 
                CharType.None | CharType.FirstName | CharType.Name, //  BB (�)
                CharType.None | CharType.FirstName | CharType.Name, //  BC (�)
                CharType.None | CharType.FirstName | CharType.Name, //  BD (�)
                CharType.None | CharType.FirstName | CharType.Name, //  BE (_) 
                CharType.None | CharType.FirstName | CharType.Name, //  BF (�)
                CharType.None | CharType.FirstName | CharType.Name, //  C0 (A) 
                CharType.None | CharType.FirstName | CharType.Name, //  C1 (A) 
                CharType.None | CharType.FirstName | CharType.Name, //  C2 (A)
                CharType.None | CharType.FirstName | CharType.Name, //  C3 (A) 
                CharType.None | CharType.FirstName | CharType.Name, //  C4 (�)
                CharType.None | CharType.FirstName | CharType.Name, //  C5 (�)
                CharType.None | CharType.FirstName | CharType.Name, //  C6 (�)
                CharType.None | CharType.FirstName | CharType.Name, //  C7 (�) 
                CharType.None | CharType.FirstName | CharType.Name, //  C8 (E)
                CharType.None | CharType.FirstName | CharType.Name, //  C9 (�) 
                CharType.None | CharType.FirstName | CharType.Name, //  CA (E) 
                CharType.None | CharType.FirstName | CharType.Name, //  CB (E)
                CharType.None | CharType.FirstName | CharType.Name, //  CC (I) 
                CharType.None | CharType.FirstName | CharType.Name, //  CD (I)
                CharType.None | CharType.FirstName | CharType.Name, //  CE (I)
                CharType.None | CharType.FirstName | CharType.Name, //  CF (I)
                CharType.None | CharType.FirstName | CharType.Name, //  D0 (D) 
                CharType.None | CharType.FirstName | CharType.Name, //  D1 (�)
                CharType.None | CharType.FirstName | CharType.Name, //  D2 (O) 
                CharType.None | CharType.FirstName | CharType.Name, //  D3 (O) 
                CharType.None | CharType.FirstName | CharType.Name, //  D4 (O)
                CharType.None | CharType.FirstName | CharType.Name, //  D5 (O) 
                CharType.None | CharType.FirstName | CharType.Name, //  D6 (�)
                CharType.None | CharType.FirstName | CharType.Name, //  D7 (x)
                CharType.None | CharType.FirstName | CharType.Name, //  D8 (O)
                CharType.None | CharType.FirstName | CharType.Name, //  D9 (U) 
                CharType.None | CharType.FirstName | CharType.Name, //  DA (U)
                CharType.None | CharType.FirstName | CharType.Name, //  DB (U) 
                CharType.None | CharType.FirstName | CharType.Name, //  DC (�) 
                CharType.None | CharType.FirstName | CharType.Name, //  DD (Y)
                CharType.None | CharType.FirstName | CharType.Name, //  DE (_) 
                CharType.None | CharType.FirstName | CharType.Name, //  DF (�)
                CharType.None | CharType.FirstName | CharType.Name, //  E0 (�)
                CharType.None | CharType.FirstName | CharType.Name, //  E1 (�)
                CharType.None | CharType.FirstName | CharType.Name, //  E2 (�) 
                CharType.None | CharType.FirstName | CharType.Name, //  E3 (a)
                CharType.None | CharType.FirstName | CharType.Name, //  E4 (�) 
                CharType.None | CharType.FirstName | CharType.Name, //  E5 (�) 
                CharType.None | CharType.FirstName | CharType.Name, //  E6 (�)
                CharType.None | CharType.FirstName | CharType.Name, //  E7 (�) 
                CharType.None | CharType.FirstName | CharType.Name, //  E8 (�)
                CharType.None | CharType.FirstName | CharType.Name, //  E9 (�)
                CharType.None | CharType.FirstName | CharType.Name, //  EA (�)
                CharType.None | CharType.FirstName | CharType.Name, //  EB (�) 
                CharType.None | CharType.FirstName | CharType.Name, //  EC (�)
                CharType.None | CharType.FirstName | CharType.Name, //  ED (�) 
                CharType.None | CharType.FirstName | CharType.Name, //  EE (�) 
                CharType.None | CharType.FirstName | CharType.Name, //  EF (�)
                CharType.None | CharType.FirstName | CharType.Name, //  F0 (d) 
                CharType.None | CharType.FirstName | CharType.Name, //  F1 (�)
                CharType.None | CharType.FirstName | CharType.Name, //  F2 (�)
                CharType.None | CharType.FirstName | CharType.Name, //  F3 (�)
                CharType.None | CharType.FirstName | CharType.Name, //  F4 (�) 
                CharType.None | CharType.FirstName | CharType.Name, //  F5 (o)
                CharType.None | CharType.FirstName | CharType.Name, //  F6 (�) 
                CharType.None | CharType.FirstName | CharType.Name, //  F7 (�) 
                CharType.None | CharType.FirstName | CharType.Name, //  F8 (o)
                CharType.None | CharType.FirstName | CharType.Name, //  F9 (�) 
                CharType.None | CharType.FirstName | CharType.Name, //  FA (�)
                CharType.None | CharType.FirstName | CharType.Name, //  FB (�)
                CharType.None | CharType.FirstName | CharType.Name, //  FC (�)
                CharType.None | CharType.FirstName | CharType.Name, //  FD (y) 
                CharType.None | CharType.FirstName | CharType.Name, //  FE (_)
                CharType.None | CharType.FirstName | CharType.Name, //  FF (�) 
            }; 
        bool buffered;
        byte[] charactersToSkipOnNextRead; 
        JsonComplexTextMode complexTextMode = JsonComplexTextMode.None;
        bool expectingFirstElementInNonPrimitiveChild;
        int maxBytesPerRead;
        OnXmlDictionaryReaderClose onReaderClose; 
        bool readServerTypeElement = false;
        int scopeDepth = 0; 
        JsonNodeType[] scopes; 

        enum JsonComplexTextMode 
        {
            QuotedText,
            NumericalText,
            None 
        };
 
        public override bool CanCanonicalize 
        {
            get 
            {
                return false;
            }
        } 

        public override string Value 
        { 
            get
            { 
                if (IsAttributeValue && !this.IsLocalName(JsonGlobals.typeString))
                {
                    return UnescapeJsonString(base.Value);
                } 
                return base.Value;
            } 
        } 

        bool IsAttributeValue 
        {
            get
            {
                return (this.Node.NodeType == XmlNodeType.Attribute || this.Node is XmlAttributeTextNode); 
            }
        } 
 
        bool IsReadingCollection
        { 
            get
            {
                return ((scopeDepth > 0) && (scopes[scopeDepth] == JsonNodeType.Collection));
            } 
        }
 
        bool IsReadingComplexText 
        {
            get 
            {
                return ((!this.Node.IsAtomicValue) &&
                    (this.Node.NodeType == XmlNodeType.Text));
 
            }
        } 
 
        public override void Close()
        { 
            base.Close();
            OnXmlDictionaryReaderClose onClose = this.onReaderClose;
            this.onReaderClose = null;
            ResetState(); 
            if (onClose != null)
            { 
                try 
                {
                    onClose(this); 
                }
                catch (Exception e)
                {
                    if (System.ServiceModel.DiagnosticUtility.IsFatal(e)) 
                    {
                        throw; 
                    } 

                    throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperCallback(e); 
                }
            }
        }
 
        public override void EndCanonicalization()
        { 
            throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException()); 
        }
 
        public override string GetAttribute(int index)
        {
            return UnescapeJsonString(base.GetAttribute(index));
        } 

        public override string GetAttribute(string localName, string namespaceUri) 
        { 
            if (localName != JsonGlobals.typeString)
            { 
                return UnescapeJsonString(base.GetAttribute(localName, namespaceUri));
            }
            return base.GetAttribute(localName, namespaceUri);
        } 
        public override string GetAttribute(string name)
        { 
            if (name != JsonGlobals.typeString) 
            {
                return UnescapeJsonString(base.GetAttribute(name)); 
            }
            return base.GetAttribute(name);
        }
 
        public override string GetAttribute(XmlDictionaryString localName, XmlDictionaryString namespaceUri)
        { 
            if (XmlDictionaryString.GetString(localName) != JsonGlobals.typeString) 
            {
                return UnescapeJsonString(base.GetAttribute(localName, namespaceUri)); 
            }
            return base.GetAttribute(localName, namespaceUri);
        }
 
        public override bool Read()
        { 
            if (this.Node.CanMoveToElement) 
            {
                // If we're positioned on an attribute or attribute text on an empty element, we need to move back 
                // to the element in order to get the correct setting of ExitScope
                MoveToElement();
            }
 
            if (this.Node.ReadState == ReadState.Closed)
            { 
                return false; 
            }
            if (this.Node.ExitScope) 
            {
                ExitScope();
            }
            if (!buffered) 
            {
                BufferReader.SetWindow(ElementNode.BufferOffset, this.maxBytesPerRead); 
            } 

            byte ch; 

            // Skip whitespace before checking EOF
            // Complex text check necessary because whitespace could be part of really long
            //    quoted text that's read using multiple Read() calls. 
            // This also ensures that we deal with the whitespace-only input case properly by not
            //    floating a root element at all. 
            if (!IsReadingComplexText) 
            {
                SkipWhitespaceInBufferReader(); 

                if (TryGetByte(out ch))
                {
                    if (charactersToSkipOnNextRead[0] == ch || charactersToSkipOnNextRead[1] == ch) 
                    {
                        BufferReader.SkipByte(); 
                        charactersToSkipOnNextRead[0] = 0; 
                        charactersToSkipOnNextRead[1] = 0;
                    } 
                }

                SkipWhitespaceInBufferReader();
 
                if (TryGetByte(out ch))
                { 
                    if (ch == JsonGlobals.EndCollectionByte && IsReadingCollection) 
                    {
                        BufferReader.SkipByte(); 
                        SkipWhitespaceInBufferReader();
                        ExitJsonScope();
                    }
                } 

                if (BufferReader.EndOfFile) 
                { 
                    if (scopeDepth > 0)
                    { 
                        MoveToEndElement();
                        return true;
                    }
                    else 
                    {
                        MoveToEndOfFile(); 
                        return false; 
                    }
                } 
            }

            ch = BufferReader.GetByte();
 
            if (scopeDepth == 0)
            { 
                ReadNonExistentElementName(StringHandleConstStringType.Root); 
            }
            else if (IsReadingComplexText) 
            {
                switch (complexTextMode)
                {
                    case JsonComplexTextMode.NumericalText: 
                        ReadNumericalText();
                        break; 
                    case JsonComplexTextMode.QuotedText: 
                        if (ch == (byte) '\\')
                        { 
                            ReadEscapedCharacter(true); //  moveToText
                        }
                        else
                        { 
                            ReadQuotedText(true); //  moveToText
                        } 
                        break; 
                    case JsonComplexTextMode.None:
                        XmlExceptionHelper.ThrowXmlException(this, 
                            new XmlException(SR2.GetString(SR2.JsonEncounteredUnexpectedCharacter, (char) ch)));
                        break;
                }
            } 
            else if (IsReadingCollection)
            { 
                ReadNonExistentElementName(StringHandleConstStringType.Item); 
            }
            else if (ch == JsonGlobals.EndCollectionByte) 
            {
                BufferReader.SkipByte();
                MoveToEndElement();
                ExitJsonScope(); 
            }
            else if (ch == JsonGlobals.ObjectByte) 
            { 
                BufferReader.SkipByte();
                SkipWhitespaceInBufferReader(); 
                ch = (byte) BufferReader.GetByte();
                if (ch == JsonGlobals.EndObjectByte)
                {
                    BufferReader.SkipByte(); 
                    SkipWhitespaceInBufferReader();
                    if (TryGetByte(out ch)) 
                    { 
                        if (ch == JsonGlobals.MemberSeparatorByte)
                        { 
                            BufferReader.SkipByte();
                        }
                    }
                    else 
                    {
                        charactersToSkipOnNextRead[0] = JsonGlobals.MemberSeparatorByte; 
                    } 
                    MoveToEndElement();
                } 
                else
                {
                    EnterJsonScope(JsonNodeType.Object);
                    ParseStartElement(); 
                }
            } 
            else if (ch == JsonGlobals.EndObjectByte) 
            {
                BufferReader.SkipByte(); 
                if (expectingFirstElementInNonPrimitiveChild)
                {
                    SkipWhitespaceInBufferReader();
                    ch = BufferReader.GetByte(); 
                    if ((ch == JsonGlobals.MemberSeparatorByte) ||
                        (ch == JsonGlobals.EndObjectByte)) 
                    { 
                        BufferReader.SkipByte();
                    } 
                    else
                    {
                        XmlExceptionHelper.ThrowXmlException(this,
                            new XmlException(SR2.GetString(SR2.JsonEncounteredUnexpectedCharacter, 
                            (char) ch)));
                    } 
                    expectingFirstElementInNonPrimitiveChild = false; 
                }
                MoveToEndElement(); 
            }
            else if (ch == JsonGlobals.MemberSeparatorByte)
            {
                BufferReader.SkipByte(); 
                MoveToEndElement();
            } 
            else if (ch == JsonGlobals.QuoteByte) 
            {
                if (readServerTypeElement) 
                {
                    readServerTypeElement = false;
                    EnterJsonScope(JsonNodeType.Object);
                    ParseStartElement(); 
                }
                else if (this.Node.NodeType == XmlNodeType.Element) 
                { 
                    if (expectingFirstElementInNonPrimitiveChild)
                    { 
                        EnterJsonScope(JsonNodeType.Object);
                        ParseStartElement();
                    }
                    else 
                    {
                        BufferReader.SkipByte(); 
                        ReadQuotedText(true); //  moveToText 
                    }
                } 
                else if (this.Node.NodeType == XmlNodeType.EndElement)
                {
                    EnterJsonScope(JsonNodeType.Element);
                    ParseStartElement(); 
                }
                else 
                { 
                    XmlExceptionHelper.ThrowXmlException(this,
                        new XmlException(SR2.GetString(SR2.JsonEncounteredUnexpectedCharacter, 
                        JsonGlobals.QuoteChar)));
                }
            }
            else if (ch == (byte) 'f') 
            {
                int offset; 
                byte[] buffer = BufferReader.GetBuffer(5, out offset); 
                if (buffer[offset + 1] != (byte) 'a' ||
                    buffer[offset + 2] != (byte) 'l' || 
                    buffer[offset + 3] != (byte) 's' ||
                    buffer[offset + 4] != (byte) 'e')
                {
                    XmlExceptionHelper.ThrowTokenExpected(this, "false", Encoding.UTF8.GetString(buffer, offset, 5)); 
                }
                BufferReader.Advance(5); 
 
                if (TryGetByte(out ch))
                { 
                    if (!IsWhitespace(ch) && ch != JsonGlobals.MemberSeparatorByte && ch != JsonGlobals.EndObjectChar && ch != JsonGlobals.EndCollectionByte)
                    {
                        XmlExceptionHelper.ThrowTokenExpected(this, "false", Encoding.UTF8.GetString(buffer, offset, 4) + (char) ch);
                    } 
                }
                MoveToAtomicText().Value.SetValue(ValueHandleType.UTF8, offset, 5); 
            } 
            else if (ch == (byte) 't')
            { 
                int offset;
                byte[] buffer = BufferReader.GetBuffer(4, out offset);
                if (buffer[offset + 1] != (byte) 'r' ||
                    buffer[offset + 2] != (byte) 'u' || 
                    buffer[offset + 3] != (byte) 'e')
                { 
                    XmlExceptionHelper.ThrowTokenExpected(this, "true", Encoding.UTF8.GetString(buffer, offset, 4)); 
                }
                BufferReader.Advance(4); 

                if (TryGetByte(out ch))
                {
                    if (!IsWhitespace(ch) && ch != JsonGlobals.MemberSeparatorByte && ch != JsonGlobals.EndObjectChar && ch != JsonGlobals.EndCollectionByte) 
                    {
                        XmlExceptionHelper.ThrowTokenExpected(this, "true", Encoding.UTF8.GetString(buffer, offset, 4) + (char) ch); 
                    } 
                }
                MoveToAtomicText().Value.SetValue(ValueHandleType.UTF8, offset, 4); 
            }
            else if (ch == (byte) 'n')
            {
                int offset; 
                byte[] buffer = BufferReader.GetBuffer(4, out offset);
                if (buffer[offset + 1] != (byte) 'u' || 
                    buffer[offset + 2] != (byte) 'l' || 
                    buffer[offset + 3] != (byte) 'l')
                { 
                    XmlExceptionHelper.ThrowTokenExpected(this, "null", Encoding.UTF8.GetString(buffer, offset, 4));
                }
                BufferReader.Advance(4);
                SkipWhitespaceInBufferReader(); 

                if (TryGetByte(out ch)) 
                { 
                    if (ch == JsonGlobals.MemberSeparatorByte || ch == JsonGlobals.EndObjectChar)
                    { 
                        BufferReader.SkipByte();
                    }
                    else if (ch != JsonGlobals.EndCollectionByte)
                    { 
                        XmlExceptionHelper.ThrowTokenExpected(this, "null", Encoding.UTF8.GetString(buffer, offset, 4) + (char) ch);
                    } 
                } 
                else
                { 
                    charactersToSkipOnNextRead[0] = JsonGlobals.MemberSeparatorByte;
                    charactersToSkipOnNextRead[1] = JsonGlobals.EndObjectByte;
                }
                MoveToEndElement(); 
            }
            else if ((ch == (byte) '-') || 
                (((byte) '0' <= ch) && (ch <= (byte) '9')) || 
                (ch == (byte) 'I') ||
                (ch == (byte) 'N')) 
            {
                ReadNumericalText();
            }
            else 
            {
                XmlExceptionHelper.ThrowXmlException(this, 
                    new XmlException(SR2.GetString(SR2.JsonEncounteredUnexpectedCharacter, (char) ch))); 
            }
 
            return true;
        }

        public override decimal ReadContentAsDecimal() 
        {
            string value = ReadContentAsString(); 
            try 
            {
                return decimal.Parse(value, NumberStyles.Float, NumberFormatInfo.InvariantInfo); 
            }
            catch (ArgumentException exception)
            {
                throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlExceptionHelper.CreateConversionException(value, "decimal", exception)); 
            }
            catch (FormatException exception) 
            { 
                throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlExceptionHelper.CreateConversionException(value, "decimal", exception));
            } 
            catch (OverflowException exception)
            {
                throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlExceptionHelper.CreateConversionException(value, "decimal", exception));
            } 
        }
 
        public override int ReadContentAsInt() 
        {
            return ParseInt(ReadContentAsString(), NumberStyles.Float); 
        }

        public override long ReadContentAsLong()
        { 
            string value = ReadContentAsString();
            try 
            { 
                return long.Parse(value, NumberStyles.Float, NumberFormatInfo.InvariantInfo);
            } 
            catch (ArgumentException exception)
            {
                throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlExceptionHelper.CreateConversionException(value, "Int64", exception));
            } 
            catch (FormatException exception)
            { 
                throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlExceptionHelper.CreateConversionException(value, "Int64", exception)); 
            }
            catch (OverflowException exception) 
            {
                throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlExceptionHelper.CreateConversionException(value, "Int64", exception));
            }
        } 

        public override int ReadValueAsBase64(byte[] buffer, int offset, int count) 
        { 
            if (IsAttributeValue)
            { 
                if (buffer == null)
                {
                    throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("buffer"));
                } 
                if (offset < 0)
                { 
                    throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("offset", System.Runtime.Serialization.SR.GetString(System.Runtime.Serialization.SR.ValueMustBeNonNegative))); 
                }
                if (offset > buffer.Length) 
                {
                    throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("offset", System.Runtime.Serialization.SR.GetString(System.Runtime.Serialization.SR.OffsetExceedsBufferSize, buffer.Length)));
                }
                if (count < 0) 
                {
                    throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("count", System.Runtime.Serialization.SR.GetString(System.Runtime.Serialization.SR.ValueMustBeNonNegative))); 
                } 
                if (count > buffer.Length - offset)
                { 
                    throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("count", System.Runtime.Serialization.SR.GetString(System.Runtime.Serialization.SR.SizeExceedsRemainingBufferSpace, buffer.Length - offset)));
                }

                return 0; 
            }
 
            return base.ReadValueAsBase64(buffer, offset, count); 
        }
 
        public override int ReadValueChunk(char[] chars, int offset, int count)
        {
            if (IsAttributeValue)
            { 
                if (chars == null)
                { 
                    throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("chars")); 
                }
                if (offset < 0) 
                {
                    throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("offset", System.Runtime.Serialization.SR.GetString(System.Runtime.Serialization.SR.ValueMustBeNonNegative)));
                }
                if (offset > chars.Length) 
                {
                    throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("offset", System.Runtime.Serialization.SR.GetString(System.Runtime.Serialization.SR.OffsetExceedsBufferSize, chars.Length))); 
                } 
                if (count < 0)
                { 
                    throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("count", System.Runtime.Serialization.SR.GetString(System.Runtime.Serialization.SR.ValueMustBeNonNegative)));
                }
                if (count > chars.Length - offset)
                { 
                    throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("count", System.Runtime.Serialization.SR.GetString(System.Runtime.Serialization.SR.SizeExceedsRemainingBufferSpace, chars.Length - offset)));
                } 
                int actual; 

                string value = UnescapeJsonString(this.Node.ValueAsString); 
                actual = Math.Min(count, value.Length);
                if (actual > 0)
                {
                    value.CopyTo(0, chars, offset, actual); 
                    if (this.Node.QNameType == QNameType.Xmlns)
                    { 
                        this.Node.Namespace.Uri.SetValue(0, 0); 
                    }
                    else 
                    {
                        this.Node.Value.SetValue(ValueHandleType.UTF8, 0, 0);
                    }
                } 
                return actual;
            } 
 
            return base.ReadValueChunk(chars, offset, count);
        } 

        public void SetInput(byte[] buffer, int offset, int count, Encoding encoding, XmlDictionaryReaderQuotas quotas,
            OnXmlDictionaryReaderClose onClose)
        { 
            if (buffer == null)
            { 
                throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("buffer"); 
            }
            if (offset < 0) 
            {
                throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(
                    new ArgumentOutOfRangeException("offset", SR2.GetString(SR2.ValueMustBeNonNegative)));
            } 
            if (offset > buffer.Length)
            { 
                throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError( 
                    new ArgumentOutOfRangeException("offset",
                    SR2.GetString(SR2.JsonOffsetExceedsBufferSize, buffer.Length))); 
            }
            if (count < 0)
            {
                throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError( 
                    new ArgumentOutOfRangeException("count", SR2.GetString(SR2.ValueMustBeNonNegative)));
            } 
            if (count > buffer.Length - offset) 
            {
                throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError( 
                    new ArgumentOutOfRangeException("count",
                    SR2.GetString(SR2.JsonSizeExceedsRemainingBufferSpace,
                    buffer.Length - offset)));
            } 
            MoveToInitial(quotas, onClose);
 
            ArraySegment seg = JsonEncodingStreamWrapper.ProcessBuffer(buffer, offset, count, encoding); 
            BufferReader.SetBuffer(seg.Array, seg.Offset, seg.Count, null, null);
            this.buffered = true; 
            ResetState();
        }

        public void SetInput(Stream stream, Encoding encoding, XmlDictionaryReaderQuotas quotas, 
            OnXmlDictionaryReaderClose onClose)
        { 
            if (stream == null) 
            {
                throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("stream"); 
            }
            MoveToInitial(quotas, onClose);

            stream = new JsonEncodingStreamWrapper(stream, encoding, true); 

            BufferReader.SetBuffer(stream, null, null); 
            this.buffered = false; 
            ResetState();
        } 

        public override void StartCanonicalization(Stream stream, bool includeComments, string[] inclusivePrefixes)
        {
            throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException()); 
        }
 
        internal static void CheckArray(Array array, int offset, int count) 
        {
            if (array == null) 
            {
                throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("array"));
            }
            if (offset < 0) 
            {
                throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("offset", SR2.GetString(SR2.ValueMustBeNonNegative))); 
            } 
            if (offset > array.Length)
            { 
                throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("offset", SR2.GetString(SR2.OffsetExceedsBufferSize, array.Length)));
            }
            if (count < 0)
            { 
                throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("count", SR2.GetString(SR2.ValueMustBeNonNegative)));
            } 
            if (count > array.Length - offset) 
            {
                throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("count", SR2.GetString(SR2.SizeExceedsRemainingBufferSpace, array.Length - offset))); 
            }
        }

        protected override XmlSigningNodeWriter CreateSigningNodeWriter() 
        {
            throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(SR2.GetString(SR2.JsonMethodNotSupported, "CreateSigningNodeWriter"))); 
        } 

        static int BreakText(byte[] buffer, int offset, int length) 
        {
            // See if we might be breaking a utf8 sequence
            if (length > 0 && (buffer[offset + length - 1] & 0x80) == 0x80)
            { 
                // Find the lead char of the utf8 sequence (0x11xxxxxx)
                int originalLength = length; 
                do 
                {
                    length--; 
                } while (length > 0 && (buffer[offset + length] & 0xC0) != 0xC0);
                // Couldn't find the lead char
                if (length == 0)
                { 
                    return originalLength; // Invalid utf8 sequence - can't break
                } 
                // Count how many bytes follow the lead char 
                byte b = (byte)(buffer[offset + length] << 2);
                int byteCount = 2; 
                while ((b & 0x80) == 0x80)
                {
                    b = (byte)(b << 1);
                    byteCount++; 
                    // There shouldn't be more than 3 bytes following the lead char
                    if (byteCount > 4) 
                    { 
                        return originalLength; // Invalid utf8 sequence - can't break
                    } 
                }
                if (length + byteCount == originalLength)
                {
                    return originalLength; // sequence fits exactly 
                }
                if (length == 0) 
                { 
                    return originalLength; // Quota too small to read a char
                } 
            }
            return length;
        }
 
        static int ComputeNumericalTextLength(byte[] buffer, int offset, int offsetMax)
        { 
            int beginOffset = offset; 
            while (offset < offsetMax)
            { 
                byte ch = buffer[offset];
                if (ch == JsonGlobals.MemberSeparatorByte || ch == JsonGlobals.EndObjectByte || ch == JsonGlobals.EndCollectionByte
                    || IsWhitespace(ch))
                { 
                    break;
                } 
                offset++; 
            }
            return offset - beginOffset; 
        }

        static int ComputeQuotedTextLengthUntilEndQuote(byte[] buffer, int offset, int offsetMax, out bool escaped)
        { 
            // Assumes that for quoted text "someText", the first " has been consumed.
            // For original text "someText", buffer passed in is someText". 
            // This method returns return 8 for someText" (s, o, m, e, T, e, x, t). 
            int beginOffset = offset;
            escaped = false; 

            while (offset < offsetMax)
            {
                byte ch = buffer[offset]; 
                if (ch < 0x20)
                { 
                    throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new FormatException(SR2.GetString(SR2.InvalidCharacterEncountered, (char) ch))); 
                }
                else if (ch == (byte) '\\' || ch == 0xEF) 
                {
                    escaped = true;
                    break;
                } 
                else if (ch == JsonGlobals.QuoteByte)
                { 
                    break; 
                }
 
                offset++;
            }

            return offset - beginOffset; 
        }
 
 
        // From JSON spec:
        // ws = *( 
        //    %x20 /              ; Space
        //    %x09 /              ; Horizontal tab
        //    %x0A /              ; Line feed or New line
        //    %x0D                ; Carriage return 
        // )
        static bool IsWhitespace(byte ch) 
        { 
            return ((ch == 0x20) || (ch == 0x09) || (ch == 0x0A) || (ch == 0x0D));
        } 

        static char ParseChar(string value, NumberStyles style)
        {
            int intValue = ParseInt(value, style); 
            try
            { 
                return Convert.ToChar(intValue); 
            }
            catch (OverflowException exception) 
            {
                throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlExceptionHelper.CreateConversionException(value, "char", exception));
            }
        } 

        static int ParseInt(string value, NumberStyles style) 
        { 
            try
            { 
                return int.Parse(value, style, NumberFormatInfo.InvariantInfo);
            }
            catch (ArgumentException exception)
            { 
                throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlExceptionHelper.CreateConversionException(value, "Int32", exception));
            } 
            catch (FormatException exception) 
            {
                throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlExceptionHelper.CreateConversionException(value, "Int32", exception)); 
            }
            catch (OverflowException exception)
            {
                throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlExceptionHelper.CreateConversionException(value, "Int32", exception)); 
            }
        } 
 
        void BufferElement()
        { 
            int elementOffset = BufferReader.Offset;
            const int byteCount = 128;
            bool done = false;
            byte quoteChar = 0; 
            while (!done)
            { 
                int offset; 
                int offsetMax;
                byte[] buffer = BufferReader.GetBuffer(byteCount, out offset, out offsetMax); 
                if (offset + byteCount != offsetMax)
                {
                    break;
                } 
                for (int i = offset; i < offsetMax && !done; i++)
                { 
                    byte b = buffer[i]; 
                    if (b == '\\')
                    { 
                        i++;
                        if (i >= offsetMax)
                        {
                            break; 
                        }
                    } 
                    else if (quoteChar == 0) 
                    {
                        if (b == (byte) '\'' || b == JsonGlobals.QuoteByte) 
                        {
                            quoteChar = b;
                        }
                        if (b == JsonGlobals.NameValueSeparatorByte) 
                        {
                            done = true; 
                        } 
                    }
                    else 
                    {
                        if (b == quoteChar)
                        {
                            quoteChar = 0; 
                        }
                    } 
                } 
                BufferReader.Advance(byteCount);
            } 
            BufferReader.Offset = elementOffset;
        }

        void EnterJsonScope(JsonNodeType currentNodeType) 
        {
            scopeDepth++; 
            if (scopes == null) 
            {
                scopes = new JsonNodeType[4]; 
            }
            else if (scopes.Length == scopeDepth)
            {
                JsonNodeType[] newScopes = new JsonNodeType[scopeDepth * 2]; 
                Array.Copy(scopes, newScopes, scopeDepth);
                scopes = newScopes; 
            } 
            scopes[scopeDepth] = currentNodeType;
        } 

        JsonNodeType ExitJsonScope()
        {
            JsonNodeType nodeTypeToReturn = scopes[scopeDepth]; 
            scopes[scopeDepth] = JsonNodeType.None;
            scopeDepth--; 
            return nodeTypeToReturn; 
        }
 
        new void MoveToEndElement()
        {
            ExitJsonScope();
            base.MoveToEndElement(); 
        }
 
        void MoveToInitial(XmlDictionaryReaderQuotas quotas, OnXmlDictionaryReaderClose onClose) 
        {
            MoveToInitial(quotas); 
            this.maxBytesPerRead = quotas.MaxBytesPerRead;
            this.onReaderClose = onClose;
        }
 
        void ParseAndSetLocalName()
        { 
            XmlElementNode elementNode = EnterScope(); 
            elementNode.NameOffset = BufferReader.Offset;
 
            do
            {
                if (BufferReader.GetByte() == '\\')
                { 
                    ReadEscapedCharacter(false); //  moveToText
                } 
                else 
                {
                    ReadQuotedText(false); //  moveToText 
                }
            } while (complexTextMode == JsonComplexTextMode.QuotedText);

            int actualOffset = BufferReader.Offset - 1; //  -1 to ignore " at end of local name 
            elementNode.LocalName.SetValue(elementNode.NameOffset, actualOffset - elementNode.NameOffset);
            elementNode.NameLength = actualOffset - elementNode.NameOffset; 
            elementNode.Namespace.Uri.SetValue(elementNode.NameOffset, 0); 
            elementNode.Prefix.SetValue(PrefixHandleType.Empty);
            elementNode.IsEmptyElement = false; 
            elementNode.ExitScope = false;
            elementNode.BufferOffset = actualOffset;

            int currentCharacter = (int) BufferReader.GetByte(elementNode.NameOffset); 
            if ((charType[currentCharacter] & CharType.FirstName) == 0)
            { 
                SetJsonNameWithMapping(elementNode); 
            }
            else 
            {
                for (int i = 0, offset = elementNode.NameOffset; i < elementNode.NameLength; i++, offset++)
                {
                    currentCharacter = (int) BufferReader.GetByte(offset); 
                    if ((charType[currentCharacter] & CharType.Name) == 0 || currentCharacter >= 0x80)
                    { 
                        SetJsonNameWithMapping(elementNode); 
                        break;
                    } 
                }
            }
        }
 
        void ParseStartElement()
        { 
            if (!buffered) 
            {
                BufferElement(); 
            }

            expectingFirstElementInNonPrimitiveChild = false;
 
            byte ch = BufferReader.GetByte();
            if (ch == JsonGlobals.QuoteByte) 
            { 
                BufferReader.SkipByte();
 
                ParseAndSetLocalName();

                SkipWhitespaceInBufferReader();
                SkipExpectedByteInBufferReader(JsonGlobals.NameValueSeparatorByte); 
                SkipWhitespaceInBufferReader();
 
 
                if (BufferReader.GetByte() == JsonGlobals.ObjectByte)
                { 
                    BufferReader.SkipByte();
                    expectingFirstElementInNonPrimitiveChild = true;
                }
                ReadAttributes(); 
            }
            else 
            { 
                // " and } are the only two valid characters that may follow a {
                XmlExceptionHelper.ThrowTokenExpected(this, "\"", (char) ch); 
            }
        }

        void ReadAttributes() 
        {
            XmlAttributeNode attribute = AddAttribute(); 
            attribute.LocalName.SetConstantValue(StringHandleConstStringType.Type); 
            attribute.Namespace.Uri.SetValue(0, 0);
            attribute.Prefix.SetValue(PrefixHandleType.Empty); 

            SkipWhitespaceInBufferReader();
            byte nextByte = BufferReader.GetByte();
            switch (nextByte) 
            {
                case JsonGlobals.QuoteByte: 
                    if (!expectingFirstElementInNonPrimitiveChild) 
                    {
                        attribute.Value.SetConstantValue(ValueHandleConstStringType.String); 
                    }
                    else
                    {
                        attribute.Value.SetConstantValue(ValueHandleConstStringType.Object); 
                        ReadServerTypeAttribute(true);
                    } 
                    break; 
                case (byte) 'n':
                    attribute.Value.SetConstantValue(ValueHandleConstStringType.Null); 
                    break;
                case (byte) 't':
                case (byte) 'f':
                    attribute.Value.SetConstantValue(ValueHandleConstStringType.Boolean); 
                    break;
                case JsonGlobals.ObjectByte: 
                    attribute.Value.SetConstantValue(ValueHandleConstStringType.Object); 
                    ReadServerTypeAttribute(false);
                    break; 
                case JsonGlobals.EndObjectByte:
                    if (expectingFirstElementInNonPrimitiveChild)
                    {
                        attribute.Value.SetConstantValue(ValueHandleConstStringType.Object); 
                    }
                    else 
                    { 
                        XmlExceptionHelper.ThrowXmlException(this,
                            new XmlException(SR2.GetString(SR2.JsonEncounteredUnexpectedCharacter, (char) nextByte))); 
                    }
                    break;
                case JsonGlobals.CollectionByte:
                    attribute.Value.SetConstantValue(ValueHandleConstStringType.Array); 
                    BufferReader.SkipByte();
                    EnterJsonScope(JsonNodeType.Collection); 
                    break; 
                default:
                    if (nextByte == '-' || 
                        (nextByte <= '9' && nextByte >= '0') ||
                        nextByte == 'N' ||
                        nextByte == 'I')
                    { 
                        attribute.Value.SetConstantValue(ValueHandleConstStringType.Number);
                    } 
                    else 
                    {
                        XmlExceptionHelper.ThrowXmlException(this, 
                            new XmlException(SR2.GetString(SR2.JsonEncounteredUnexpectedCharacter, (char) nextByte)));
                    }
                    break;
            } 
        }
 
        void ReadEscapedCharacter(bool moveToText) 
        {
            BufferReader.SkipByte(); 
            char ch = (char) BufferReader.GetByte();
            if (ch == 'u')
            {
                BufferReader.SkipByte(); 
                int offset;
                byte[] buffer = BufferReader.GetBuffer(5, out offset); 
                string bufferAsString = Encoding.UTF8.GetString(buffer, offset, 4); 
                BufferReader.Advance(4);
                int charValue = ParseChar(bufferAsString, NumberStyles.HexNumber); 
                if (Char.IsHighSurrogate((char) charValue))
                {
                    byte nextByte = BufferReader.GetByte();
                    if (nextByte == (byte) '\\') 
                    {
                        BufferReader.SkipByte(); 
                        SkipExpectedByteInBufferReader((byte) 'u'); 
                        buffer = BufferReader.GetBuffer(5, out offset);
                        bufferAsString = Encoding.UTF8.GetString(buffer, offset, 4); 
                        BufferReader.Advance(4);
                        char lowChar = ParseChar(bufferAsString, NumberStyles.HexNumber);
                        if (!Char.IsLowSurrogate(lowChar))
                        { 
                            XmlExceptionHelper.ThrowXmlException(this,
                                new XmlException(System.Runtime.Serialization.SR.GetString(System.Runtime.Serialization.SR.XmlInvalidLowSurrogate, bufferAsString))); 
                        } 
                        charValue = new SurrogateChar(lowChar, (char) charValue).Char;
                    } 
                }

                if (buffer[offset + 4] == JsonGlobals.QuoteByte)
                { 
                    BufferReader.SkipByte();
                    if (moveToText) 
                    { 
                        MoveToAtomicText().Value.SetCharValue(charValue);
                    } 
                    complexTextMode = JsonComplexTextMode.None;
                }
                else
                { 
                    if (moveToText)
                    { 
                        MoveToComplexText().Value.SetCharValue(charValue); 
                    }
                    complexTextMode = JsonComplexTextMode.QuotedText; 
                }
            }
            else
            { 
                switch (ch)
                { 
                    case 'b': 
                        ch = '\b';
                        break; 
                    case 'f':
                        ch = '\f';
                        break;
                    case 'n': 
                        ch = '\n';
                        break; 
                    case 'r': 
                        ch = '\r';
                        break; 
                    case 't':
                        ch = '\t';
                        break;
                    case '\"': 
                    case '\\':
                    case '/': 
                        // Do nothing. These are the actual unescaped values. 
                        break;
                    default: 
                        XmlExceptionHelper.ThrowXmlException(this,
                            new XmlException(SR2.GetString(SR2.JsonEncounteredUnexpectedCharacter, (char) ch)));
                        break;
                } 
                BufferReader.SkipByte();
                if (BufferReader.GetByte() == JsonGlobals.QuoteByte) 
                { 
                    BufferReader.SkipByte();
                    if (moveToText) 
                    {
                        MoveToAtomicText().Value.SetCharValue(ch);
                    }
                    complexTextMode = JsonComplexTextMode.None; 
                }
                else 
                { 
                    if (moveToText)
                    { 
                        MoveToComplexText().Value.SetCharValue(ch);
                    }
                    complexTextMode = JsonComplexTextMode.QuotedText;
                } 
            }
        } 
 
        void ReadNonExistentElementName(StringHandleConstStringType elementName)
        { 
            EnterJsonScope(JsonNodeType.Object);
            XmlElementNode elementNode = EnterScope();
            elementNode.LocalName.SetConstantValue(elementName);
            elementNode.Namespace.Uri.SetValue(elementNode.NameOffset, 0); 
            elementNode.Prefix.SetValue(PrefixHandleType.Empty);
            elementNode.BufferOffset = BufferReader.Offset; 
            elementNode.IsEmptyElement = false; 
            elementNode.ExitScope = false;
            ReadAttributes(); 
        }

        int ReadNonFFFE()
        { 
            int off;
            byte[] buff = BufferReader.GetBuffer(3, out off); 
            if (buff[off + 1] == 0xBF && (buff[off + 2] == 0xBE || buff[off + 2] == 0xBF)) 
            {
                XmlExceptionHelper.ThrowXmlException(this, new XmlException(SR2.GetString(SR2.JsonInvalidFFFE))); 
            }
            return 3;
        }
 
        void ReadNumericalText()
        { 
            byte[] buffer; 
            int offset;
            int offsetMax; 
            int length;

            if (buffered)
            { 
                buffer = BufferReader.GetBuffer(out offset, out offsetMax);
                length = ComputeNumericalTextLength(buffer, offset, offsetMax); 
            } 
            else
            { 
                buffer = BufferReader.GetBuffer(MaxTextChunk, out offset, out offsetMax);
                length = ComputeNumericalTextLength(buffer, offset, offsetMax);
                length = BreakText(buffer, offset, length);
            } 
            BufferReader.Advance(length);
 
            if (offset <= offsetMax - length) 
            {
                MoveToAtomicText().Value.SetValue(ValueHandleType.UTF8, offset, length); 
                complexTextMode = JsonComplexTextMode.None;
            }
            else
            { 
                MoveToComplexText().Value.SetValue(ValueHandleType.UTF8, offset, length);
                complexTextMode = JsonComplexTextMode.NumericalText; 
            } 
        }
 
        void ReadQuotedText(bool moveToText)
        {
            byte[] buffer;
            int offset; 
            int offsetMax;
            int length; 
            bool escaped; 

            if (buffered) 
            {
                buffer = BufferReader.GetBuffer(out offset, out offsetMax);
                length = ComputeQuotedTextLengthUntilEndQuote(buffer, offset, offsetMax, out escaped);
            } 
            else
            { 
                buffer = BufferReader.GetBuffer(MaxTextChunk, out offset, out offsetMax); 
                length = ComputeQuotedTextLengthUntilEndQuote(buffer, offset, offsetMax, out escaped);
                length = BreakText(buffer, offset, length); 
            }

            if (escaped && BufferReader.GetByte() == 0xEF)
            { 
                offset = BufferReader.Offset;
                length = ReadNonFFFE(); 
            } 

            BufferReader.Advance(length); 


            if (!escaped && (offset < offsetMax - length))
            { 
                if (moveToText)
                { 
                    MoveToAtomicText().Value.SetValue(ValueHandleType.UTF8, offset, length); 
                }
                SkipExpectedByteInBufferReader(JsonGlobals.QuoteByte); 
                complexTextMode = JsonComplexTextMode.None;
            }
            else
            { 
                if ((length == 0) && escaped)
                { 
                    ReadEscapedCharacter(moveToText); 
                }
                else 
                {
                    if (moveToText)
                    {
                        MoveToComplexText().Value.SetValue(ValueHandleType.UTF8, offset, length); 
                    }
                    complexTextMode = JsonComplexTextMode.QuotedText; 
                } 
            }
        } 

        void ReadServerTypeAttribute(bool consumedObjectChar)
        {
            int offset; 
            int offsetMax;
            int correction = consumedObjectChar ? -1 : 0; 
            byte[] buffer = BufferReader.GetBuffer(9 + correction, out offset, out offsetMax); 
            if (offset + 9 + correction <= offsetMax)
            { 
                if (buffer[offset + correction + 1] == (byte) '\"' &&
                    buffer[offset + correction + 2] == (byte) '_' &&
                    buffer[offset + correction + 3] == (byte) '_' &&
                    buffer[offset + correction + 4] == (byte) 't' && 
                    buffer[offset + correction + 5] == (byte) 'y' &&
                    buffer[offset + correction + 6] == (byte) 'p' && 
                    buffer[offset + correction + 7] == (byte) 'e' && 
                    buffer[offset + correction + 8] == (byte) '\"')
                { 
                    XmlAttributeNode attribute = AddAttribute();

                    attribute.LocalName.SetValue(offset + 2 + correction, 6);
                    attribute.Namespace.Uri.SetValue(0, 0); 
                    attribute.Prefix.SetValue(PrefixHandleType.Empty);
                    BufferReader.Advance(9 + correction); 
 
                    if (!buffered)
                    { 
                        BufferElement();
                    }

                    SkipWhitespaceInBufferReader(); 
                    SkipExpectedByteInBufferReader(JsonGlobals.NameValueSeparatorByte);
                    SkipWhitespaceInBufferReader(); 
                    SkipExpectedByteInBufferReader(JsonGlobals.QuoteByte); 

                    buffer = BufferReader.GetBuffer(out offset, out offsetMax); 

                    do
                    {
                        if (BufferReader.GetByte() == '\\') 
                        {
                            ReadEscapedCharacter(false); //  moveToText 
                        } 
                        else
                        { 
                            ReadQuotedText(false); //  moveToText
                        }
                    } while (complexTextMode == JsonComplexTextMode.QuotedText);
 
                    attribute.Value.SetValue(ValueHandleType.UTF8, offset, BufferReader.Offset - 1 - offset);
 
                    SkipWhitespaceInBufferReader(); 

                    if (BufferReader.GetByte() == JsonGlobals.MemberSeparatorByte) 
                    {
                        BufferReader.SkipByte();
                        readServerTypeElement = true;
                    } 
                    else if (BufferReader.GetByte() == JsonGlobals.EndObjectByte)
                    { 
                        BufferReader.SkipByte(); 
                        readServerTypeElement = false;
                        expectingFirstElementInNonPrimitiveChild = false; 
                    }
                    else
                    {
                        readServerTypeElement = true; 
                    }
 
                } 
            }
        } 

        void ResetState()
        {
            complexTextMode = JsonComplexTextMode.None; 
            expectingFirstElementInNonPrimitiveChild = false;
            charactersToSkipOnNextRead = new byte[2]; 
            scopeDepth = 0; 
            if ((scopes != null) && (scopes.Length > JsonGlobals.maxScopeSize))
            { 
                scopes = null;
            }
        }
 
        void SetJsonNameWithMapping(XmlElementNode elementNode)
        { 
            Namespace ns = AddNamespace(); 
            ns.Prefix.SetValue(PrefixHandleType.A);
            ns.Uri.SetConstantValue(StringHandleConstStringType.Item); 
            AddXmlnsAttribute(ns);

            XmlAttributeNode attribute = AddAttribute();
            attribute.LocalName.SetConstantValue(StringHandleConstStringType.Item); 
            attribute.Namespace.Uri.SetValue(0, 0);
            attribute.Prefix.SetValue(PrefixHandleType.Empty); 
            attribute.Value.SetValue(ValueHandleType.UTF8, elementNode.NameOffset, elementNode.NameLength); 

            elementNode.NameLength = 0; 
            elementNode.Prefix.SetValue(PrefixHandleType.A);
            elementNode.LocalName.SetConstantValue(StringHandleConstStringType.Item);
            elementNode.Namespace = ns;
        } 

        void SkipExpectedByteInBufferReader(byte characterToSkip) 
        { 
            if (BufferReader.GetByte() != characterToSkip)
            { 
                XmlExceptionHelper.ThrowTokenExpected(this, ((char) characterToSkip).ToString(), (char) BufferReader.GetByte());
            }
            BufferReader.SkipByte();
        } 

        void SkipWhitespaceInBufferReader() 
        { 
            byte ch;
            while (TryGetByte(out ch) && IsWhitespace(ch)) 
            {
                BufferReader.SkipByte();
            }
        } 

        bool TryGetByte(out byte ch) 
        { 
            int offset, offsetMax;
            byte[] buffer = BufferReader.GetBuffer(1, out offset, out offsetMax); 

            if (offset < offsetMax)
            {
                ch = buffer[offset]; 
                return true;
            } 
            else 
            {
                ch = (byte) '\0'; 
                return false;
            }
        }
 
        string UnescapeJsonString(string val)
        { 
            if (val == null) 
            {
                return null; 
            }

            StringBuilder sb = null;
            int startIndex = 0, count = 0; 
            for (int i = 0; i < val.Length; i++)
            { 
                if (val[i] == '\\') 
                {
                    i++; 
                    if (sb == null)
                    {
                        sb = new StringBuilder();
                    } 
                    sb.Append(val, startIndex, count);
                    Fx.Assert(i < val.Length, "Found that an '\' was the last character in a string. ReadServerTypeAttriute validates that the escape sequence is valid when it calls ReadQuotedText and ReadEscapedCharacter"); 
                    if (i >= val.Length) 
                    {
                        XmlExceptionHelper.ThrowXmlException(this, new XmlException(SR2.GetString(SR2.JsonEncounteredUnexpectedCharacter, val[i]))); 
                    }
                    switch (val[i])
                    {
                        case '"': 
                        case '\'':
                        case '/': 
                        case '\\': 
                            sb.Append(val[i]);
                            break; 
                        case 'b':
                            sb.Append('\b');
                            break;
                        case 'f': 
                            sb.Append('\f');
                            break; 
                        case 'n': 
                            sb.Append('\n');
                            break; 
                        case 'r':
                            sb.Append('\r');
                            break;
                        case 't': 
                            sb.Append('\t');
                            break; 
                        case 'u': 
                            if ((i + 3) >= val.Length)
                            { 
                                XmlExceptionHelper.ThrowXmlException(this,
                                    new XmlException(SR2.GetString(SR2.JsonEncounteredUnexpectedCharacter, val[i])));
                            }
                            sb.Append(ParseChar(val.Substring(i + 1, 4), NumberStyles.HexNumber)); 
                            i += 4;
                            break; 
                    } 
                    startIndex = i + 1;
                    count = 0; 
                }
                else
                {
                    count++; 
                }
            } 
            if (sb == null) 
            {
                return val; 
            }
            if (count > 0)
            {
                sb.Append(val, startIndex, count); 
            }
 
            return sb.ToString(); 
        }
 
        static class CharType
        {
            public const byte FirstName = 0x01;
            public const byte Name = 0x02; 
            public const byte None = 0x00;
        } 
    } 
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.


                        

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