private ValidatingReaderNodeData AddContent(XmlNodeType nodeType) { Debug.Assert(_contentIndex <= _contentEvents.Length); ValidatingReaderNodeData contentInfo = _contentEvents[_contentIndex]; if (contentInfo != null) { contentInfo.Clear(nodeType); _contentIndex++; return(contentInfo); } if (_contentIndex >= _contentEvents.Length - 1) { //reached capacity of array, Need to increase capacity to twice the initial ValidatingReaderNodeData[] newContentEvents = new ValidatingReaderNodeData[_contentEvents.Length * 2]; Array.Copy(_contentEvents, 0, newContentEvents, 0, _contentEvents.Length); _contentEvents = newContentEvents; } contentInfo = _contentEvents[_contentIndex]; if (contentInfo == null) { contentInfo = new ValidatingReaderNodeData(nodeType); _contentEvents[_contentIndex] = contentInfo; } _contentIndex++; return(contentInfo); }
internal ValidatingReaderNodeData RecordTextNode(string textValue, string originalStringValue, int depth, int lineNo, int linePos) { ValidatingReaderNodeData textNode = AddContent(XmlNodeType.Text); textNode.SetItemData(textValue, originalStringValue); textNode.SetLineInfo(lineNo, linePos); textNode.Depth = depth; return(textNode); }
// Moves to the next attribute. public override bool MoveToNextAttribute() { if (_currentAttrIndex + 1 < _attributeCount) { _cachedNode = _attributeEvents[++_currentAttrIndex]; return(true); } return(false); }
// Moves to the attribute with the specified index. public override void MoveToAttribute(int i) { if (i < 0 || i >= _attributeCount) { throw new ArgumentOutOfRangeException("i"); } _currentAttrIndex = i; _cachedNode = _attributeEvents[i]; }
private ValidatingReaderNodeData CreateDummyTextNode(string attributeValue, int depth) { if (_textNode == null) { _textNode = new ValidatingReaderNodeData(XmlNodeType.Text); } _textNode.Depth = depth; _textNode.RawValue = attributeValue; return(_textNode); }
// Parses the attribute value into one or more Text and/or EntityReference node types. public override bool ReadAttributeValue() { Debug.Assert(_cacheState == CachingReaderState.Replay); if (_cachedNode.NodeType != XmlNodeType.Attribute) { return(false); } _cachedNode = CreateDummyTextNode(_cachedNode.RawValue, _cachedNode.Depth + 1); return(true); }
// Moves to the first attribute. public override bool MoveToFirstAttribute() { if (_attributeCount == 0) { return(false); } _currentAttrIndex = 0; _cachedNode = _attributeEvents[0]; return(true); }
internal void RecordEndElementNode() { ValidatingReaderNodeData recordedNode = AddContent(XmlNodeType.EndElement); Debug.Assert(_coreReader.NodeType == XmlNodeType.EndElement || (_coreReader.NodeType == XmlNodeType.Element && _coreReader.IsEmptyElement)); recordedNode.SetItemData(_coreReader.LocalName, _coreReader.Prefix, _coreReader.NamespaceURI, _coreReader.Depth); recordedNode.SetLineInfo(_coreReader as IXmlLineInfo); if (_coreReader.IsEmptyElement) { //Simulated endElement node for <e/>, the coreReader is on cached Element node itself. _readAhead = true; } }
internal void SwitchTextNodeAndEndElement(string textValue, string originalStringValue) { Debug.Assert(_coreReader.NodeType == XmlNodeType.EndElement || (_coreReader.NodeType == XmlNodeType.Element && _coreReader.IsEmptyElement)); ValidatingReaderNodeData textNode = RecordTextNode(textValue, originalStringValue, _coreReader.Depth + 1, 0, 0); int endElementIndex = _contentIndex - 2; ValidatingReaderNodeData endElementNode = _contentEvents[endElementIndex]; Debug.Assert(endElementNode.NodeType == XmlNodeType.EndElement); _contentEvents[endElementIndex] = textNode; _contentEvents[_contentIndex - 1] = endElementNode; }
private void Init() { _coreReaderNameTable = _coreReader.NameTable; _cacheState = CachingReaderState.Init; _contentIndex = 0; _currentAttrIndex = -1; _currentContentIndex = -1; _attributeCount = 0; _cachedNode = null; _readAhead = false; //Initialize the cachingReader with start state if (_coreReader.NodeType == XmlNodeType.Element) { ValidatingReaderNodeData element = AddContent(_coreReader.NodeType); element.SetItemData(_coreReader.LocalName, _coreReader.Prefix, _coreReader.NamespaceURI, _coreReader.Depth); //Only created for element node type element.SetLineInfo(_lineInfo); RecordAttributes(); } }
// Moves to the attribute with the specified LocalName and NamespaceURI public override bool MoveToAttribute(string name, string ns) { ns = (ns == null) ? string.Empty : _coreReaderNameTable.Get(ns); name = _coreReaderNameTable.Get(name); ValidatingReaderNodeData attribute; for (int i = 0; i < _attributeCount; i++) { attribute = _attributeEvents[i]; if (Ref.Equal(attribute.LocalName, name) && Ref.Equal(attribute.Namespace, ns)) { _currentAttrIndex = i; _cachedNode = _attributeEvents[i]; return(true); } } return(false); }
private ValidatingReaderNodeData AddAttribute(int attIndex) { Debug.Assert(attIndex <= _attributeEvents.Length); ValidatingReaderNodeData attInfo = _attributeEvents[attIndex]; if (attInfo != null) { attInfo.Clear(XmlNodeType.Attribute); return(attInfo); } if (attIndex >= _attributeEvents.Length - 1) { //reached capacity of array, Need to increase capacity to twice the initial ValidatingReaderNodeData[] newAttributeEvents = new ValidatingReaderNodeData[_attributeEvents.Length * 2]; Array.Copy(_attributeEvents, 0, newAttributeEvents, 0, _attributeEvents.Length); _attributeEvents = newAttributeEvents; } attInfo = _attributeEvents[attIndex]; if (attInfo == null) { attInfo = new ValidatingReaderNodeData(XmlNodeType.Attribute); _attributeEvents[attIndex] = attInfo; } return(attInfo); }
// Moves to the attribute with the specified Name. public override bool MoveToAttribute(string name) { int i; if (name.IndexOf(':') == -1) { i = GetAttributeIndexWithoutPrefix(name); } else { i = GetAttributeIndexWithPrefix(name); } if (i >= 0) { _currentAttrIndex = i; _cachedNode = _attributeEvents[i]; return(true); } else { return(false); } }
// Reads the next node from the stream/TextReader. public override async Task <bool> ReadAsync() { switch (_cacheState) { case CachingReaderState.Init: _cacheState = CachingReaderState.Record; goto case CachingReaderState.Record; case CachingReaderState.Record: ValidatingReaderNodeData recordedNode = null; if (await _coreReader.ReadAsync().ConfigureAwait(false)) { switch (_coreReader.NodeType) { case XmlNodeType.Element: //Dont record element within the content of a union type since the main reader will break on this and the underlying coreReader will be positioned on this node _cacheState = CachingReaderState.ReaderClosed; return(false); case XmlNodeType.EndElement: recordedNode = AddContent(_coreReader.NodeType); recordedNode.SetItemData(_coreReader.LocalName, _coreReader.Prefix, _coreReader.NamespaceURI, _coreReader.Depth); //Only created for element node type recordedNode.SetLineInfo(_lineInfo); break; case XmlNodeType.Comment: case XmlNodeType.ProcessingInstruction: case XmlNodeType.Text: case XmlNodeType.CDATA: case XmlNodeType.Whitespace: case XmlNodeType.SignificantWhitespace: recordedNode = AddContent(_coreReader.NodeType); recordedNode.SetItemData(await _coreReader.GetValueAsync().ConfigureAwait(false)); recordedNode.SetLineInfo(_lineInfo); recordedNode.Depth = _coreReader.Depth; break; default: break; } _cachedNode = recordedNode; return(true); } else { _cacheState = CachingReaderState.ReaderClosed; return(false); } case CachingReaderState.Replay: if (_currentContentIndex >= _contentIndex) { //When positioned on the last cached node, switch back as the underlying coreReader is still positioned on this node _cacheState = CachingReaderState.ReaderClosed; _cacheHandler(this); if (_coreReader.NodeType != XmlNodeType.Element || _readAhead) { //Only when coreReader not positioned on Element node, read ahead, otherwise it is on the next element node already, since this was not cached return(await _coreReader.ReadAsync().ConfigureAwait(false)); } return(true); } _cachedNode = _contentEvents[_currentContentIndex]; if (_currentContentIndex > 0) { ClearAttributesInfo(); } _currentContentIndex++; return(true); default: return(false); } }