private int IncrementalReadHelper(object destBuffer, int destIndex, IncrementalReadType readType, int srcIndex, int count) { switch (readType) { case IncrementalReadType.Chars: char[] charBuffer = destBuffer as char[]; Array.Copy(_achText, srcIndex, charBuffer, destIndex, _nPos - srcIndex); return destIndex + (_nPos - srcIndex); case IncrementalReadType.Base64: byte[] base64ByteBuffer = destBuffer as byte[]; if (null == _Base64Decoder) { _Base64Decoder = new Base64Decoder(); } return destIndex + _Base64Decoder.DecodeBase64(_achText, srcIndex, _nPos, base64ByteBuffer, destIndex, count, false); case IncrementalReadType.BinHex: byte[] binhexByteBuffer = destBuffer as byte[]; if (null == _BinHexDecoder) { _BinHexDecoder = new BinHexDecoder(); } return destIndex + _BinHexDecoder.DecodeBinHex(_achText, srcIndex, _nPos, binhexByteBuffer, destIndex, count, false); default: throw new XmlException(Res.Xml_InternalError); } // switch }
internal int GetCharCount(int count, IncrementalReadType readType) { int loopCount; switch (readType) { case IncrementalReadType.Base64: loopCount = count * 8; loopCount = (loopCount % 6 > 0 ? (loopCount / 6) + 1 : loopCount / 6); if (_Base64Decoder != null) { loopCount -= _Base64Decoder.BitsFilled / 6; } break; case IncrementalReadType.BinHex: loopCount = count * 2; if (_BinHexDecoder != null) { loopCount -= (_BinHexDecoder.BitsFilled /4); } break; default: loopCount = count; break; } return loopCount; }
internal int IncrementalRead(object destBuffer, int index, int count, XmlTextReader reader,IncrementalReadType readType ) { int nStart = _nPos; int initialDestStartIndex = index; int loopCount; int offset = index; int lineNumber = LineNum; int linePosition = LinePos; bool lastCharD = false; int i; loopCount = GetCharCount(count, readType); try { for(i = 0; i < loopCount; i++) { if (_nPos == _nUsed) { index = IncrementalReadHelper(destBuffer, index, readType, nStart, count - index + offset); _nStart = _nPos; int diff = count - index + offset ; if (IncrementalReadType.Base64 == readType || IncrementalReadType.BinHex == readType ) { loopCount += GetCharCount(diff , readType); } if (diff == 0) return index - initialDestStartIndex; if (Read() == 0) throw new XmlException(Res.Xml_UnexpectedEOF, XmlToken.ToString(XmlToken.TAG), LineNum, LinePos); nStart = _nPos; lineNumber = LineNum; linePosition = LinePos; } switch(_achText[_nPos]) { case '<': { index = IncrementalReadHelper(destBuffer, index, readType, nStart, count - index + offset); int diff = count - index + offset ; if (IncrementalReadType.Base64 == readType || IncrementalReadType.BinHex == readType ) { loopCount += GetCharCount(diff , readType); } if (diff == 0) return index - initialDestStartIndex; } // Refill buffer to ensure that the calls from ContinueReadFromBuffer will not cause // The buffer size to increase _nStart = _nPos; Read(); //as its not end of input we just calling read to make sure buffer is enough full so no need to check the result nStart = _nPos; lineNumber = LineNum; linePosition = LinePos; // set ReadBufferConsistency in case name of the tag is bigger than 4k. Highly unlikely but possible. if (reader.ContinueReadFromBuffer(ScanMarkup())) { // We can continue filling up the buffer but _nPos might have moved. if (nStart < _nPos) { // Some stuff was read by the textReader; if (_nPos - nStart > loopCount - (index - offset)) { _nPos = nStart + loopCount - (index - offset); i = loopCount - 1; _nStart = _nPos; } else { i += _nPos - nStart -1; } } //if (nStart < _nPos) } else { return index - initialDestStartIndex; } // if ... else ... lastCharD = false; break; case (char)0xA: if (!lastCharD) { ++_nLineNum; } _nPos++; _nLinePos = _nPos; lastCharD = false; break; case (char)0xD: ++_nLineNum; lastCharD = true; _nPos++; _nLinePos = _nPos; break; default: _nPos++; lastCharD = false; break; } if (i == loopCount -1) { index = IncrementalReadHelper(destBuffer, index, readType, nStart, count - index + offset); int diff = count - index + offset ; if (IncrementalReadType.Base64 == readType || IncrementalReadType.BinHex == readType ) { loopCount += GetCharCount(diff , readType); } nStart = _nStart = _nPos; lineNumber = LineNum; linePosition = LinePos; if (diff == 0) return index - initialDestStartIndex; } } } catch (XmlException e) { throw new XmlException(e.ErrorCode, e.msg, lineNumber, linePosition); } return index - initialDestStartIndex; }
private int IncrementalRead(Object buffer, int index, int count, IncrementalReadType readType) { if (this.NodeType != XmlNodeType.Element) { // noop return 0; } if (_ElementToken.IsEmpty) { Read(); return 0; } if (null == buffer) { throw new ArgumentNullException("buffer"); } if (0 > count) { throw new ArgumentOutOfRangeException("count"); } if (0 > index) { throw new ArgumentOutOfRangeException("index"); } if (readType == IncrementalReadType.Chars) { char[] inArray = buffer as char[]; if (count > inArray.Length - index) throw new ArgumentException("count"); } else if (readType == IncrementalReadType.Base64 || readType == IncrementalReadType.BinHex) { byte[] inArray = buffer as byte[]; if (count > inArray.Length - index) throw new ArgumentException("count"); } ResetFieldsCollection(); if (_FinishReadChars == _NextFunction) { _NextFunction = _PreviousFunction; } Debug.Assert(_BufferConsistency == false, "_BufferConsistency should be false in this situation"); _Scanner.ReadBufferConsistency = -1; int totalChars = _Scanner.IncrementalRead(buffer, index, count, this, readType); if (count > totalChars) { _ReadInnerCharCount = 0; Read(); } else { _PreviousFunction = _NextFunction; _NextFunction = _FinishReadChars; } return totalChars; }