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); } }