Browse Source

AvalonEdit encoding detection: add support for UTF-8 without BOM.

We now don't add a BOM when saving an UTF-8 that didn't have one when it was loaded.
pull/32/merge
Daniel Grunwald 13 years ago
parent
commit
9a6e77d214
  1. 9
      src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/ChooseEncodingDialog.xaml
  2. 22
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/TextEditor.cs
  3. 27
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Utils/FileReader.cs

9
src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/ChooseEncodingDialog.xaml

@ -13,13 +13,8 @@ @@ -13,13 +13,8 @@
Content="{core:Localize Dialog.Options.IDEOptions.TextEditor.General.FontGroupBox.FileEncodingLabel}" />
<ComboBox
Name="encodingComboBox"
Margin="16,0,8,8">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding DisplayName}"/>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
DisplayMemberPath="DisplayName"
Margin="16,0,8,8" />
<widgets:UniformGridWithSpacing
Columns="2"
Margin="4,4,10,10"

22
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/TextEditor.cs

@ -946,11 +946,24 @@ namespace ICSharpCode.AvalonEdit @@ -946,11 +946,24 @@ namespace ICSharpCode.AvalonEdit
}
}
/// <summary>
/// Encoding dependency property.
/// </summary>
public static readonly DependencyProperty EncodingProperty =
DependencyProperty.Register("Encoding", typeof(Encoding), typeof(TextEditor));
/// <summary>
/// Gets/sets the encoding used when the file is saved.
/// </summary>
/// <remarks>
/// The <see cref="Load(Stream)"/> method autodetects the encoding of the file and sets this property accordingly.
/// The <see cref="Save(Stream)"/> method uses the encoding specified in this property.
/// </remarks>
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public Encoding Encoding { get; set; }
public Encoding Encoding {
get { return (Encoding)GetValue(EncodingProperty); }
set { SetValue(EncodingProperty, value); }
}
/// <summary>
/// Saves the text to the stream.
@ -962,8 +975,11 @@ namespace ICSharpCode.AvalonEdit @@ -962,8 +975,11 @@ namespace ICSharpCode.AvalonEdit
{
if (stream == null)
throw new ArgumentNullException("stream");
StreamWriter writer = new StreamWriter(stream, this.Encoding ?? Encoding.UTF8);
writer.Write(this.Text);
var encoding = this.Encoding;
var document = this.Document;
StreamWriter writer = encoding != null ? new StreamWriter(stream, encoding) : new StreamWriter(stream);
if (document != null)
document.WriteTextTo(writer);
writer.Flush();
// do not close the stream
this.IsModified = false;

27
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Utils/FileReader.cs

@ -36,6 +36,22 @@ namespace ICSharpCode.AvalonEdit.Utils @@ -36,6 +36,22 @@ namespace ICSharpCode.AvalonEdit.Utils
}
}
static bool IsASCIICompatible(Encoding encoding)
{
byte[] bytes = encoding.GetBytes("Az");
return bytes.Length == 2 && bytes[0] == 'A' && bytes[1] == 'z';
}
static Encoding RemoveBOM(Encoding encoding)
{
switch (encoding.CodePage) {
case 65001: // UTF-8
return UTF8NoBOM;
default:
return encoding;
}
}
/// <summary>
/// Reads the content of the given stream.
/// </summary>
@ -125,6 +141,8 @@ namespace ICSharpCode.AvalonEdit.Utils @@ -125,6 +141,8 @@ namespace ICSharpCode.AvalonEdit.Utils
}
}
static readonly Encoding UTF8NoBOM = new UTF8Encoding(false);
static StreamReader AutoDetect(Stream fs, byte firstByte, byte secondByte, Encoding defaultEncoding)
{
int max = (int)Math.Min(fs.Length, 500000); // look at max. 500 KB
@ -187,21 +205,20 @@ namespace ICSharpCode.AvalonEdit.Utils @@ -187,21 +205,20 @@ namespace ICSharpCode.AvalonEdit.Utils
fs.Position = 0;
switch (state) {
case ASCII:
return new StreamReader(fs, IsASCIICompatible(defaultEncoding) ? RemoveBOM(defaultEncoding) : Encoding.ASCII);
case Error:
// when the file seems to be ASCII or non-UTF8,
// When the file seems to be non-UTF8,
// we read it using the user-specified encoding so it is saved again
// using that encoding.
if (IsUnicode(defaultEncoding)) {
// the file is not Unicode, so don't read it using Unicode even if the
// user has choosen Unicode as the default encoding.
// If we don't do this, SD will end up always adding a Byte Order Mark
// to ASCII files.
defaultEncoding = Encoding.Default; // use system encoding instead
}
return new StreamReader(fs, defaultEncoding);
return new StreamReader(fs, RemoveBOM(defaultEncoding));
default:
return new StreamReader(fs);
return new StreamReader(fs, UTF8NoBOM);
}
}
}

Loading…
Cancel
Save