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);
}
}