From 787c2b3aa6619fb4fb6b49477f8325a1e0994a9c Mon Sep 17 00:00:00 2001 From: berryzplus Date: Tue, 27 Oct 2020 23:22:19 +0900 Subject: [PATCH] =?UTF-8?q?CodeFactor=E3=81=AE=E8=AD=A6=E5=91=8A=E5=AF=BE?= =?UTF-8?q?=E7=AD=96=E3=81=A8=E3=81=97=E3=81=A62=E3=81=A4=E4=BB=A5?= =?UTF-8?q?=E4=B8=8A=E3=81=AE=E3=82=AF=E3=83=A9=E3=82=B9=E3=82=92=E5=AE=9A?= =?UTF-8?q?=E7=BE=A9=E3=81=97=E3=81=A6=E3=81=84=E3=82=8Bcs=E3=83=95?= =?UTF-8?q?=E3=82=A1=E3=82=A4=E3=83=AB=E3=82=92=E5=88=86=E5=89=B2=E3=81=99?= =?UTF-8?q?=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CodeFactorの警告(保守性に難アリ)の対応で修正します。 --- .../ChmSourceConverter.csproj | 3 + .../ChmSourceConverterApp.cs | 153 ++++++++++++++++++ .../EncoderEscapingFallback.cs | 100 ------------ .../EncoderEscapingFallbackBuffer.cs | 128 +++++++++++++++ .../ChmSourceConverter/FileContents.cs | 81 ---------- .../ChmSourceConverter/LineEnumerator.cs | 111 +++++++++++++ .../ChmSourceConverter/Program.cs | 127 --------------- 7 files changed, 395 insertions(+), 308 deletions(-) create mode 100644 tools/ChmSourceConverter/ChmSourceConverter/ChmSourceConverterApp.cs create mode 100644 tools/ChmSourceConverter/ChmSourceConverter/EncoderEscapingFallbackBuffer.cs create mode 100644 tools/ChmSourceConverter/ChmSourceConverter/LineEnumerator.cs diff --git a/tools/ChmSourceConverter/ChmSourceConverter/ChmSourceConverter.csproj b/tools/ChmSourceConverter/ChmSourceConverter/ChmSourceConverter.csproj index ae09634f30..77dc98c9c1 100644 --- a/tools/ChmSourceConverter/ChmSourceConverter/ChmSourceConverter.csproj +++ b/tools/ChmSourceConverter/ChmSourceConverter/ChmSourceConverter.csproj @@ -41,8 +41,11 @@ + + + diff --git a/tools/ChmSourceConverter/ChmSourceConverter/ChmSourceConverterApp.cs b/tools/ChmSourceConverter/ChmSourceConverter/ChmSourceConverterApp.cs new file mode 100644 index 0000000000..d69ed08353 --- /dev/null +++ b/tools/ChmSourceConverter/ChmSourceConverter/ChmSourceConverterApp.cs @@ -0,0 +1,153 @@ +/* + Copyright (C) 2018-2020 Sakura Editor Organization + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; + you must not claim that you wrote the original software. + If you use this software in a product, an acknowledgment + in the product documentation would be appreciated but is + not required. + + 2. Altered source versions must be plainly marked as such, + and must not be misrepresented as being the original software. + + 3. This notice may not be removed or altered from any source + distribution. + */ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Text.RegularExpressions; +using System.Threading.Tasks; + +namespace ChmSourceConverter +{ + /// + /// 変換アプリ本体 + /// + internal class ChmSourceConverterApp + { + /// + /// 設定 + /// + private readonly Properties.Settings Settings; + + /// + /// 変換対象の拡張子 + /// + private readonly IEnumerable TargetExtensions; + + /// + /// 入力ファイルのエンコーディング + /// + private readonly Encoding InputEncoding; + + /// + /// HTML中に現れる文字セット定義のパターン(正規表現) + /// + private readonly Regex HtmlCharsetPattern; + + /// + /// コンストラクタ + /// + public ChmSourceConverterApp(Properties.Settings settings) + { + Settings = settings; + + TargetExtensions = Settings.TargetExtensions.Cast().ToList(); + InputEncoding = Encoding.GetEncoding(Settings.InputEncoding); + HtmlCharsetPattern = new Regex(Settings.ReplacePattern, RegexOptions.IgnoreCase); + } + + /// + /// プログラムを開始します + /// + /// + public void Start(string[] args) + { + if (args.Length < 1 && string.IsNullOrEmpty(args.FirstOrDefault())) + throw new ArgumentException("argument missing! Pass the target directory.", "args[0]"); + + string baseDirectory = args.First(); + if (!Directory.Exists(baseDirectory)) + throw new ArgumentException("invalid argument! the target directory does not exist.", "args[0]"); + + var files = Directory.EnumerateFiles(baseDirectory, "*.*", SearchOption.AllDirectories) + .Where(file => TargetExtensions.Any(ext => file.EndsWith(ext))); + + ParallelOptions options = new ParallelOptions() { MaxDegreeOfParallelism = Settings.MaxDegreeOfParallelism }; + Parallel.ForEach(files, options, (file) => DoConvertFile(file)); + } + + /// + /// ファイルを変換する + /// + /// + /// + public void DoConvertFile(string filename) + { + // 作業用ストリームを生成する + using (var memStream = new MemoryStream()) + { + // 作業用ストリームにファイルを読み込む + ReadFileIntoMemory(filename, memStream); + + // 作業用ストリームに蓄積したデータをbyte配列に書き出す + using (var destStream = new FileStream(filename, FileMode.Truncate, FileAccess.Write, FileShare.None)) + memStream.WriteTo(destStream); + } + } + + /// + /// ファイルをメモリに書き込む + /// + /// + /// + private void ReadFileIntoMemory(string filename, Stream stream) + { + // 変換用エンコーディングを生成する + Encoding outputEncoding = Encoding.GetEncoding(Settings.OutputEncoding, + new EncoderEscapingFallback(Settings.EscapingFormat), + new DecoderExceptionFallback()); + + // テキストライターを使ってストリームに読み込む + using (var writer = new StreamWriter(stream, outputEncoding, Settings.OutputBufferSize, true)) + ReadLinesIntoMemory(filename, writer); + } + + /// + /// ファイルから行を読み取ってメモリに書き込む + /// + /// + /// + private void ReadLinesIntoMemory(string filename, TextWriter writer) + { + bool IsHtml = Path.GetExtension(filename) == TargetExtensions.FirstOrDefault(); + + // 入力ファイルから行データを読み取る + using (var contents = new FileContents(filename, InputEncoding)) + { + foreach (var line in contents) + { + // コンテンツフィルターを適用する + if (IsHtml && HtmlCharsetPattern.IsMatch(line)) + { + IsHtml = false; + writer.WriteLine(HtmlCharsetPattern.Replace(line, $"$1{Settings.OutputEncoding}$2")); + continue; + } + writer.WriteLine(line); + } + } + } + } +} diff --git a/tools/ChmSourceConverter/ChmSourceConverter/EncoderEscapingFallback.cs b/tools/ChmSourceConverter/ChmSourceConverter/EncoderEscapingFallback.cs index db24a0740b..a3315371ef 100644 --- a/tools/ChmSourceConverter/ChmSourceConverter/EncoderEscapingFallback.cs +++ b/tools/ChmSourceConverter/ChmSourceConverter/EncoderEscapingFallback.cs @@ -22,8 +22,6 @@ 3. This notice may not be removed or altered from any source distribution. */ using System; -using System.Linq; -using System.Security; using System.Text; using System.Text.RegularExpressions; @@ -71,102 +69,4 @@ public override EncoderFallbackBuffer CreateFallbackBuffer() return new EncoderEscapingFallbackBuffer(this); } } - - /// - /// Represents a substitute input string that is used when the original input character cannot be encoded. - /// This class cannot be inherited. - /// - internal sealed class EncoderEscapingFallbackBuffer : EncoderFallbackBuffer - { - private ArraySegment Buffer; - private EncoderEscapingFallback FallbackRef; - - /// - public override int Remaining => Buffer.Count(); - - /// - /// Initializes a new instance of the EncoderEscapingFallbackBuffer class - /// using the value of a EncoderEscapingFallback object. - /// - /// A EncoderEscapingFallback object. - public EncoderEscapingFallbackBuffer(EncoderEscapingFallback fallback) - { - Buffer = new ArraySegment(Array.Empty()); - FallbackRef = fallback; - } - - /// - /// Prepares the escaping fallback buffer to use the current format string. - /// - /// - /// - private bool Fallback(int charUnknown) - { - var escapedChar = string.Format(FallbackRef.Format, charUnknown); - Buffer = new ArraySegment(escapedChar.ToCharArray()); - return true; - } - - /// - public override bool Fallback(char charUnknown, int index) - { - if (Buffer.Any()) - { - throw new ArgumentException("This method is called again before the GetNextChar method has read all the replacement string characters."); - } - - return Fallback((Int32)charUnknown); - } - - /// - public override bool Fallback(char charUnknownHigh, char charUnknownLow, int index) - { - if (Buffer.Any()) - { - throw new ArgumentException("This method is called again before the GetNextChar method has read all the replacement string characters."); - } - if (charUnknownHigh < 0xD800 || charUnknownHigh > 0xD8FF) - { - throw new ArgumentOutOfRangeException("charUnknownHigh", charUnknownHigh, "The value of charUnknownHigh is out of range"); - } - if (charUnknownLow < 0xDC00 || charUnknownLow > 0xDFFF) - { - throw new ArgumentOutOfRangeException("charUnknownLow", charUnknownLow, "The value of charUnknownLow is out of range"); - } - - int charUnknown = Char.ConvertToUtf32(charUnknownHigh, charUnknownLow); - return Fallback(charUnknown); - } - - /// - public override char GetNextChar() - { - char ch = Buffer.FirstOrDefault(); - if (Buffer.Any()) - { - Buffer = new ArraySegment(Buffer.Array, Buffer.Offset + 1, Buffer.Count - 1); - } - return ch; - } - - /// - public override bool MovePrevious() - { - if (Buffer.Offset == 0) return false; - Buffer = new ArraySegment(Buffer.Array, Buffer.Offset - 1, Buffer.Count + 1); - return true; - } - - /// - /// Initializes all internal state information and data in this instance of System.Text.EncoderReplacementFallbackBuffer. - /// - [SecuritySafeCritical] - public override void Reset() - { - if (Buffer.Any()) - { - Buffer = new ArraySegment(Buffer.Array, 0, Buffer.Array.Length); - } - } - } } diff --git a/tools/ChmSourceConverter/ChmSourceConverter/EncoderEscapingFallbackBuffer.cs b/tools/ChmSourceConverter/ChmSourceConverter/EncoderEscapingFallbackBuffer.cs new file mode 100644 index 0000000000..2a093f253f --- /dev/null +++ b/tools/ChmSourceConverter/ChmSourceConverter/EncoderEscapingFallbackBuffer.cs @@ -0,0 +1,128 @@ +/* + Copyright (C) 2018-2020 Sakura Editor Organization + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; + you must not claim that you wrote the original software. + If you use this software in a product, an acknowledgment + in the product documentation would be appreciated but is + not required. + + 2. Altered source versions must be plainly marked as such, + and must not be misrepresented as being the original software. + + 3. This notice may not be removed or altered from any source + distribution. + */ +using System; +using System.Linq; +using System.Security; +using System.Text; + +namespace ChmSourceConverter +{ + /// + /// Represents a substitute input string that is used when the original input character cannot be encoded. + /// This class cannot be inherited. + /// + internal sealed class EncoderEscapingFallbackBuffer : EncoderFallbackBuffer + { + private ArraySegment Buffer; + private EncoderEscapingFallback FallbackRef; + + /// + public override int Remaining => Buffer.Count(); + + /// + /// Initializes a new instance of the EncoderEscapingFallbackBuffer class + /// using the value of a EncoderEscapingFallback object. + /// + /// A EncoderEscapingFallback object. + public EncoderEscapingFallbackBuffer(EncoderEscapingFallback fallback) + { + Buffer = new ArraySegment(Array.Empty()); + FallbackRef = fallback; + } + + /// + /// Prepares the escaping fallback buffer to use the current format string. + /// + /// + /// + private bool Fallback(int charUnknown) + { + var escapedChar = string.Format(FallbackRef.Format, charUnknown); + Buffer = new ArraySegment(escapedChar.ToCharArray()); + return true; + } + + /// + public override bool Fallback(char charUnknown, int index) + { + if (Buffer.Any()) + { + throw new ArgumentException("This method is called again before the GetNextChar method has read all the replacement string characters."); + } + + return Fallback((Int32)charUnknown); + } + + /// + public override bool Fallback(char charUnknownHigh, char charUnknownLow, int index) + { + if (Buffer.Any()) + { + throw new ArgumentException("This method is called again before the GetNextChar method has read all the replacement string characters."); + } + if (charUnknownHigh < 0xD800 || charUnknownHigh > 0xD8FF) + { + throw new ArgumentOutOfRangeException("charUnknownHigh", charUnknownHigh, "The value of charUnknownHigh is out of range"); + } + if (charUnknownLow < 0xDC00 || charUnknownLow > 0xDFFF) + { + throw new ArgumentOutOfRangeException("charUnknownLow", charUnknownLow, "The value of charUnknownLow is out of range"); + } + + int charUnknown = Char.ConvertToUtf32(charUnknownHigh, charUnknownLow); + return Fallback(charUnknown); + } + + /// + public override char GetNextChar() + { + char ch = Buffer.FirstOrDefault(); + if (Buffer.Any()) + { + Buffer = new ArraySegment(Buffer.Array, Buffer.Offset + 1, Buffer.Count - 1); + } + return ch; + } + + /// + public override bool MovePrevious() + { + if (Buffer.Offset == 0) return false; + Buffer = new ArraySegment(Buffer.Array, Buffer.Offset - 1, Buffer.Count + 1); + return true; + } + + /// + /// Initializes all internal state information and data in this instance of System.Text.EncoderReplacementFallbackBuffer. + /// + [SecuritySafeCritical] + public override void Reset() + { + if (Buffer.Any()) + { + Buffer = new ArraySegment(Buffer.Array, 0, Buffer.Array.Length); + } + } + } +} diff --git a/tools/ChmSourceConverter/ChmSourceConverter/FileContents.cs b/tools/ChmSourceConverter/ChmSourceConverter/FileContents.cs index cd26d708e1..9b9cb1e989 100644 --- a/tools/ChmSourceConverter/ChmSourceConverter/FileContents.cs +++ b/tools/ChmSourceConverter/ChmSourceConverter/FileContents.cs @@ -24,7 +24,6 @@ 3. This notice may not be removed or altered from any source using System; using System.Collections; using System.Collections.Generic; -using System.IO; using System.Text; namespace ChmSourceConverter @@ -94,84 +93,4 @@ public void Dispose() } #endregion } - - /// - /// 行データを列挙するオブジェクトのクラス - /// - internal class LineEnumerator : IEnumerator - { - /// - /// ストリームリーダー - /// - private StreamReader Reader; - - /// - /// 現在行の行データ - /// - private string CurrentLine; - - /// - public string Current => CurrentLine; - - /// - object IEnumerator.Current => CurrentLine; - - /// - /// コンストラクタ - /// - /// - /// - public LineEnumerator(string filename, Encoding encoding) - { - Reader = new StreamReader(filename, encoding, true); - } - - /// - public bool MoveNext() - { - if (Reader.EndOfStream) return false; - CurrentLine = Reader.ReadLine(); - return true; - } - - /// - public void Reset() - { - CurrentLine = null; - Reader.BaseStream.Seek(0, SeekOrigin.Begin); - } - - #region IDisposable Support - private bool disposedValue = false; // To detect redundant calls - - protected virtual void Dispose(bool disposing) - { - if (!disposedValue) - { - if (disposing) - { - // dispose managed state (managed objects). - Reader.Dispose(); - Reader = null; - } - - disposedValue = true; - } - } - - ~LineEnumerator() - { - // Do not change this code. Put cleanup code in Dispose(bool disposing) above. - Dispose(false); - } - - // This code added to correctly implement the disposable pattern. - public void Dispose() - { - // Do not change this code. Put cleanup code in Dispose(bool disposing) above. - Dispose(true); - GC.SuppressFinalize(this); - } - #endregion - } } diff --git a/tools/ChmSourceConverter/ChmSourceConverter/LineEnumerator.cs b/tools/ChmSourceConverter/ChmSourceConverter/LineEnumerator.cs new file mode 100644 index 0000000000..a6c9125ff1 --- /dev/null +++ b/tools/ChmSourceConverter/ChmSourceConverter/LineEnumerator.cs @@ -0,0 +1,111 @@ +/* + Copyright (C) 2018-2020 Sakura Editor Organization + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; + you must not claim that you wrote the original software. + If you use this software in a product, an acknowledgment + in the product documentation would be appreciated but is + not required. + + 2. Altered source versions must be plainly marked as such, + and must not be misrepresented as being the original software. + + 3. This notice may not be removed or altered from any source + distribution. + */ +using System; +using System.Collections; +using System.Collections.Generic; +using System.IO; +using System.Text; + +namespace ChmSourceConverter +{ + /// + /// 行データを列挙するオブジェクトのクラス + /// + internal class LineEnumerator : IEnumerator + { + /// + /// ストリームリーダー + /// + private StreamReader Reader; + + /// + /// 現在行の行データ + /// + private string CurrentLine; + + /// + public string Current => CurrentLine; + + /// + object IEnumerator.Current => CurrentLine; + + /// + /// コンストラクタ + /// + /// + /// + public LineEnumerator(string filename, Encoding encoding) + { + Reader = new StreamReader(filename, encoding, true); + } + + /// + public bool MoveNext() + { + if (Reader.EndOfStream) return false; + CurrentLine = Reader.ReadLine(); + return true; + } + + /// + public void Reset() + { + CurrentLine = null; + Reader.BaseStream.Seek(0, SeekOrigin.Begin); + } + + #region IDisposable Support + private bool disposedValue = false; // To detect redundant calls + + protected virtual void Dispose(bool disposing) + { + if (!disposedValue) + { + if (disposing) + { + // dispose managed state (managed objects). + Reader.Dispose(); + Reader = null; + } + + disposedValue = true; + } + } + + ~LineEnumerator() + { + // Do not change this code. Put cleanup code in Dispose(bool disposing) above. + Dispose(false); + } + + // This code added to correctly implement the disposable pattern. + public void Dispose() + { + // Do not change this code. Put cleanup code in Dispose(bool disposing) above. + Dispose(true); + GC.SuppressFinalize(this); + } + #endregion + } +} diff --git a/tools/ChmSourceConverter/ChmSourceConverter/Program.cs b/tools/ChmSourceConverter/ChmSourceConverter/Program.cs index 9c7cd972d9..9c74408a48 100644 --- a/tools/ChmSourceConverter/ChmSourceConverter/Program.cs +++ b/tools/ChmSourceConverter/ChmSourceConverter/Program.cs @@ -21,136 +21,9 @@ and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. */ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Text; -using System.Text.RegularExpressions; -using System.Threading.Tasks; namespace ChmSourceConverter { - /// - /// 変換アプリ本体 - /// - internal class ChmSourceConverterApp - { - /// - /// 設定 - /// - private readonly Properties.Settings Settings; - - /// - /// 変換対象の拡張子 - /// - private readonly IEnumerable TargetExtensions; - - /// - /// 入力ファイルのエンコーディング - /// - private readonly Encoding InputEncoding; - - /// - /// HTML中に現れる文字セット定義のパターン(正規表現) - /// - private readonly Regex HtmlCharsetPattern; - - /// - /// コンストラクタ - /// - public ChmSourceConverterApp(Properties.Settings settings) - { - Settings = settings; - - TargetExtensions = Settings.TargetExtensions.Cast().ToList(); - InputEncoding = Encoding.GetEncoding(Settings.InputEncoding); - HtmlCharsetPattern = new Regex(Settings.ReplacePattern, RegexOptions.IgnoreCase); - } - - /// - /// プログラムを開始します - /// - /// - public void Start(string[] args) - { - if (args.Length < 1 && string.IsNullOrEmpty(args.FirstOrDefault())) - throw new ArgumentException("argument missing! Pass the target directory.", "args[0]"); - - string baseDirectory = args.First(); - if (!Directory.Exists(baseDirectory)) - throw new ArgumentException("invalid argument! the target directory does not exist.", "args[0]"); - - var files = Directory.EnumerateFiles(baseDirectory, "*.*", SearchOption.AllDirectories) - .Where(file => TargetExtensions.Any(ext => file.EndsWith(ext))); - - ParallelOptions options = new ParallelOptions() { MaxDegreeOfParallelism = Settings.MaxDegreeOfParallelism }; - Parallel.ForEach(files, options, (file) => DoConvertFile(file)); - } - - /// - /// ファイルを変換する - /// - /// - /// - public void DoConvertFile(string filename) - { - // 作業用ストリームを生成する - using (var memStream = new MemoryStream()) - { - // 作業用ストリームにファイルを読み込む - ReadFileIntoMemory(filename, memStream); - - // 作業用ストリームに蓄積したデータをbyte配列に書き出す - using (var destStream = new FileStream(filename, FileMode.Truncate, FileAccess.Write, FileShare.None)) - memStream.WriteTo(destStream); - } - } - - /// - /// ファイルをメモリに書き込む - /// - /// - /// - private void ReadFileIntoMemory(string filename, Stream stream) - { - // 変換用エンコーディングを生成する - Encoding outputEncoding = Encoding.GetEncoding(Settings.OutputEncoding, - new EncoderEscapingFallback(Settings.EscapingFormat), - new DecoderExceptionFallback()); - - // テキストライターを使ってストリームに読み込む - using (var writer = new StreamWriter(stream, outputEncoding, Settings.OutputBufferSize, true)) - ReadLinesIntoMemory(filename, writer); - } - - /// - /// ファイルから行を読み取ってメモリに書き込む - /// - /// - /// - private void ReadLinesIntoMemory(string filename, TextWriter writer) - { - bool IsHtml = Path.GetExtension(filename) == TargetExtensions.FirstOrDefault(); - - // 入力ファイルから行データを読み取る - using (var contents = new FileContents(filename, InputEncoding)) - { - foreach (var line in contents) - { - // コンテンツフィルターを適用する - if (IsHtml && HtmlCharsetPattern.IsMatch(line)) - { - IsHtml = false; - writer.WriteLine(HtmlCharsetPattern.Replace(line, $"$1{Settings.OutputEncoding}$2")); - continue; - } - writer.WriteLine(line); - } - } - } - } - class Program { static void Main(string[] args)