Skip to content

Instantly share code, notes, and snippets.

@georg-jung
Last active January 27, 2019 16:20
Show Gist options
  • Save georg-jung/6ab5b05ea0ea362c705362b098bc584b to your computer and use it in GitHub Desktop.
Save georg-jung/6ab5b05ea0ea362c705362b098bc584b to your computer and use it in GitHub Desktop.
A StreamReader that replaces invalid XML characters. This enables you to use XmlReader for files which contain i.e. control chars.
// slightly updated version of https://stackoverflow.com/a/30351313/1200847
// uses .Net 4.0 function XmlConvert.IsXmlChar
// supports Async
public class InvalidXmlCharacterReplacingStreamReader : StreamReader
{
private readonly char _replacementCharacter;
public InvalidXmlCharacterReplacingStreamReader(string fileName, char replacementCharacter) : base(fileName)
{
_replacementCharacter = replacementCharacter;
}
public InvalidXmlCharacterReplacingStreamReader(Stream stream, char replacementCharacter) : base(stream)
{
_replacementCharacter = replacementCharacter;
}
public override int Peek()
{
var ch = base.Peek();
if (ch != -1 && IsInvalidChar(ch))
{
return _replacementCharacter;
}
return ch;
}
public override int Read()
{
var ch = base.Read();
if (ch != -1 && IsInvalidChar(ch))
{
return _replacementCharacter;
}
return ch;
}
public override int Read(char[] buffer, int index, int count)
{
var readCount = base.Read(buffer, index, count);
ReplaceInBuffer(buffer, index, readCount);
return readCount;
}
public override async Task<int> ReadAsync(char[] buffer, int index, int count)
{
var readCount = await base.ReadAsync(buffer, index, count).ConfigureAwait(false);
ReplaceInBuffer(buffer, index, readCount);
return readCount;
}
private void ReplaceInBuffer(char[] buffer, int index, int readCount)
{
for (var i = index; i < readCount + index; i++)
{
var ch = buffer[i];
if (IsInvalidChar(ch))
{
buffer[i] = _replacementCharacter;
}
}
}
private static bool IsInvalidChar(int ch)
{
return IsInvalidChar((char)ch);
}
private static bool IsInvalidChar(char ch)
{
return !XmlConvert.IsXmlChar(ch);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment