// // &{ split cases // 1). HtmlAttributeText("a&"); // HtmlAttributeText("{b}"); // // 2). HtmlAttributeText("a&"); // EndAttribute(); // 3).split with Flush by the user // HtmlAttributeText("a&"); // FlushBuffer(); // HtmlAttributeText("{b}"); // // Solutions: // case 1)hold the & output as & // if the next income character is {, output { // else output amp; // 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 + this.bufPos; char ch = (char)0; for (; ;) { byte *pDstEnd = pDst + (pSrcEnd - pSrc); if (pDstEnd > pDstBegin + bufLen) { pDstEnd = pDstBegin + bufLen; } while (pDst < pDstEnd && (((xmlCharType.charProperties[(ch = *pSrc)] & XmlCharType.fAttrValue) != 0) && 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 = XmlUtf8RawTextWriter.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(char *pDstBegin = bufChars) { char *pDst = pDstBegin + this.bufPos; char ch = (char)0; for (; ;) { char *pDstEnd = pDst + (pSrcEnd - pSrc); if (pDstEnd > pDstBegin + bufLen) { pDstEnd = pDstBegin + bufLen; } while (pDst < pDstEnd && (((xmlCharType.charProperties[(ch = *pSrc)] & XmlCharType.fAttrValue) != 0) && ch < 0x80)) { *pDst++ = (char)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 = XmlEncodedRawTextWriter.AmpEntity(pDst); break; } *pDst++ = (char)ch; break; case '"': pDst = QuoteEntity(pDst); break; case '<': case '>': case '\'': case (char)0x9: *pDst++ = (char)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: const string hexDigits = "0123456789ABCDEF"; fixed(byte *pUriEscapingBuffer = _uriEscapingBuffer) { byte *pByte = pUriEscapingBuffer; byte *pEnd = pByte; XmlUtf8RawTextWriter.CharToUTF8(ref pSrc, pSrcEnd, ref pEnd); while (pByte < pEnd) { *pDst++ = (char)'%'; *pDst++ = (char)hexDigits[*pByte >> 4]; *pDst++ = (char)hexDigits[*pByte & 0xF]; pByte++; } } continue; } pSrc++; } bufPos = (int)(pDst - pDstBegin); } }
internal XmlWriter CreateWriter(Stream output) { if (output == null) { throw new ArgumentNullException("output"); } XmlWriter writer; // create raw writer Debug.Assert(Encoding.UTF8.WebName == "utf-8"); if (this.Encoding.WebName == "utf-8") { // Encoding.CodePage is not supported in Silverlight // create raw UTF-8 writer switch (this.OutputMethod) { case XmlOutputMethod.Xml: if (this.Indent) { writer = new XmlUtf8RawTextWriterIndent(output, this); } else { writer = new XmlUtf8RawTextWriter(output, this); } break; case XmlOutputMethod.Html: if (this.Indent) { writer = new HtmlUtf8RawTextWriterIndent(output, this); } else { writer = new HtmlUtf8RawTextWriter(output, this); } break; case XmlOutputMethod.Text: writer = new TextUtf8RawTextWriter(output, this); break; case XmlOutputMethod.AutoDetect: writer = new XmlAutoDetectWriter(output, this); break; default: Debug.Assert(false, "Invalid XmlOutputMethod setting."); return(null); } } else { // Otherwise, create a general-purpose writer than can do any encoding switch (this.OutputMethod) { case XmlOutputMethod.Xml: if (this.Indent) { writer = new XmlEncodedRawTextWriterIndent(output, this); } else { writer = new XmlEncodedRawTextWriter(output, this); } break; case XmlOutputMethod.Html: if (this.Indent) { writer = new HtmlEncodedRawTextWriterIndent(output, this); } else { writer = new HtmlEncodedRawTextWriter(output, this); } break; case XmlOutputMethod.Text: writer = new TextEncodedRawTextWriter(output, this); break; case XmlOutputMethod.AutoDetect: writer = new XmlAutoDetectWriter(output, this); break; default: Debug.Assert(false, "Invalid XmlOutputMethod setting."); return(null); } } // Wrap with Xslt/XQuery specific writer if needed; // XmlOutputMethod.AutoDetect writer does this lazily when it creates the underlying Xml or Html writer. if (this.OutputMethod != XmlOutputMethod.AutoDetect) { if (this.IsQuerySpecific) { // Create QueryOutputWriter if CData sections or DocType need to be tracked writer = new QueryOutputWriter((XmlRawWriter)writer, this); } } // wrap with well-formed writer writer = new XmlWellFormedWriter(writer, this); return(writer); }