private unsafe void WriteUriAttributeText(char *pSrc, char *pSrcEnd) { if (endsWithAmpersand) { if (pSrcEnd - pSrc > 0 && pSrc[0] != '{') { OutputRestAmps(); } this.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 < 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 = 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: 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++ = (byte)'%'; *pDst++ = (byte)hexDigits[*pByte >> 4]; *pDst++ = (byte)hexDigits[*pByte & 0xF]; pByte++; } } continue; } pSrc++; } bufPos = (int)(pDst - pDstBegin); } }
private unsafe void WriteUriAttributeText(char *pSrc, char *pSrcEnd) { if (this.endsWithAmpersand) { if ((((long)((pSrcEnd - pSrc) / 2)) > 0L) && (pSrc[0] != '{')) { this.OutputRestAmps(); } this.endsWithAmpersand = false; } fixed(byte *numRef = base.bufBytes) { byte *numPtr2; byte *pDst = numRef + base.bufPos; char ch = '\0'; Label_0050: numPtr2 = pDst + ((byte *)((long)((pSrcEnd - pSrc) / 2))); if (numPtr2 > (numRef + base.bufLen)) { numPtr2 = numRef + base.bufLen; } while (((pDst < numPtr2) && ((this.xmlCharType.charProperties[ch = pSrc[0]] & 0x80) != 0)) && (ch < '\x0080')) { pDst++; pDst[0] = (byte)ch; pSrc++; } if (pSrc >= pSrcEnd) { goto Label_021D; } if (pDst >= numPtr2) { base.bufPos = (int)((long)((pDst - numRef) / 1)); this.FlushBuffer(); pDst = numRef + 1; goto Label_0050; } switch (ch) { case '\t': case '\'': case '<': case '>': pDst++; pDst[0] = (byte)ch; goto Label_0212; case '\n': pDst = XmlUtf8RawTextWriter.LineFeedEntity(pDst); goto Label_0212; case '\r': pDst = XmlUtf8RawTextWriter.CarriageReturnEntity(pDst); goto Label_0212; case '"': pDst = XmlUtf8RawTextWriter.QuoteEntity(pDst); goto Label_0212; case '&': if ((pSrc + 1) != pSrcEnd) { break; } this.endsWithAmpersand = true; goto Label_014E; default: fixed(byte *numRef2 = this.uriEscapingBuffer) { byte *numPtr3 = numRef2; byte *numPtr4 = numPtr3; XmlUtf8RawTextWriter.CharToUTF8(ref pSrc, pSrcEnd, ref numPtr4); while (numPtr3 < numPtr4) { pDst++; pDst[0] = 0x25; pDst++; pDst[0] = (byte)"0123456789ABCDEF"[numPtr3[0] >> 4]; pDst++; pDst[0] = (byte)"0123456789ABCDEF"[numPtr3[0] & 15]; numPtr3++; } } goto Label_0050; } if (pSrc[1] != '{') { pDst = XmlUtf8RawTextWriter.AmpEntity(pDst); goto Label_0212; } Label_014E: pDst++; pDst[0] = (byte)ch; Label_0212: pSrc++; goto Label_0050; Label_021D: base.bufPos = (int)((long)((pDst - numRef) / 1)); } }
// // &{ 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 WriteHtmlAttributeText(char *pSrc, char *pSrcEnd) { if (this.endsWithAmpersand) { if ((((long)((pSrcEnd - pSrc) / 2)) > 0L) && (pSrc[0] != '{')) { this.OutputRestAmps(); } this.endsWithAmpersand = false; } fixed(byte *numRef = base.bufBytes) { byte *numPtr2; byte *pDst = numRef + base.bufPos; char ch = '\0'; Label_0050: numPtr2 = pDst + ((byte *)((long)((pSrcEnd - pSrc) / 2))); if (numPtr2 > (numRef + base.bufLen)) { numPtr2 = numRef + base.bufLen; } while (((pDst < numPtr2) && ((this.xmlCharType.charProperties[ch = pSrc[0]] & 0x80) != 0)) && (ch <= '\x007f')) { pDst++; pDst[0] = (byte)ch; pSrc++; } if (pSrc >= pSrcEnd) { goto Label_0191; } if (pDst >= numPtr2) { base.bufPos = (int)((long)((pDst - numRef) / 1)); this.FlushBuffer(); pDst = numRef + 1; goto Label_0050; } switch (ch) { case '\t': case '\'': case '<': case '>': pDst++; pDst[0] = (byte)ch; goto Label_0186; case '\n': pDst = XmlUtf8RawTextWriter.LineFeedEntity(pDst); goto Label_0186; case '\r': pDst = XmlUtf8RawTextWriter.CarriageReturnEntity(pDst); goto Label_0186; case '"': pDst = XmlUtf8RawTextWriter.QuoteEntity(pDst); goto Label_0186; case '&': if ((pSrc + 1) != pSrcEnd) { break; } this.endsWithAmpersand = true; goto Label_0145; default: base.EncodeChar(ref pSrc, pSrcEnd, ref pDst); goto Label_0050; } if (pSrc[1] != '{') { pDst = XmlUtf8RawTextWriter.AmpEntity(pDst); goto Label_0186; } Label_0145: pDst++; pDst[0] = (byte)ch; Label_0186: pSrc++; goto Label_0050; Label_0191: base.bufPos = (int)((long)((pDst - numRef) / 1)); } }