private string GetAttributeText(int i)
 {
     string str2;
     string val = this.attributes[i].val;
     if (val != null)
     {
         return val;
     }
     int pos = this.pos;
     try
     {
         this.pos = this.attributes[i].contentPos;
         BinXmlToken token = this.RescanNextToken();
         if ((BinXmlToken.Attr == token) || (BinXmlToken.EndAttrs == token))
         {
             return "";
         }
         this.token = token;
         this.ReScanOverValue(token);
         str2 = this.ValueAsString(token);
     }
     finally
     {
         this.pos = pos;
     }
     return str2;
 }
        public override bool MoveToElement() {
            switch (this.state) {
                case ScanState.Attr:
                case ScanState.AttrVal:
                case ScanState.AttrValPseudoValue:
                    this.attrIndex = 0;
                    this.qnameOther = this.qnameElement;
                    if (XmlNodeType.Element == this.parentNodeType)
                        this.token = BinXmlToken.Element;
                    else if (XmlNodeType.XmlDeclaration == this.parentNodeType)
                        this.token = BinXmlToken.XmlDecl;
                    else if (XmlNodeType.DocumentType == this.parentNodeType)
                        this.token = BinXmlToken.DocType;
                    else
                        Debug.Fail("Unexpected parent NodeType");
                    this.nodetype = this.parentNodeType;
                    this.state = ScanState.Doc;
                    this.pos = this.posAfterAttrs;
                    this.stringValue = null;
                    return true;

                case ScanState.XmlText:
                    return UpdateFromTextReader(this.textXmlReader.MoveToElement());

                default:
                    return false;
            }
        }
 public override void Close() {
     this.state = ScanState.Closed;
     this.nodetype = XmlNodeType.None;
     this.token = BinXmlToken.Error;
     this.stringValue = null;
     if (null != this.textXmlReader) {
         this.textXmlReader.Close();
         this.textXmlReader = null;
     }
     if (null != this.inStrm && closeInput)
         this.inStrm.Close();
     this.inStrm = null;
     this.pos = this.end = 0;
 }
        string ValueAsString(BinXmlToken token) {
            try {
                CheckValueTokenBounds();
                switch ( token ) {
                    case BinXmlToken.SQL_NCHAR:
                    case BinXmlToken.SQL_NVARCHAR:
                    case BinXmlToken.SQL_NTEXT:
                        return GetString( this.tokDataPos, this.tokLen );

                    case BinXmlToken.XSD_BOOLEAN: {
                            if ( 0 == this.data[this.tokDataPos] )
                                return "false";
                            else
                                return "true";
                        }

                    case BinXmlToken.SQL_BIT:
                    case BinXmlToken.SQL_TINYINT:
                    case BinXmlToken.SQL_SMALLINT:
                    case BinXmlToken.SQL_INT:
                    case BinXmlToken.SQL_BIGINT:
                    case BinXmlToken.XSD_BYTE:
                    case BinXmlToken.XSD_UNSIGNEDSHORT:
                    case BinXmlToken.XSD_UNSIGNEDINT:
                        return ValueAsLong().ToString( CultureInfo.InvariantCulture );

                    case BinXmlToken.XSD_UNSIGNEDLONG:
                        return ValueAsULong().ToString( CultureInfo.InvariantCulture );

                    case BinXmlToken.SQL_REAL:
                        return XmlConvert.ToString( GetSingle( this.tokDataPos ) );

                    case BinXmlToken.SQL_FLOAT:
                        return XmlConvert.ToString( GetDouble( this.tokDataPos ) );

                    case BinXmlToken.SQL_UUID: {
                            int a; short b, c;
                            int pos = this.tokDataPos;
                            a = GetInt32( pos );
                            b = GetInt16( pos + 4 );
                            c = GetInt16( pos + 6 );
                            Guid v = new Guid( a, b, c, data[pos + 8], data[pos + 9], data[pos + 10], data[pos + 11], data[pos + 12], data[pos + 13], data[pos + 14], data[pos + 15] );
                            return v.ToString();
                        }

                    case BinXmlToken.SQL_SMALLMONEY: {
                            BinXmlSqlMoney v = new BinXmlSqlMoney( GetInt32( this.tokDataPos ) );
                            return v.ToString();
                        }
                    case BinXmlToken.SQL_MONEY: {
                            BinXmlSqlMoney v = new BinXmlSqlMoney( GetInt64( this.tokDataPos ) );
                            return v.ToString();
                        }

                    case BinXmlToken.XSD_DECIMAL:
                    case BinXmlToken.SQL_DECIMAL:
                    case BinXmlToken.SQL_NUMERIC: {
                            BinXmlSqlDecimal v = new BinXmlSqlDecimal( this.data, this.tokDataPos, token == BinXmlToken.XSD_DECIMAL );
                            return v.ToString();
                        }

                    case BinXmlToken.SQL_CHAR:
                    case BinXmlToken.SQL_VARCHAR:
                    case BinXmlToken.SQL_TEXT: {
                            int pos = this.tokDataPos;
                            int codepage = GetInt32( pos );
                            Encoding enc = System.Text.Encoding.GetEncoding( codepage );
                            return enc.GetString( this.data, pos + 4, this.tokLen - 4 );
                        }

                    case BinXmlToken.SQL_VARBINARY:
                    case BinXmlToken.SQL_BINARY:
                    case BinXmlToken.SQL_IMAGE:
                    case BinXmlToken.SQL_UDT:
                    case BinXmlToken.XSD_BASE64: {
                            return Convert.ToBase64String( this.data, this.tokDataPos, this.tokLen );
                        }

                    case BinXmlToken.XSD_BINHEX:
                        return BinHexEncoder.Encode( this.data, this.tokDataPos, this.tokLen );

                    case BinXmlToken.SQL_DATETIME:
                    case BinXmlToken.SQL_SMALLDATETIME:
                    case BinXmlToken.XSD_TIME:
                    case BinXmlToken.XSD_DATE:
                    case BinXmlToken.XSD_DATETIME:
                    case BinXmlToken.XSD_KATMAI_DATE:
                    case BinXmlToken.XSD_KATMAI_DATETIME:
                    case BinXmlToken.XSD_KATMAI_TIME:
                    case BinXmlToken.XSD_KATMAI_DATEOFFSET:
                    case BinXmlToken.XSD_KATMAI_DATETIMEOFFSET:
                    case BinXmlToken.XSD_KATMAI_TIMEOFFSET:
                        return ValueAsDateTimeString();

                    case BinXmlToken.XSD_QNAME: {
                            int nameNum = ParseMB32( this.tokDataPos );
                            if ( nameNum < 0 || nameNum >= this.symbolTables.qnameCount )
                                throw new XmlException( Res.XmlBin_InvalidQNameID, String.Empty );
                            QName qname = this.symbolTables.qnametable[nameNum];
                            if ( qname.prefix.Length == 0 )
                                return qname.localname;
                            else
                                return String.Concat( qname.prefix, ":", qname.localname );
                        }

                    default:
                        throw ThrowUnexpectedToken( this.token );
                }
            }
            catch {
                this.state = ScanState.Error;
                throw;
            }
        }
        object ValueAs(BinXmlToken token, Type returnType, IXmlNamespaceResolver namespaceResolver) {
            object value;
            CheckValueTokenBounds();
            switch (token) {
                case BinXmlToken.SQL_NCHAR:
                case BinXmlToken.SQL_NVARCHAR:
                case BinXmlToken.SQL_NTEXT:
                    value = GetValueConverter(XmlTypeCode.UntypedAtomic).ChangeType(
                        GetString(this.tokDataPos, this.tokLen),
                        returnType, namespaceResolver);
                    break;

                case BinXmlToken.XSD_BOOLEAN:
                    value = GetValueConverter(XmlTypeCode.Boolean).ChangeType(
                        (0 != this.data[this.tokDataPos]),
                        returnType, namespaceResolver);
                    break;

                case BinXmlToken.SQL_BIT:
                    value = GetValueConverter(XmlTypeCode.NonNegativeInteger).ChangeType(
                        (Int32)this.data[this.tokDataPos],
                        returnType, namespaceResolver);
                    break;

                case BinXmlToken.SQL_TINYINT:
                    value = GetValueConverter(XmlTypeCode.UnsignedByte).ChangeType(
                        this.data[this.tokDataPos],
                        returnType, namespaceResolver);
                    break;

                case BinXmlToken.SQL_SMALLINT: {
                        int v = GetInt16(this.tokDataPos);
                        value = GetValueConverter(XmlTypeCode.Short).ChangeType(
                            v, returnType, namespaceResolver);
                        break;
                    }
                case BinXmlToken.SQL_INT: {
                        int v = GetInt32(this.tokDataPos);
                        value = GetValueConverter(XmlTypeCode.Int).ChangeType(
                            v, returnType, namespaceResolver);
                        break;
                    }
                case BinXmlToken.SQL_BIGINT: {
                        long v = GetInt64(this.tokDataPos);
                        value = GetValueConverter(XmlTypeCode.Long).ChangeType(
                            v, returnType, namespaceResolver);
                        break;
                    }
                case BinXmlToken.XSD_BYTE: {
                        value = GetValueConverter(XmlTypeCode.Byte).ChangeType(
                            (int)unchecked((sbyte)this.data[this.tokDataPos]),
                            returnType, namespaceResolver);
                        break;
                    }
                case BinXmlToken.XSD_UNSIGNEDSHORT: {
                        int v = GetUInt16(this.tokDataPos);
                        value = GetValueConverter(XmlTypeCode.UnsignedShort).ChangeType(
                            v, returnType, namespaceResolver);
                        break;
                    }
                case BinXmlToken.XSD_UNSIGNEDINT: {
                        long v = GetUInt32(this.tokDataPos);
                        value = GetValueConverter(XmlTypeCode.UnsignedInt).ChangeType(
                            v, returnType, namespaceResolver);
                        break;
                    }
                case BinXmlToken.XSD_UNSIGNEDLONG: {
                        Decimal v = (Decimal)GetUInt64(this.tokDataPos);
                        value = GetValueConverter(XmlTypeCode.UnsignedLong).ChangeType(
                            v, returnType, namespaceResolver);
                        break;
                    }
                case BinXmlToken.SQL_REAL: {
                        Single v = GetSingle(this.tokDataPos);
                        value = GetValueConverter(XmlTypeCode.Float).ChangeType(
                            v, returnType, namespaceResolver);
                        break;
                    }
                case BinXmlToken.SQL_FLOAT: {
                        Double v = GetDouble(this.tokDataPos);
                        value = GetValueConverter(XmlTypeCode.Double).ChangeType(
                            v, returnType, namespaceResolver);
                        break;
                    }
                case BinXmlToken.SQL_UUID:
                    value = GetValueConverter(XmlTypeCode.String).ChangeType(
                        this.ValueAsString(token), returnType, namespaceResolver);
                    break;

                case BinXmlToken.SQL_SMALLMONEY:
                    value = GetValueConverter(XmlTypeCode.Decimal).ChangeType(
                        (new BinXmlSqlMoney(GetInt32(this.tokDataPos))).ToDecimal(),
                        returnType, namespaceResolver);
                    break;

                case BinXmlToken.SQL_MONEY:
                    value = GetValueConverter(XmlTypeCode.Decimal).ChangeType(
                        (new BinXmlSqlMoney(GetInt64(this.tokDataPos))).ToDecimal(),
                        returnType, namespaceResolver);
                    break;

                case BinXmlToken.XSD_DECIMAL:
                case BinXmlToken.SQL_DECIMAL:
                case BinXmlToken.SQL_NUMERIC:
                    value = GetValueConverter(XmlTypeCode.Decimal).ChangeType(
                        (new BinXmlSqlDecimal(this.data, this.tokDataPos, token == BinXmlToken.XSD_DECIMAL)).ToDecimal(),
                        returnType, namespaceResolver);
                    break;

                case BinXmlToken.SQL_CHAR:
                case BinXmlToken.SQL_VARCHAR:
                case BinXmlToken.SQL_TEXT: {
                        int pos = this.tokDataPos;
                        int codepage = GetInt32(pos);
                        Encoding enc = System.Text.Encoding.GetEncoding(codepage);
                        value = GetValueConverter(XmlTypeCode.UntypedAtomic).ChangeType(
                            enc.GetString(this.data, pos + 4, this.tokLen - 4),
                            returnType, namespaceResolver);
                        break;
                    }

                case BinXmlToken.SQL_VARBINARY:
                case BinXmlToken.SQL_BINARY:
                case BinXmlToken.SQL_IMAGE:
                case BinXmlToken.SQL_UDT:
                case BinXmlToken.XSD_BASE64:
                case BinXmlToken.XSD_BINHEX: {
                        byte[] data = new byte[this.tokLen];
                        Array.Copy(this.data, this.tokDataPos, data, 0, this.tokLen);
                        value = GetValueConverter(token == BinXmlToken.XSD_BINHEX ? XmlTypeCode.HexBinary : XmlTypeCode.Base64Binary).ChangeType(
                            data, returnType, namespaceResolver);
                        break;
                    }

                case BinXmlToken.SQL_DATETIME:
                case BinXmlToken.SQL_SMALLDATETIME:
                case BinXmlToken.XSD_DATETIME:
                case BinXmlToken.XSD_KATMAI_DATE:
                case BinXmlToken.XSD_KATMAI_DATETIME:
                case BinXmlToken.XSD_KATMAI_TIME:
                    value = GetValueConverter(XmlTypeCode.DateTime).ChangeType(
                        ValueAsDateTime(),
                        returnType, namespaceResolver);
                    break;

                case BinXmlToken.XSD_KATMAI_DATEOFFSET:
                case BinXmlToken.XSD_KATMAI_DATETIMEOFFSET:
                case BinXmlToken.XSD_KATMAI_TIMEOFFSET:
                    value = GetValueConverter(XmlTypeCode.DateTime).ChangeType(
                        ValueAsDateTimeOffset(),
                        returnType, namespaceResolver);
                    break;

                case BinXmlToken.XSD_TIME:
                    value = GetValueConverter(XmlTypeCode.Time).ChangeType(
                        ValueAsDateTime(),
                        returnType, namespaceResolver);
                    break;

                case BinXmlToken.XSD_DATE:
                    value = GetValueConverter(XmlTypeCode.Date).ChangeType(
                        ValueAsDateTime(),
                        returnType, namespaceResolver);
                    break;

                case BinXmlToken.XSD_QNAME: {
                        int nameNum = ParseMB32(this.tokDataPos);
                        if (nameNum < 0 || nameNum >= this.symbolTables.qnameCount)
                            throw new XmlException(Res.XmlBin_InvalidQNameID, String.Empty);
                        QName qname = this.symbolTables.qnametable[nameNum];
                        value = GetValueConverter(XmlTypeCode.QName).ChangeType(
                            new XmlQualifiedName(qname.localname, qname.namespaceUri),
                            returnType, namespaceResolver);
                        break;
                    }

                default:
                    throw ThrowUnexpectedToken(this.token);
            }
            return value;
        }
 XmlNodeType ScanOverValue(BinXmlToken token, bool attr, bool checkChars) {
     if (token == BinXmlToken.SQL_NVARCHAR) {
         if (this.mark < 0)
             this.mark = this.pos;
         this.tokLen = ParseMB32();
         this.tokDataPos = this.pos;
         checked{this.pos += this.tokLen * 2;}
         Fill(-1);
         // check chars (if this is the first pass and settings.CheckCharacters was set)
         if (checkChars && this.checkCharacters) {
             // check for invalid chardata
             return CheckText(attr);
         }
         else if (!attr) { // attribute values are always reported as Text
             // check for whitespace-only text
             return CheckTextIsWS();
         }
         else {
             return XmlNodeType.Text;
         }
     }
     else {
         return ScanOverAnyValue(token, attr, checkChars);
     }
 }
        public XmlSqlBinaryReader(System.IO.Stream stream, byte[] data, int len, string baseUri, bool closeInput, XmlReaderSettings settings) {
            unicode = System.Text.Encoding.Unicode;
            xmlCharType = XmlCharType.Instance;

            this.xnt = settings.NameTable;
            if (this.xnt == null) {
                this.xnt = new NameTable();
                this.xntFromSettings = false;
            }
            else {
                this.xntFromSettings = true;
            }
            this.xml = this.xnt.Add("xml");
            this.xmlns = this.xnt.Add("xmlns");
            this.nsxmlns = this.xnt.Add(XmlReservedNs.NsXmlNs);
            this.baseUri = baseUri;
            this.state = ScanState.Init;
            this.nodetype = XmlNodeType.None;
            this.token = BinXmlToken.Error;
            this.elementStack = new ElemInfo[16];
            //this.elemDepth = 0;
            this.attributes = new AttrInfo[8];
            this.attrHashTbl = new int[8];
            //this.attrCount = 0;
            //this.attrIndex = 0;
            this.symbolTables.Init();
            this.qnameOther.Clear();
            this.qnameElement.Clear();
            this.xmlspacePreserve = false;
            this.hasher = new SecureStringHasher();
            this.namespaces = new Dictionary<String, NamespaceDecl>(hasher);
            AddInitNamespace(String.Empty, String.Empty);
            AddInitNamespace(this.xml, this.xnt.Add(XmlReservedNs.NsXml));
            AddInitNamespace(this.xmlns, this.nsxmlns);
            this.valueType = TypeOfString;
            // init buffer position, etc
            this.inStrm = stream;
            if (data != null) {
                Debug.Assert(len >= 2 && (data[0] == 0xdf && data[1] == 0xff));
                this.data = data;
                this.end = len;
                this.pos = 2;
                this.sniffed = true;
            }
            else {
                this.data = new byte[XmlReader.DefaultBufferSize];
                this.end = stream.Read(this.data, 0, XmlReader.DefaultBufferSize);
                this.pos = 0;
                this.sniffed = false;
            }

            this.mark = -1;
            this.eof = (0 == this.end);
            this.offset = 0;
            this.closeInput = closeInput;
            switch (settings.ConformanceLevel) {
                case ConformanceLevel.Auto:
                    this.docState = 0; break;
                case ConformanceLevel.Fragment:
                    this.docState = 9; break;
                case ConformanceLevel.Document:
                    this.docState = 1; break;
            }
            this.checkCharacters = settings.CheckCharacters;
            this.dtdProcessing = settings.DtdProcessing;
            this.ignoreWhitespace = settings.IgnoreWhitespace;
            this.ignorePIs = settings.IgnoreProcessingInstructions;
            this.ignoreComments = settings.IgnoreComments;

            if (TokenTypeMap == null)
                GenerateTokenTypeMap();
        }
        //////////
        // Internal implementation methods

        void VerifyVersion(int requiredVersion, BinXmlToken token) {
            if (version < requiredVersion) {
                throw ThrowUnexpectedToken(token);
            }
        }
 BinXmlToken NextToken2(BinXmlToken token) {
     while (true) {
         switch (token) {
             case BinXmlToken.Name:
                 AddName();
                 break;
             case BinXmlToken.QName:
                 AddQName();
                 break;
             case BinXmlToken.NmFlush:
                 NameFlush();
                 break;
             case BinXmlToken.Extn:
                 SkipExtn();
                 break;
             default:
                 return token;
         }
         token = ReadToken();
     }
 }
        private void ImplReadData(BinXmlToken tokenType)
        {
            this.mark = this.pos;
            switch (tokenType)
            {
                case BinXmlToken.SQL_CHAR:
                case BinXmlToken.SQL_NCHAR:
                case BinXmlToken.SQL_VARCHAR:
                case BinXmlToken.SQL_NVARCHAR:
                case BinXmlToken.SQL_TEXT:
                case BinXmlToken.SQL_NTEXT:
                    this.valueType = TypeOfString;
                    this.hasTypedValue = false;
                    break;

                default:
                    this.valueType = this.GetValueType(this.token);
                    this.hasTypedValue = true;
                    break;
            }
            this.nodetype = this.ScanOverValue(this.token, false, true);
            switch (this.PeekNextToken())
            {
                case BinXmlToken.SQL_SMALLINT:
                case BinXmlToken.SQL_INT:
                case BinXmlToken.SQL_REAL:
                case BinXmlToken.SQL_FLOAT:
                case BinXmlToken.SQL_MONEY:
                case BinXmlToken.SQL_BIT:
                case BinXmlToken.SQL_TINYINT:
                case BinXmlToken.SQL_BIGINT:
                case BinXmlToken.SQL_UUID:
                case BinXmlToken.SQL_DECIMAL:
                case BinXmlToken.SQL_NUMERIC:
                case BinXmlToken.SQL_BINARY:
                case BinXmlToken.SQL_CHAR:
                case BinXmlToken.SQL_NCHAR:
                case BinXmlToken.SQL_VARBINARY:
                case BinXmlToken.SQL_VARCHAR:
                case BinXmlToken.SQL_NVARCHAR:
                case BinXmlToken.SQL_DATETIME:
                case BinXmlToken.SQL_SMALLDATETIME:
                case BinXmlToken.SQL_SMALLMONEY:
                case BinXmlToken.SQL_TEXT:
                case BinXmlToken.SQL_IMAGE:
                case BinXmlToken.SQL_NTEXT:
                case BinXmlToken.SQL_UDT:
                case BinXmlToken.XSD_KATMAI_TIMEOFFSET:
                case BinXmlToken.XSD_KATMAI_DATETIMEOFFSET:
                case BinXmlToken.XSD_KATMAI_DATEOFFSET:
                case BinXmlToken.XSD_KATMAI_TIME:
                case BinXmlToken.XSD_KATMAI_DATETIME:
                case BinXmlToken.XSD_KATMAI_DATE:
                case BinXmlToken.XSD_TIME:
                case BinXmlToken.XSD_DATETIME:
                case BinXmlToken.XSD_DATE:
                case BinXmlToken.XSD_BINHEX:
                case BinXmlToken.XSD_BASE64:
                case BinXmlToken.XSD_BOOLEAN:
                case BinXmlToken.XSD_DECIMAL:
                case BinXmlToken.XSD_BYTE:
                case BinXmlToken.XSD_UNSIGNEDSHORT:
                case BinXmlToken.XSD_UNSIGNEDINT:
                case BinXmlToken.XSD_UNSIGNEDLONG:
                case BinXmlToken.XSD_QNAME:
                    throw this.ThrowNotSupported("XmlBinary_ListsOfValuesNotSupported");

                case (BinXmlToken.SQL_SMALLMONEY | BinXmlToken.SQL_SMALLINT):
                case (BinXmlToken.SQL_NTEXT | BinXmlToken.SQL_SMALLINT):
                case (BinXmlToken.SQL_NTEXT | BinXmlToken.SQL_INT):
                case ((BinXmlToken) 0x80):
                    return;
            }
        }
        private void ImplReadElement()
        {
            if ((3 != this.docState) || (9 != this.docState))
            {
                switch (this.docState)
                {
                    case -1:
                        throw this.ThrowUnexpectedToken(this.token);

                    case 0:
                        this.docState = 9;
                        break;

                    case 1:
                    case 2:
                        this.docState = 3;
                        break;
                }
            }
            this.elemDepth++;
            if (this.elemDepth == this.elementStack.Length)
            {
                this.GrowElements();
            }
            QName name = this.symbolTables.qnametable[this.ReadQNameRef()];
            this.qnameOther = this.qnameElement = name;
            this.elementStack[this.elemDepth].Set(name, this.xmlspacePreserve);
            this.PushNamespace(name.prefix, name.namespaceUri, true);
            BinXmlToken token = this.PeekNextToken();
            if (BinXmlToken.Attr == token)
            {
                this.ScanAttributes();
                token = this.PeekNextToken();
            }
            this.GenerateImpliedXmlnsAttrs();
            if (BinXmlToken.EndElem == token)
            {
                this.NextToken();
                this.isEmpty = true;
            }
            else if (BinXmlToken.SQL_NVARCHAR == token)
            {
                if (this.mark < 0)
                {
                    this.mark = this.pos;
                }
                this.pos++;
                if (this.ReadByte() == 0)
                {
                    if (0xf7 != this.ReadByte())
                    {
                        this.pos -= 3;
                    }
                    else
                    {
                        this.pos--;
                    }
                }
                else
                {
                    this.pos -= 2;
                }
            }
            this.nodetype = XmlNodeType.Element;
            this.valueType = TypeOfObject;
            this.posAfterAttrs = this.pos;
        }
        public XmlSqlBinaryReader(Stream stream, byte[] data, int len, string baseUri, bool closeInput, XmlReaderSettings settings)
        {
            this.xnt = settings.NameTable;
            if (this.xnt == null)
            {
                this.xnt = new System.Xml.NameTable();
                this.xntFromSettings = false;
            }
            else
            {
                this.xntFromSettings = true;
            }
            this.xml = this.xnt.Add("xml");
            this.xmlns = this.xnt.Add("xmlns");
            this.nsxmlns = this.xnt.Add("http://www.w3.org/2000/xmlns/");
            this.baseUri = baseUri;
            this.state = ScanState.Init;
            this.nodetype = XmlNodeType.None;
            this.token = BinXmlToken.Error;
            this.elementStack = new ElemInfo[0x10];
            this.attributes = new AttrInfo[8];
            this.attrHashTbl = new int[8];
            this.symbolTables.Init();
            this.qnameOther.Clear();
            this.qnameElement.Clear();
            this.xmlspacePreserve = false;
            this.hasher = new SecureStringHasher();
            this.namespaces = new Dictionary<string, NamespaceDecl>(this.hasher);
            this.AddInitNamespace(string.Empty, string.Empty);
            this.AddInitNamespace(this.xml, this.xnt.Add("http://www.w3.org/XML/1998/namespace"));
            this.AddInitNamespace(this.xmlns, this.nsxmlns);
            this.valueType = TypeOfString;
            this.inStrm = stream;
            if (data != null)
            {
                this.data = data;
                this.end = len;
                this.pos = 2;
                this.sniffed = true;
            }
            else
            {
                this.data = new byte[0x1000];
                this.end = stream.Read(this.data, 0, 0x1000);
                this.pos = 0;
                this.sniffed = false;
            }
            this.mark = -1;
            this.eof = 0 == this.end;
            this.offset = 0L;
            this.closeInput = closeInput;
            switch (settings.ConformanceLevel)
            {
                case ConformanceLevel.Auto:
                    this.docState = 0;
                    break;

                case ConformanceLevel.Fragment:
                    this.docState = 9;
                    break;

                case ConformanceLevel.Document:
                    this.docState = 1;
                    break;
            }
            this.checkCharacters = settings.CheckCharacters;
            this.dtdProcessing = settings.DtdProcessing;
            this.ignoreWhitespace = settings.IgnoreWhitespace;
            this.ignorePIs = settings.IgnoreProcessingInstructions;
            this.ignoreComments = settings.IgnoreComments;
            if (TokenTypeMap == null)
            {
                this.GenerateTokenTypeMap();
            }
        }
        private int GetXsdKatmaiTokenLength(BinXmlToken token)
        {
            byte num;
            switch (token)
            {
                case BinXmlToken.XSD_KATMAI_TIMEOFFSET:
                case BinXmlToken.XSD_KATMAI_DATETIMEOFFSET:
                case BinXmlToken.XSD_KATMAI_DATEOFFSET:
                    this.Fill(0);
                    num = this.data[this.pos];
                    return (6 + this.XsdKatmaiTimeScaleToValueLength(num));

                case BinXmlToken.XSD_KATMAI_TIME:
                case BinXmlToken.XSD_KATMAI_DATETIME:
                    this.Fill(0);
                    num = this.data[this.pos];
                    return (4 + this.XsdKatmaiTimeScaleToValueLength(num));

                case BinXmlToken.XSD_KATMAI_DATE:
                    return 3;
            }
            throw this.ThrowUnexpectedToken(this.token);
        }
 private Type GetValueType(BinXmlToken token)
 {
     Type type = TokenTypeMap[(int) token];
     if (type == null)
     {
         throw this.ThrowUnexpectedToken(token);
     }
     return type;
 }
 System.Type GetValueType(BinXmlToken token) {
     Type t = TokenTypeMap[(int)token];
     if (t == null)
         throw ThrowUnexpectedToken(token);
     return t;
 }
 BinXmlToken NextToken1() {
     BinXmlToken token;
     int pos = this.pos;
     if (pos >= this.end)
         token = ReadToken();
     else {
         token = (BinXmlToken)this.data[pos];
         this.pos = pos + 1;
     }
     // BinXmlToken.Name = 0xF0
     // BinXmlToken.QName = 0xEF
     // BinXmlToken.Extn = 0xEA,
     // BinXmlToken.NmFlush = 0xE9,
     if (token >= BinXmlToken.NmFlush
         && token <= BinXmlToken.Name)
         return NextToken2(token);
     return token;
 }
 // helper method...
 void ReScanOverValue(BinXmlToken token) {
     ScanOverValue(token, true, false);
 }
 // like NextToken() but meta-tokens are skipped (not reinterpreted)
 BinXmlToken RescanNextToken() {
     BinXmlToken token;
     while (true) {
         token = ReadToken();
         switch (token) {
             case BinXmlToken.Name: {
                     int cb = ParseMB32();
                     checked{this.pos += 2 * cb;}
                     break;
                 }
             case BinXmlToken.QName:
                 ParseMB32();
                 ParseMB32();
                 ParseMB32();
                 break;
             case BinXmlToken.Extn: {
                     int cb = ParseMB32();
                     checked{this.pos += cb;}
                     break;
                 }
             case BinXmlToken.NmFlush:
                 break;
             default:
                 return token;
         }
     }
 }
        XmlNodeType ScanOverAnyValue(BinXmlToken token, bool attr, bool checkChars) {
            if (this.mark < 0)
                this.mark = this.pos;
            checked {
                switch (token) {
                    case BinXmlToken.SQL_BIT:
                    case BinXmlToken.SQL_TINYINT:
                    case BinXmlToken.XSD_BOOLEAN:
                    case BinXmlToken.XSD_BYTE:
                        this.tokDataPos = this.pos;
                        this.tokLen = 1;
                        this.pos += 1;
                        break;

                    case BinXmlToken.SQL_SMALLINT:
                    case BinXmlToken.XSD_UNSIGNEDSHORT:
                        this.tokDataPos = this.pos;
                        this.tokLen = 2;
                        this.pos += 2;
                        break;

                    case BinXmlToken.SQL_INT:
                    case BinXmlToken.XSD_UNSIGNEDINT:
                    case BinXmlToken.SQL_REAL:
                    case BinXmlToken.SQL_SMALLMONEY:
                    case BinXmlToken.SQL_SMALLDATETIME:
                        this.tokDataPos = this.pos;
                        this.tokLen = 4;
                        this.pos += 4;
                        break;

                    case BinXmlToken.SQL_BIGINT:
                    case BinXmlToken.XSD_UNSIGNEDLONG:
                    case BinXmlToken.SQL_FLOAT:
                    case BinXmlToken.SQL_MONEY:
                    case BinXmlToken.SQL_DATETIME:
                    case BinXmlToken.XSD_TIME:
                    case BinXmlToken.XSD_DATETIME:
                    case BinXmlToken.XSD_DATE:
                        this.tokDataPos = this.pos;
                        this.tokLen = 8;
                        this.pos += 8;
                        break;

                    case BinXmlToken.SQL_UUID:
                        this.tokDataPos = this.pos;
                        this.tokLen = 16;
                        this.pos += 16;
                        break;

                    case BinXmlToken.SQL_DECIMAL:
                    case BinXmlToken.SQL_NUMERIC:
                    case BinXmlToken.XSD_DECIMAL:
                        this.tokDataPos = this.pos;
                        this.tokLen = ParseMB64();
                        this.pos += this.tokLen;
                        break;

                    case BinXmlToken.SQL_VARBINARY:
                    case BinXmlToken.SQL_BINARY:
                    case BinXmlToken.SQL_IMAGE:
                    case BinXmlToken.SQL_UDT:
                    case BinXmlToken.XSD_BINHEX:
                    case BinXmlToken.XSD_BASE64:
                        this.tokLen = ParseMB64();
                        this.tokDataPos = this.pos;
                        this.pos += this.tokLen;
                        break;

                    case BinXmlToken.SQL_CHAR:
                    case BinXmlToken.SQL_VARCHAR:
                    case BinXmlToken.SQL_TEXT:
                        this.tokLen = ParseMB64();
                        this.tokDataPos = this.pos;
                        this.pos += this.tokLen;
                        if (checkChars && this.checkCharacters) {
                            // check for invalid chardata
                            Fill(-1);
                            string val = ValueAsString(token);
                            XmlConvert.VerifyCharData(val, ExceptionType.ArgumentException, ExceptionType.XmlException);
                            this.stringValue = val;
                        }
                        break;

                    case BinXmlToken.SQL_NVARCHAR:
                    case BinXmlToken.SQL_NCHAR:
                    case BinXmlToken.SQL_NTEXT:
                        return ScanOverValue(BinXmlToken.SQL_NVARCHAR, attr, checkChars);

                    case BinXmlToken.XSD_QNAME:
                        this.tokDataPos = this.pos;
                        ParseMB32();
                        break;

                    case BinXmlToken.XSD_KATMAI_DATE:
                    case BinXmlToken.XSD_KATMAI_DATETIME:
                    case BinXmlToken.XSD_KATMAI_TIME:
                    case BinXmlToken.XSD_KATMAI_DATEOFFSET:
                    case BinXmlToken.XSD_KATMAI_DATETIMEOFFSET:
                    case BinXmlToken.XSD_KATMAI_TIMEOFFSET:
                        VerifyVersion(2, token);
                        this.tokDataPos = this.pos;
                        this.tokLen = GetXsdKatmaiTokenLength(token);
                        this.pos += tokLen;
                        break;

                    default:
                        throw ThrowUnexpectedToken(token);
                }
            }
            Fill(-1);
            return XmlNodeType.Text;
        }
        private string GetAttributeText(int i) {
            string val = this.attributes[i].val;

            if (null != val)
                return val;
            else {
                int origPos = this.pos;
                try {
                    this.pos = this.attributes[i].contentPos;
                    BinXmlToken token = RescanNextToken();
                    if (BinXmlToken.Attr == token || BinXmlToken.EndAttrs == token) {
                        return "";
                    }
                    this.token = token;
                    ReScanOverValue(token);
                    return ValueAsString(token);
                }
                finally {
                    this.pos = origPos;
                }
            }
        }
 int GetXsdKatmaiTokenLength(BinXmlToken token) {
     byte scale;
     switch (token) {
         case BinXmlToken.XSD_KATMAI_DATE:
             // SQL Katmai type DATE = date(3b)
             return 3;                                           
         case BinXmlToken.XSD_KATMAI_TIME:
         case BinXmlToken.XSD_KATMAI_DATETIME:
             // SQL Katmai type DATETIME2 = scale(1b) + time(3-5b) + date(3b)
             Fill(0);
             scale = this.data[this.pos];
             return 4 + XsdKatmaiTimeScaleToValueLength(scale);  
         case BinXmlToken.XSD_KATMAI_DATEOFFSET:
         case BinXmlToken.XSD_KATMAI_TIMEOFFSET:
         case BinXmlToken.XSD_KATMAI_DATETIMEOFFSET:
             // SQL Katmai type DATETIMEOFFSET = scale(1b) + time(3-5b) + date(3b) + zone(2b)
             Fill(0);
             scale = this.data[this.pos];
             return 6 + XsdKatmaiTimeScaleToValueLength(scale);
         default:
             throw ThrowUnexpectedToken(this.token);
     }
 }
 private void PositionOnAttribute(int i) {
     // save element's qname
     this.attrIndex = i;
     this.qnameOther = this.attributes[i - 1].name;
     if (this.state == ScanState.Doc) {
         this.parentNodeType = this.nodetype;
     }
     this.token = BinXmlToken.Attr;
     this.nodetype = XmlNodeType.Attribute;
     this.state = ScanState.Attr;
     this.valueType = TypeOfObject;
     this.stringValue = null;
 }
        object ValueAsObject(BinXmlToken token, bool returnInternalTypes) {
            CheckValueTokenBounds();
            switch (token) {
                case BinXmlToken.SQL_NCHAR:
                case BinXmlToken.SQL_NVARCHAR:
                case BinXmlToken.SQL_NTEXT:
                    return GetString(this.tokDataPos, this.tokLen);

                case BinXmlToken.XSD_BOOLEAN:
                    return (0 != this.data[this.tokDataPos]);

                case BinXmlToken.SQL_BIT:
                    return (Int32)this.data[this.tokDataPos];

                case BinXmlToken.SQL_TINYINT:
                    return this.data[this.tokDataPos];

                case BinXmlToken.SQL_SMALLINT:
                    return GetInt16(this.tokDataPos);

                case BinXmlToken.SQL_INT:
                    return GetInt32(this.tokDataPos);

                case BinXmlToken.SQL_BIGINT:
                    return GetInt64(this.tokDataPos);

                case BinXmlToken.XSD_BYTE: {
                        sbyte v = unchecked((sbyte)this.data[this.tokDataPos]);
                        return v;
                    }

                case BinXmlToken.XSD_UNSIGNEDSHORT:
                    return GetUInt16(this.tokDataPos);

                case BinXmlToken.XSD_UNSIGNEDINT:
                    return GetUInt32(this.tokDataPos);

                case BinXmlToken.XSD_UNSIGNEDLONG:
                    return GetUInt64(this.tokDataPos);

                case BinXmlToken.SQL_REAL:
                    return GetSingle(this.tokDataPos);

                case BinXmlToken.SQL_FLOAT:
                    return GetDouble(this.tokDataPos);

                case BinXmlToken.SQL_UUID: {
                        int a; short b, c;
                        int pos = this.tokDataPos;
                        a = GetInt32(pos);
                        b = GetInt16(pos + 4);
                        c = GetInt16(pos + 6);
                        Guid v = new Guid(a, b, c, data[pos + 8], data[pos + 9], data[pos + 10], data[pos + 11], data[pos + 12], data[pos + 13], data[pos + 14], data[pos + 15]);
                        return v.ToString();
                    }

                case BinXmlToken.SQL_SMALLMONEY: {
                        BinXmlSqlMoney v = new BinXmlSqlMoney(GetInt32(this.tokDataPos));
                        if (returnInternalTypes)
                            return v;
                        else
                            return v.ToDecimal();
                    }

                case BinXmlToken.SQL_MONEY: {
                        BinXmlSqlMoney v = new BinXmlSqlMoney(GetInt64(this.tokDataPos));
                        if (returnInternalTypes)
                            return v;
                        else
                            return v.ToDecimal();
                    }

                case BinXmlToken.XSD_DECIMAL:
                case BinXmlToken.SQL_DECIMAL:
                case BinXmlToken.SQL_NUMERIC: {
                        BinXmlSqlDecimal v = new BinXmlSqlDecimal(this.data, this.tokDataPos, token == BinXmlToken.XSD_DECIMAL);
                        if (returnInternalTypes)
                            return v;
                        else
                            return v.ToDecimal();
                    }

                case BinXmlToken.SQL_CHAR:
                case BinXmlToken.SQL_VARCHAR:
                case BinXmlToken.SQL_TEXT: {
                        int pos = this.tokDataPos;
                        int codepage = GetInt32(pos);
                        Encoding enc = System.Text.Encoding.GetEncoding(codepage);
                        return enc.GetString(this.data, pos + 4, this.tokLen - 4);
                    }

                case BinXmlToken.SQL_VARBINARY:
                case BinXmlToken.SQL_BINARY:
                case BinXmlToken.SQL_IMAGE:
                case BinXmlToken.SQL_UDT:
                case BinXmlToken.XSD_BASE64:
                case BinXmlToken.XSD_BINHEX: {
                        byte[] data = new byte[this.tokLen];
                        Array.Copy(this.data, this.tokDataPos, data, 0, this.tokLen);
                        return data;
                    }

                case BinXmlToken.SQL_DATETIME:
                case BinXmlToken.SQL_SMALLDATETIME:
                case BinXmlToken.XSD_TIME:
                case BinXmlToken.XSD_DATE:
                case BinXmlToken.XSD_DATETIME:
                case BinXmlToken.XSD_KATMAI_DATE:
                case BinXmlToken.XSD_KATMAI_DATETIME:
                case BinXmlToken.XSD_KATMAI_TIME:
                    return ValueAsDateTime();

                case BinXmlToken.XSD_KATMAI_DATEOFFSET:
                case BinXmlToken.XSD_KATMAI_DATETIMEOFFSET:
                case BinXmlToken.XSD_KATMAI_TIMEOFFSET:
                    return ValueAsDateTimeOffset();

                case BinXmlToken.XSD_QNAME: {
                        int nameNum = ParseMB32(this.tokDataPos);
                        if (nameNum < 0 || nameNum >= this.symbolTables.qnameCount)
                            throw new XmlException(Res.XmlBin_InvalidQNameID, String.Empty);
                        QName qname = this.symbolTables.qnametable[nameNum];
                        return new XmlQualifiedName(qname.localname, qname.namespaceUri);
                    }

                default:
                    throw ThrowUnexpectedToken(this.token);
            }
        }
        void ScanAttributes() {
            BinXmlToken token;
            int xmlspace = -1;
            int xmllang = -1;

            this.mark = this.pos;
            string curDeclPrefix = null;
            bool lastWasValue = false;

            while (BinXmlToken.EndAttrs != (token = NextToken())) {
                if (BinXmlToken.Attr == token) {
                    // watch out for nsdecl with no actual content
                    if (null != curDeclPrefix) {
                        PushNamespace(curDeclPrefix, string.Empty, false);
                        curDeclPrefix = null;
                    }
                    // do we need to grow the array?
                    if (this.attrCount == this.attributes.Length)
                        GrowAttributes();
                    // note: ParseMB32 _must_ happen _before_ we grab this.pos...
                    QName n = this.symbolTables.qnametable[ReadQNameRef()];
                    this.attributes[this.attrCount].Set(n, (int)this.pos);
                    if (n.prefix == "xml") {
                        if (n.localname == "lang") {
                            xmllang = this.attrCount;
                        }
                        else if (n.localname == "space") {
                            xmlspace = this.attrCount;
                        }
                    }
                    else if (Ref.Equal(n.namespaceUri, this.nsxmlns)) {
                        // push namespace when we get the value
                        curDeclPrefix = n.localname;
                        if (curDeclPrefix == "xmlns")
                            curDeclPrefix = string.Empty;
                    }
                    else if (n.prefix.Length != 0) {
                        if (n.namespaceUri.Length == 0)
                            throw new XmlException(Res.Xml_PrefixForEmptyNs, String.Empty);
                        this.PushNamespace(n.prefix, n.namespaceUri, true);
                    }
                    else if (n.namespaceUri.Length != 0) {
                        throw ThrowXmlException(Res.XmlBinary_AttrWithNsNoPrefix, n.localname, n.namespaceUri);
                    }
                    this.attrCount++;
                    lastWasValue = false;
                }
                else {
                    // first scan over token to make sure it is a value token
                    ScanOverValue(token, true, true);
                    // don't allow lists of values
                    if (lastWasValue) {
                        throw ThrowNotSupported(Res.XmlBinary_ListsOfValuesNotSupported);
                    }

                    // if char checking is on, we need to scan text values to
                    // validate that they don't use invalid CharData, so we
                    // might as well store the saved string for quick attr value access
                    string val = this.stringValue;
                    if (null != val) {
                        this.attributes[this.attrCount - 1].val = val;
                        this.stringValue = null;
                    }
                    // namespace decls can only have text values, and should only
                    // have a single value, so we just grab it here...
                    if (null != curDeclPrefix) {
                        string nsuri = this.xnt.Add(ValueAsString(token));
                        PushNamespace(curDeclPrefix, nsuri, false);
                        curDeclPrefix = null;
                    }
                    lastWasValue = true;
                }
            }

            if (xmlspace != -1) {
                string val = GetAttributeText(xmlspace);
                XmlSpace xs = XmlSpace.None;
                if (val == "preserve")
                    xs = XmlSpace.Preserve;
                else if (val == "default")
                    xs = XmlSpace.Default;
                this.elementStack[this.elemDepth].xmlSpace = xs;
                this.xmlspacePreserve = (XmlSpace.Preserve == xs);
            }
            if (xmllang != -1) {
                this.elementStack[this.elemDepth].xmlLang = GetAttributeText(xmllang);
            }

            if (this.attrCount < 200)
                SimpleCheckForDuplicateAttributes();
            else
                HashCheckForDuplicateAttributes();
        }
 Exception ThrowUnexpectedToken(BinXmlToken token) {
     System.Diagnostics.Debug.WriteLine("Unhandled token: " + token.ToString());
     return ThrowXmlException(Res.XmlBinary_UnexpectedToken);
 }
        bool ReadDoc() {
            switch (this.nodetype) {
                case XmlNodeType.CDATA:
                    FinishCDATA();
                    break;
                case XmlNodeType.EndElement:
                    FinishEndElement();
                    break;
                case XmlNodeType.Element:
                    if (this.isEmpty) {
                        FinishEndElement();
                        this.isEmpty = false;
                    }
                    break;
            }

        Read:
            // clear existing state
            this.nodetype = XmlNodeType.None;
            this.mark = -1;
            if (this.qnameOther.localname.Length != 0)
                this.qnameOther.Clear();

            ClearAttributes();
            this.attrCount = 0;
            this.valueType = TypeOfString;
            this.stringValue = null;
            this.hasTypedValue = false;

            this.token = NextToken();
            switch (this.token) {
                case BinXmlToken.EOF:
                    if (this.elemDepth > 0)
                        throw new XmlException(Res.Xml_UnexpectedEOF1, (string[])null);
                    this.state = ScanState.EOF;
                    return false;

                case BinXmlToken.Element:
                    ImplReadElement();
                    break;

                case BinXmlToken.EndElem:
                    ImplReadEndElement();
                    break;

                case BinXmlToken.DocType:
                    ImplReadDoctype();
                    if (this.dtdProcessing == DtdProcessing.Ignore)
                        goto Read;
                    // nested, don't report doctype
                    if (prevNameInfo != null)
                        goto Read;
                    break;

                case BinXmlToken.PI:
                    ImplReadPI();
                    if (this.ignorePIs)
                        goto Read;
                    break;

                case BinXmlToken.Comment:
                    ImplReadComment();
                    if (this.ignoreComments)
                        goto Read;
                    break;

                case BinXmlToken.CData:
                    ImplReadCDATA();
                    break;

                case BinXmlToken.Nest:
                    ImplReadNest();
                    // parse first token in nested document
                    sniffed = false;
                    return ReadInit(true);

                case BinXmlToken.EndNest:
                    if (null == this.prevNameInfo)
                        goto default;
                    ImplReadEndNest();
                    return ReadDoc();

                case BinXmlToken.XmlText:
                    ImplReadXmlText();
                    break;

                // text values
                case BinXmlToken.SQL_BIT:
                case BinXmlToken.SQL_TINYINT:
                case BinXmlToken.SQL_SMALLINT:
                case BinXmlToken.SQL_INT:
                case BinXmlToken.SQL_BIGINT:
                case BinXmlToken.SQL_REAL:
                case BinXmlToken.SQL_FLOAT:
                case BinXmlToken.SQL_MONEY:
                case BinXmlToken.SQL_SMALLMONEY:
                case BinXmlToken.SQL_DATETIME:
                case BinXmlToken.SQL_SMALLDATETIME:
                case BinXmlToken.SQL_DECIMAL:
                case BinXmlToken.SQL_NUMERIC:
                case BinXmlToken.XSD_DECIMAL:
                case BinXmlToken.SQL_UUID:
                case BinXmlToken.SQL_VARBINARY:
                case BinXmlToken.SQL_BINARY:
                case BinXmlToken.SQL_IMAGE:
                case BinXmlToken.SQL_UDT:
                case BinXmlToken.XSD_KATMAI_DATE:
                case BinXmlToken.XSD_KATMAI_DATETIME:
                case BinXmlToken.XSD_KATMAI_TIME:
                case BinXmlToken.XSD_KATMAI_DATEOFFSET:
                case BinXmlToken.XSD_KATMAI_DATETIMEOFFSET:
                case BinXmlToken.XSD_KATMAI_TIMEOFFSET:
                case BinXmlToken.XSD_BINHEX:
                case BinXmlToken.XSD_BASE64:
                case BinXmlToken.SQL_CHAR:
                case BinXmlToken.SQL_VARCHAR:
                case BinXmlToken.SQL_TEXT:
                case BinXmlToken.SQL_NCHAR:
                case BinXmlToken.SQL_NVARCHAR:
                case BinXmlToken.SQL_NTEXT:
                case BinXmlToken.XSD_BOOLEAN:
                case BinXmlToken.XSD_TIME:
                case BinXmlToken.XSD_DATETIME:
                case BinXmlToken.XSD_DATE:
                case BinXmlToken.XSD_BYTE:
                case BinXmlToken.XSD_UNSIGNEDSHORT:
                case BinXmlToken.XSD_UNSIGNEDINT:
                case BinXmlToken.XSD_UNSIGNEDLONG:
                case BinXmlToken.XSD_QNAME:
                    ImplReadData(this.token);
                    if (XmlNodeType.Text == this.nodetype)
                        CheckAllowContent();
                    else if (this.ignoreWhitespace && !this.xmlspacePreserve)
                        goto Read; // skip to next token
                    return true;

                default:
                    throw ThrowUnexpectedToken(token);
            }

            return true;
        }
        public override bool ReadAttributeValue() {
            this.stringValue = null;
            switch (this.state) {
                case ScanState.Attr:
                    if (null == this.attributes[this.attrIndex - 1].val) {
                        this.pos = this.attributes[this.attrIndex - 1].contentPos;
                        BinXmlToken tok = RescanNextToken();
                        if (BinXmlToken.Attr == tok || BinXmlToken.EndAttrs == tok) {
                            return false;
                        }
                        this.token = tok;
                        ReScanOverValue(tok);
                        this.valueType = GetValueType(tok);
                        this.state = ScanState.AttrVal;
                    }
                    else {
                        this.token = BinXmlToken.Error;
                        this.valueType = TypeOfString;
                        this.state = ScanState.AttrValPseudoValue;
                    }
                    this.qnameOther.Clear();
                    this.nodetype = XmlNodeType.Text;
                    return true;

                case ScanState.AttrVal:
                    return false;

                case ScanState.XmlText:
                    return UpdateFromTextReader(this.textXmlReader.ReadAttributeValue());

                default:
                    return false;
            }
        }
        void ImplReadData(BinXmlToken tokenType) {
            Debug.Assert(this.mark < 0);
            this.mark = this.pos;

            switch (tokenType) {
                case BinXmlToken.SQL_CHAR:
                case BinXmlToken.SQL_VARCHAR:
                case BinXmlToken.SQL_TEXT:
                case BinXmlToken.SQL_NCHAR:
                case BinXmlToken.SQL_NVARCHAR:
                case BinXmlToken.SQL_NTEXT:
                    this.valueType = TypeOfString;
                    this.hasTypedValue = false;
                    break;
                default:
                    this.valueType = GetValueType(this.token);
                    this.hasTypedValue = true;
                    break;
            }

            this.nodetype = ScanOverValue(this.token, false, true);

            // we don't support lists of values
            BinXmlToken tNext = PeekNextToken();
            switch (tNext) {
                case BinXmlToken.SQL_BIT:
                case BinXmlToken.SQL_TINYINT:
                case BinXmlToken.SQL_SMALLINT:
                case BinXmlToken.SQL_INT:
                case BinXmlToken.SQL_BIGINT:
                case BinXmlToken.SQL_REAL:
                case BinXmlToken.SQL_FLOAT:
                case BinXmlToken.SQL_MONEY:
                case BinXmlToken.SQL_SMALLMONEY:
                case BinXmlToken.SQL_DATETIME:
                case BinXmlToken.SQL_SMALLDATETIME:
                case BinXmlToken.SQL_DECIMAL:
                case BinXmlToken.SQL_NUMERIC:
                case BinXmlToken.XSD_DECIMAL:
                case BinXmlToken.SQL_UUID:
                case BinXmlToken.SQL_VARBINARY:
                case BinXmlToken.SQL_BINARY:
                case BinXmlToken.SQL_IMAGE:
                case BinXmlToken.SQL_UDT:
                case BinXmlToken.XSD_KATMAI_DATE:
                case BinXmlToken.XSD_KATMAI_DATETIME:
                case BinXmlToken.XSD_KATMAI_TIME:
                case BinXmlToken.XSD_KATMAI_DATEOFFSET:
                case BinXmlToken.XSD_KATMAI_DATETIMEOFFSET:
                case BinXmlToken.XSD_KATMAI_TIMEOFFSET:
                case BinXmlToken.XSD_BINHEX:
                case BinXmlToken.XSD_BASE64:
                case BinXmlToken.SQL_CHAR:
                case BinXmlToken.SQL_VARCHAR:
                case BinXmlToken.SQL_TEXT:
                case BinXmlToken.SQL_NCHAR:
                case BinXmlToken.SQL_NVARCHAR:
                case BinXmlToken.SQL_NTEXT:
                case BinXmlToken.XSD_BOOLEAN:
                case BinXmlToken.XSD_TIME:
                case BinXmlToken.XSD_DATETIME:
                case BinXmlToken.XSD_DATE:
                case BinXmlToken.XSD_BYTE:
                case BinXmlToken.XSD_UNSIGNEDSHORT:
                case BinXmlToken.XSD_UNSIGNEDINT:
                case BinXmlToken.XSD_UNSIGNEDLONG:
                case BinXmlToken.XSD_QNAME:
                    throw ThrowNotSupported(Res.XmlBinary_ListsOfValuesNotSupported);
                default:
                    break;
            }
        }
        // Use default implementation of and ReadContentAsString and ReadElementContentAsString
        // (there is no benefit to providing a custom version)
        // public override bool ReadElementContentAsString( string localName, string namespaceURI )
        // public override bool ReadElementContentAsString()
        // public override bool ReadContentAsString()

        // Do setup work for ReadContentAsXXX methods
        // If ready for a typed value read, returns true, otherwise returns
        //  false to indicate caller should ball back to XmlReader.ReadContentAsXXX
        // Special-Case: returns true and positioned on Element or EndElem to force parse of empty-string
        private bool SetupContentAsXXX(string name) {
            if (!CanReadContentAs(this.NodeType)) {
                throw CreateReadContentAsException(name);
            }
            switch (this.state) {
                case ScanState.Doc:
                    if (this.NodeType == XmlNodeType.EndElement)
                        return true;
                    if (this.NodeType == XmlNodeType.ProcessingInstruction || this.NodeType == XmlNodeType.Comment) {
                        while (Read() && (this.NodeType == XmlNodeType.ProcessingInstruction || this.NodeType == XmlNodeType.Comment))
                            ;
                        if (this.NodeType == XmlNodeType.EndElement)
                            return true;
                    }
                    if (this.hasTypedValue) {
                        return true;
                    }
                    break;
                case ScanState.Attr:
                    this.pos = this.attributes[this.attrIndex - 1].contentPos;
                    BinXmlToken token = RescanNextToken();
                    if (BinXmlToken.Attr == token || BinXmlToken.EndAttrs == token)
                        break;
                    this.token = token;
                    ReScanOverValue(token);
                    return true;
                case ScanState.AttrVal:
                    return true;
                default:
                    break;
            }
            return false;
        }
 private void VerifyVersion(int requiredVersion, BinXmlToken token)
 {
     if (this.version < requiredVersion)
     {
         throw this.ThrowUnexpectedToken(token);
     }
 }