diff options
author | Daniel Grunwald <daniel@danielgrunwald.de> | 2015-04-22 21:56:42 +0300 |
---|---|---|
committer | Daniel Grunwald <daniel@danielgrunwald.de> | 2015-04-22 21:56:42 +0300 |
commit | a583524629a18d705c7223fd3a4541da9c52c142 (patch) | |
tree | f09613e3326ea62bebfde2e50267e9210bb63249 | |
parent | eacd465376c0fa7f75c98ee2ab0141aa90ed81c6 (diff) |
Properly handle encoding in XmlDocumentationProvider (see icsharpcode/ILSpy#485)
-rw-r--r-- | ICSharpCode.NRefactory/Documentation/XmlDocumentationProvider.cs | 25 |
1 files changed, 21 insertions, 4 deletions
diff --git a/ICSharpCode.NRefactory/Documentation/XmlDocumentationProvider.cs b/ICSharpCode.NRefactory/Documentation/XmlDocumentationProvider.cs index 7c29d18a..ae9a0a1f 100644 --- a/ICSharpCode.NRefactory/Documentation/XmlDocumentationProvider.cs +++ b/ICSharpCode.NRefactory/Documentation/XmlDocumentationProvider.cs @@ -21,6 +21,7 @@ using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Runtime.Serialization; +using System.Text; using System.Xml; using ICSharpCode.NRefactory.Editor; using ICSharpCode.NRefactory.TypeSystem; @@ -102,6 +103,7 @@ namespace ICSharpCode.NRefactory.Documentation XmlDocumentationCache cache = new XmlDocumentationCache(); readonly string fileName; + readonly Encoding encoding; volatile IndexEntry[] index; // SORTED array of index entries #region Constructor / Redirection support @@ -122,6 +124,7 @@ namespace ICSharpCode.NRefactory.Documentation xmlReader.MoveToContent(); if (string.IsNullOrEmpty(xmlReader.GetAttribute("redirect"))) { this.fileName = fileName; + this.encoding = xmlReader.Encoding; ReadXmlDoc(xmlReader); } else { string redirectionTarget = GetRedirectionTarget(fileName, xmlReader.GetAttribute("redirect")); @@ -130,7 +133,9 @@ namespace ICSharpCode.NRefactory.Documentation using (FileStream redirectedFs = new FileStream(redirectionTarget, FileMode.Open, FileAccess.Read, FileShare.Read | FileShare.Delete)) { using (XmlTextReader redirectedXmlReader = new XmlTextReader(redirectedFs)) { redirectedXmlReader.XmlResolver = null; // no DTD resolving + redirectedXmlReader.MoveToContent(); this.fileName = redirectionTarget; + this.encoding = redirectedXmlReader.Encoding; ReadXmlDoc(redirectedXmlReader); } } @@ -208,7 +213,7 @@ namespace ICSharpCode.NRefactory.Documentation //lastWriteDate = File.GetLastWriteTimeUtc(fileName); // Open up a second file stream for the line<->position mapping using (FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read | FileShare.Delete)) { - LinePositionMapper linePosMapper = new LinePositionMapper(fs); + LinePositionMapper linePosMapper = new LinePositionMapper(fs, encoding); List<IndexEntry> indexList = new List<IndexEntry>(); while (reader.Read()) { if (reader.IsStartElement()) { @@ -227,10 +232,16 @@ namespace ICSharpCode.NRefactory.Documentation sealed class LinePositionMapper { readonly FileStream fs; + readonly Decoder decoder; int currentLine = 1; - public LinePositionMapper(FileStream fs) + // buffers for use with Decoder: + byte[] input = new byte[1]; + char[] output = new char[1]; + + public LinePositionMapper(FileStream fs, Encoding encoding) { + this.decoder = encoding.GetDecoder(); this.fs = fs; } @@ -241,7 +252,12 @@ namespace ICSharpCode.NRefactory.Documentation int b = fs.ReadByte(); if (b < 0) throw new EndOfStreamException(); - if (b == '\n') { + int bytesUsed, charsUsed; + bool completed; + input[0] = (byte)b; + decoder.Convert(input, 0, 1, output, 0, 1, false, out bytesUsed, out charsUsed, out completed); + Debug.Assert(bytesUsed == 1); + if (charsUsed == 1 && output[0] == '\n') { currentLine++; } } @@ -379,7 +395,8 @@ namespace ICSharpCode.NRefactory.Documentation { using (FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read | FileShare.Delete)) { fs.Position = positionInFile; - using (XmlTextReader r = new XmlTextReader(fs, XmlNodeType.Element, null)) { + var context = new XmlParserContext(null, null, null, XmlSpace.None) { Encoding = encoding }; + using (XmlTextReader r = new XmlTextReader(fs, XmlNodeType.Element, context)) { r.XmlResolver = null; // no DTD resolving while (r.Read()) { if (r.NodeType == XmlNodeType.Element) { |