Sep 25, 2008 - IronPythonのエンコーディング判別処理の修正 Ver.2
「エンコーディングの処理はいろんな要因が関連するため、安直な修正を行うと、他のプログラムの箇所や他のエンコーディング形式でレベルダウン障害を引き起こします」と下の記事に書きましたが。やっぱりレベルダウンが発生していましたorz
EncodingWrapperクラスへのパッチが不十分だったため、↓のコードを実行するとエラーになってしまいます。
import sys sys.setdefaultencoding( 'utf-8') f=open(r'e:\temp\utf8.txt', 'w' ) f.writelines( ['あ'*40+'\n']*40 ) f.close()
↓が修正パッチのバージョン2です。EncodingWrapperに包含されている_encodingのプロパティを呼び出すようにしただけです。
*** ./IronPython/Runtime/Operations/StringOps.cs.orig Fri Aug 22 12:05:38 2008
--- ./IronPython/Runtime/Operations/StringOps.cs Thu Sep 25 10:07:19 2008
***************
*** 1800,1805 ****
--- 1800,1860 ----
res._encoding = (Encoding)_encoding.Clone();
return res;
}
+
+ // this method is called by StreamReader.
+ public override Decoder GetDecoder() {
+ return _encoding.GetDecoder();
+ }
+
+ public override Encoder GetEncoder() {
+ return _encoding.GetEncoder();
+ }
+
+ // this method is called by PythonContext.GetSourceReader().
+ public override int CodePage {
+ get { return _encoding.CodePage; }
+ }
+
+ public override string BodyName {
+ get { return _encoding.BodyName; }
+ }
+
+ public override string EncodingName {
+ get { return _encoding.EncodingName; }
+ }
+
+ public override string HeaderName {
+ get { return _encoding.HeaderName; }
+ }
+
+ public override bool IsBrowserDisplay {
+ get { return _encoding.IsBrowserDisplay; }
+ }
+
+ public override bool IsBrowserSave {
+ get { return _encoding.IsBrowserSave; }
+ }
+
+ public override bool IsMailNewsDisplay {
+ get { return _encoding.IsMailNewsDisplay; }
+ }
+
+ public override bool IsMailNewsSave {
+ get { return _encoding.IsMailNewsSave; }
+ }
+
+ public override bool IsSingleByte {
+ get { return _encoding.IsSingleByte; }
+ }
+
+ public override string WebName {
+ get { return _encoding.WebName; }
+ }
+
+ public override int WindowsCodePage {
+ get { return _encoding.WindowsCodePage; }
+ }
+
}
private static List SplitEmptyString(bool separators) {
PythonContext.csへのパッチは変更していませんが、一応、再掲載。
*** ./IronPython/Runtime/PythonContext.cs.orig Tue Sep 09 06:33:00 2008
--- ./IronPython/Runtime/PythonContext.cs Wed Sep 24 01:41:00 2008
*************** namespace IronPython.Runtime {
*** 598,620 ****
}
}
! if (gotEncoding && sr.CurrentEncoding != PythonAsciiEncoding.Instance && encoding != sr.CurrentEncoding) {
! // we have both a BOM & an encoding type, throw an error
! throw new IOException("file has both Unicode marker and PEP-263 file encoding");
}
if (encoding == null) {
throw new IOException("unknown encoding type");
}
! if (!gotEncoding) {
! // if we didn't get an encoding seek back to the beginning...
! stream.Seek(startPosition, SeekOrigin.Begin);
! } else {
! // if we got an encoding seek to the # of bytes we read (so the StreamReader's
! // buffering doesn't throw us off)
! stream.Seek(bytesRead, SeekOrigin.Begin);
! }
// re-read w/ the correct encoding type...
return new SourceCodeReader(new StreamReader(stream, encoding), encoding);
--- 598,616 ----
}
}
! if (gotEncoding && sr.CurrentEncoding != PythonAsciiEncoding.Instance) {
! Encoding enc;
! if (!StringOps.TryGetEncoding(sr.CurrentEncoding.WebName, out enc) || enc.CodePage != encoding.CodePage) {
! // we have both a BOM & an encoding type, throw an error
! throw new IOException("file has both Unicode marker and PEP-263 file encoding");
! }
}
if (encoding == null) {
throw new IOException("unknown encoding type");
}
! stream.Seek(startPosition, SeekOrigin.Begin);
// re-read w/ the correct encoding type...
return new SourceCodeReader(new StreamReader(stream, encoding), encoding);