internal void Write(char[] array, int offset, int count) { if (null == array) { throw new ArgumentNullException(nameof(array)); } if (0 > offset) { throw new ArgumentOutOfRangeException(nameof(offset)); } if (0 > count) { throw new ArgumentOutOfRangeException(nameof(count)); } if (count > array.Length - offset) { throw new ArgumentOutOfRangeException(nameof(count)); } if (_cacheAttrValue) { _attrValue.Append(array, offset, count); } int endPos = offset + count; int i = offset; char ch = (char)0; while (true) { int startPos = i; while (i < endPos && _xmlCharType.IsAttributeValueChar(ch = array[i])) { i++; } if (startPos < i) { _textWriter.Write(array, startPos, i - startPos); } if (i == endPos) { break; } switch (ch) { case (char)0x9: _textWriter.Write(ch); break; case (char)0xA: case (char)0xD: if (_inAttribute) { WriteCharEntityImpl(ch); } else { _textWriter.Write(ch); } break; case '<': WriteEntityRefImpl("lt"); break; case '>': WriteEntityRefImpl("gt"); break; case '&': WriteEntityRefImpl("amp"); break; case '\'': if (_inAttribute && _quoteChar == ch) { WriteEntityRefImpl("apos"); } else { _textWriter.Write('\''); } break; case '"': if (_inAttribute && _quoteChar == ch) { WriteEntityRefImpl("quot"); } else { _textWriter.Write('"'); } break; default: if (XmlCharType.IsHighSurrogate(ch)) { if (i + 1 < endPos) { WriteSurrogateChar(array[++i], ch); } else { throw new ArgumentException(SR.Xml_SurrogatePairSplit); } } else if (XmlCharType.IsLowSurrogate(ch)) { throw XmlConvert.CreateInvalidHighSurrogateCharException(ch); } else { Debug.Assert((ch < 0x20 && !_xmlCharType.IsWhiteSpace(ch)) || (ch > 0xFFFD)); WriteCharEntityImpl(ch); } break; } i++; } }
private unsafe void WriteHtmlAttributeText(char *pSrc, char *pSrcEnd) { if (_endsWithAmpersand) { if (pSrcEnd - pSrc > 0 && pSrc[0] != '{') { OutputRestAmps(); } _endsWithAmpersand = false; } fixed(byte *pDstBegin = _bufBytes) { byte *pDst = pDstBegin + _bufPos; char ch = (char)0; while (true) { byte *pDstEnd = pDst + (pSrcEnd - pSrc); if (pDstEnd > pDstBegin + _bufLen) { pDstEnd = pDstBegin + _bufLen; } while (pDst < pDstEnd && XmlCharType.IsAttributeValueChar((char)(ch = *pSrc)) && ch <= 0x7F) { *pDst++ = (byte)ch; pSrc++; } Debug.Assert(pSrc <= pSrcEnd); // end of value if (pSrc >= pSrcEnd) { break; } // end of buffer if (pDst >= pDstEnd) { _bufPos = (int)(pDst - pDstBegin); FlushBuffer(); pDst = pDstBegin + 1; continue; } // some character needs to be escaped switch (ch) { case '&': if (pSrc + 1 == pSrcEnd) { _endsWithAmpersand = true; } else if (pSrc[1] != '{') { pDst = AmpEntity(pDst); break; } *pDst++ = (byte)ch; break; case '"': pDst = QuoteEntity(pDst); break; case '<': case '>': case '\'': case (char)0x9: *pDst++ = (byte)ch; break; case (char)0xD: // do not normalize new lines in attributes - just escape them pDst = CarriageReturnEntity(pDst); break; case (char)0xA: // do not normalize new lines in attributes - just escape them pDst = LineFeedEntity(pDst); break; default: EncodeChar(ref pSrc, pSrcEnd, ref pDst); continue; } pSrc++; } _bufPos = (int)(pDst - pDstBegin); } }
private unsafe void WriteUriAttributeText(char *pSrc, char *pSrcEnd) { if (_endsWithAmpersand) { if (pSrcEnd - pSrc > 0 && pSrc[0] != '{') { OutputRestAmps(); } _endsWithAmpersand = false; } fixed(byte *pDstBegin = _bufBytes) { byte *pDst = pDstBegin + _bufPos; char ch = (char)0; while (true) { byte *pDstEnd = pDst + (pSrcEnd - pSrc); if (pDstEnd > pDstBegin + _bufLen) { pDstEnd = pDstBegin + _bufLen; } while (pDst < pDstEnd && XmlCharType.IsAttributeValueChar((char)(ch = *pSrc)) && ch < 0x80) { *pDst++ = (byte)ch; pSrc++; } Debug.Assert(pSrc <= pSrcEnd); // end of value if (pSrc >= pSrcEnd) { break; } // end of buffer if (pDst >= pDstEnd) { _bufPos = (int)(pDst - pDstBegin); FlushBuffer(); pDst = pDstBegin + 1; continue; } // some character needs to be escaped switch (ch) { case '&': if (pSrc + 1 == pSrcEnd) { _endsWithAmpersand = true; } else if (pSrc[1] != '{') { pDst = AmpEntity(pDst); break; } *pDst++ = (byte)ch; break; case '"': pDst = QuoteEntity(pDst); break; case '<': case '>': case '\'': case (char)0x9: *pDst++ = (byte)ch; break; case (char)0xD: // do not normalize new lines in attributes - just escape them pDst = CarriageReturnEntity(pDst); break; case (char)0xA: // do not normalize new lines in attributes - just escape them pDst = LineFeedEntity(pDst); break; default: Debug.Assert(_uriEscapingBuffer?.Length > 0); fixed(byte *pUriEscapingBuffer = _uriEscapingBuffer) { byte *pByte = pUriEscapingBuffer; byte *pEnd = pByte; XmlUtf8RawTextWriter.CharToUTF8(ref pSrc, pSrcEnd, ref pEnd); while (pByte < pEnd) { *pDst++ = (byte)'%'; *pDst++ = (byte)HexConverter.ToCharUpper(*pByte >> 4); *pDst++ = (byte)HexConverter.ToCharUpper(*pByte); pByte++; } } continue; } pSrc++; } _bufPos = (int)(pDst - pDstBegin); } }
internal void Write(string text) { if (text == null) { return; } if (_cacheAttrValue) { Debug.Assert(_attrValue != null); _attrValue.Append(text); } // scan through the string to see if there are any characters to be escaped int len = text.Length; int i = 0; int startPos = 0; char ch = (char)0; while (true) { while (i < len && XmlCharType.IsAttributeValueChar(ch = text[i])) { i++; } if (i == len) { // reached the end of the string -> write it whole out _textWriter.Write(text); return; } if (_inAttribute) { if (ch == 0x9) { i++; continue; } } else { if (ch == 0x9 || ch == 0xA || ch == 0xD || ch == '"' || ch == '\'') { i++; continue; } } // some character that needs to be escaped is found: break; } char[] helperBuffer = new char[256]; while (true) { if (startPos < i) { WriteStringFragment(text, startPos, i - startPos, helperBuffer); } if (i == len) { break; } switch (ch) { case (char)0x9: _textWriter.Write(ch); break; case (char)0xA: case (char)0xD: if (_inAttribute) { WriteCharEntityImpl(ch); } else { _textWriter.Write(ch); } break; case '<': WriteEntityRefImpl("lt"); break; case '>': WriteEntityRefImpl("gt"); break; case '&': WriteEntityRefImpl("amp"); break; case '\'': if (_inAttribute && _quoteChar == ch) { WriteEntityRefImpl("apos"); } else { _textWriter.Write('\''); } break; case '"': if (_inAttribute && _quoteChar == ch) { WriteEntityRefImpl("quot"); } else { _textWriter.Write('"'); } break; default: if (XmlCharType.IsHighSurrogate(ch)) { if (i + 1 < len) { WriteSurrogateChar(text[++i], ch); } else { throw XmlConvert.CreateInvalidSurrogatePairException(text[i], ch); } } else if (XmlCharType.IsLowSurrogate(ch)) { throw XmlConvert.CreateInvalidHighSurrogateCharException(ch); } else { Debug.Assert((ch < 0x20 && !XmlCharType.IsWhiteSpace(ch)) || (ch > 0xFFFD)); WriteCharEntityImpl(ch); } break; } i++; startPos = i; while (i < len && XmlCharType.IsAttributeValueChar(ch = text[i])) { i++; } } }